您的位置:首页 > 编程语言 > Java开发

Spring MVC + Mybatis + Shiro

2016-01-11 21:10 513 查看
1.Spring配置:web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">

<display-name>frame</display-name>

<!-- 读取spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml;classpath:spring-mybatis.xml;classpath:shiro-config.xml</param-value>
</context-param>

<!-- 防止发生java.beans.Introspector内存泄露,应将它配置在ContextLoaderListener的前面 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Spring Application Context Listener End -->

<!-- 配置Shiro过滤器,先让Shiro过滤系统接收到的请求 -->
<!-- 这里filter-name必须对应applicationContext.xml中定义的<bean id="shiroFilter"/> -->
<!-- 使用[/*]匹配所有请求,保证所有的可控请求都经过Shiro的过滤 -->
<!-- 通常会将此filter-mapping放置到最前面(即其他filter-mapping前面),以保证它是过滤器链中第一个起作用的 -->
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<!-- 该值缺省为false,表示生命周期由SpringApplicationContext管理,设置为true则表示由ServletContainer管理 -->
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- Spring MVC Config Start -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern><!-- 拦截了所有包括静态资源文件,spring mvc中需要配置mvc:resources包含静态资源文件 -->
</servlet-mapping>
<!-- Spring MVC Config End -->

<!-- WebAppRootKey 获取项目部署的根路径,将log4j日志输出到项目的路径下 -->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>webapp.root</param-value>
</context-param>

<!-- Log4J 配置 Start -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param>
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>6000</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
<!-- Log4J 配置 End -->

<!-- Spring 编码过滤器 start -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Spring 编码过滤器 End -->

<!--CXF配置 -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>

<!-- 错误跳转页面 -->
<!-- <error-page> <error-code>404</error-code> <location>/WEB-INF/errorpage/404.jsp</location>
</error-page> <error-page> <error-code>405</error-code> <location>/WEB-INF/errorpage/405.jsp</location>
</error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/errorpage/500.jsp</location>
</error-page> -->

</web-app>


2.Spring配置:applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> 
<!-- 引入jdbc配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>

<!-- 扫描文件(自动将servicec层注入) -->
<context:component-scan base-package="org.bsframe"/>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"
lazy-init="false" autowire="default" >
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<bean id="helloWorldImpl" class="org.bsframe.web.cxf.HelloWorldServiceImpl"></bean>
<!-- soap webservice -->
<jaxws:endpoint id="helloWorld" implementor="#helloWorldImpl" address="/HelloWorld" ></jaxws:endpoint>

<!--     <import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

<jaxws:endpoint id="helloWorld" implementor="org.bsframe.web.cxf.HelloWorldServiceImpl"
address="/HelloWorld" />   -->

<!-- restful webservice -->
<jaxrs:server id="rs1" address="/rs">
<jaxrs:serviceBeans>
<ref bean="restSample" />
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</jaxrs:providers>
</jaxrs:server>

</beans>


3.Spring MVC配置:spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:solr="http://www.springframework.org/schema/data/solr" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd http://www.springframework.org/schema/data/solr http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd"> 
<!-- 会自动注册DefaultAnnotationHandlerMapping与AnnotationMethodHandlerAdapter
两个bean -->
<mvc:annotation-driven />

<!-- 配置spring处理静态资源文件 两种方案 -->
<!--方案一: 使用服务器默认的defaultServlet -->
<mvc:default-servlet-handler />
<!--(推荐方案)方案二: 把images/**映射到ResourceHttpRequestHandler进行处理 -->
<mvc:resources mapping="/images/**" location="/images/" />
<mvc:resources mapping="/css/**" location="/css/" />
<mvc:resources mapping="/js/**" location="/js/" />
<mvc:resources mapping="/frame/**" location="/frame/" />
<mvc:resources mapping="/pages/**" location="/pages/" />

<!-- 注册解析注解所需要的几个bean -->
<context:annotation-config />

<!-- 对包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 需要更改 -->
<context:component-scan base-package="org.bsframe.web.controller" />

<!-- 默认访问跳转到登录页面(即定义无需Controller的url<->view直接映射) -->
<mvc:view-controller path="/" view-name="forward:/login.jsp" />

<!-- 避免IE在ajax请求时,返回json出现下载 -->
<bean id="jacksonMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>

<!-- 对模型视图添加前后缀 -->
<!-- ViewResolver,负责为DispatcherServlet查找ModelAndView的视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/view/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>

<!-- <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
abstract="false" lazy-init="false" autowire="default" > <property name="dataSource">
<ref bean="dataSource" /> </property> </bean> -->

<!-- task任务扫描注解 -->
<task:annotation-driven />

<!-- Solr setting -->
<solr:repositories base-package="org.bsframe.web.repository"
multicore-support="true" />

<solr:solr-server id="solrServer" url="http://locahost:8983/solr" />

<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate"
scope="singleton">
<constructor-arg ref="solrServer" />
</bean>

<!-- <bean id="searchRepository"
class="org.springframework.data.solr.example.repository.SolrProductRepository">
<property name="solrOperations" ref="solrTemplate" />
</bean> -->

</beans>


4.log4j配置:log4j.properties

### direct log messages to stdout and logFile###
log4j.rootCategory=INFO, stdout,logFile

# OpenSymphony Stuff
log4j.logger.com.opensymphony=INFO
log4j.logger.org.apache.struts2=INFO
log4j.logger.org.apache.commons=INFO

# Spring Stuff
log4j.logger.org.springframework=INFO
log4j.logger.org.springframework.oxm=INFO

# Hibernate Stuff
log4j.logger.org.hibernate=INFO
log4j.logger.org.hibernate.type=INFO
log4j.logger.org.hibernate.tool.hbm2ddl=INFO

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[\u65F6\u95F4\:%d{yyyy-MM-dd hh\:mm\:ss}] [\u7EA7\u522B\:%p] [\u7C7B\:%c]  [\u6D88\u606F\:%m] %n

log4j.appender.logFile=org.apache.log4j.RollingFileAppender
log4j.appender.logFile.File=/Users/zouhao/bsframe.log
#log4j.appender.logFile.File=${webapp.root}/WEB-INF/logs/frame-app.log
log4j.appender.logFile.layout=org.apache.log4j.PatternLayout
log4j.appender.logFile.layout.ConversionPattern=[\u65F6\u95F4\:%d{yyyy-MM-dd hh\:mm\:ss}] [\u7EA7\u522B\:%p] [\u7C7B\:%c]  [\u6D88\u606F\:%m] %n
log4j.appender.logFile.MaxFileSize = 5MB
log4j.appender.logFile.MaxBackupIndex =3


5.Mybatis配置:mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 命名空间 -->
<typeAliases>

<!-- 类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余 -->
<typeAlias alias="user" type="org.bsframe.entity.User" />

<!-- 在包 domain.blog 中的 Java Bean,在没有注解的情况下(@Alias("user")),会使用 Bean 的首字母小写的非限定类名来作为它的别名(如user) -->
<package name="org.bsframe.entity" />

</typeAliases>

<!-- <typeHandlers> -->
<!-- <typeHandler handler="org.mybatis.example.ExampleTypeHandler"/> -->
<!-- </typeHandlers> -->

<plugins>

<!-- 自定义分页Interceptor -->
<!--         <plugin interceptor="org.bsframe.web.interceptor.StatementInterceptor"></plugin> -->
<!--         <plugin interceptor="org.bsframe.web.interceptor.ResultSetInterceptor"></plugin> -->

<!-- com.github.pagehelper为PageHelper类所在包名   ,使用PageHelper插件,与以上自定义的plugin只能选其一 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 4.0.0以后版本可以不设置该参数 -->
<!-- <property name="dialect" value="mysql" /> -->
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样 -->
<property name="offsetAsPageNum" value="true" />
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true" />
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型) -->
<property name="pageSizeZero" value="true" />
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="false" />
<!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
<!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
<!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,orderBy,不配置映射的用默认值 -->
<!-- 不理解该含义的前提下,不要随便复制该配置 -->
<property name="params" value="pageNum=start;pageSize=limit;" />
<!-- 支持通过Mapper接口参数来传递分页参数 -->
<property name="supportMethodsArguments" value="true" />
<!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
<property name="returnPageInfo" value="check" />
</plugin>
</plugins>

<!-- 映射map -->
<mappers>

<package name="org.bsframe.dao" />

</mappers>

</configuration>


6.Spring整合Mybatis:spring-mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> 
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName">
<value>${jdbc_driverClassName}</value>
</property>
<property name="url">
<value>${jdbc_url}</value>
</property>
<property name="username">
<value>${jdbc_username}</value>
</property>
<property name="password">
<value>${jdbc_password}</value>
</property>
<!-- 连接池最大使用连接数 -->
<property name="maxActive">
<value>20</value>
</property>
<!-- 初始化连接大小 -->
<property name="initialSize">
<value>1</value>
</property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait">
<value>60000</value>
</property>
<!-- 连接池最大空闲 -->
<property name="maxIdle">
<value>20</value>
</property>
<!-- 连接池最小空闲 -->
<property name="minIdle">
<value>3</value>
</property>
<!-- 自动清除无用连接 -->
<property name="removeAbandoned">
<value>true</value>
</property>
<!-- 清除无用连接的等待时间 -->
<property name="removeAbandonedTimeout">
<value>180</value>
</property>
<!-- 连接属性 -->
<property name="connectionProperties">
<value>clientEncoding=UTF-8</value>
</property>
</bean>

<!-- mybatis文件配置,扫描所有mapper文件 -->
<!-- <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis-config.xml"
p:mapperLocations="classpath:mapper/*.xml" /> -->

<!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mapper/*.xml"></property>
</bean>

<!-- spring与mybatis整合配置,扫描所有dao -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:basePackage="org.bsframe.dao" p:sqlSessionFactoryBeanName="sqlSessionFactory" />

<!-- 对数据源进行事务管理 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />

</beans>


7.数据源配置:jdbc.properties

jdbc_driverClassName=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/bsframe?useUnicode=true&characterEncoding=utf-8
jdbc_username=root
jdbc_password=


8.Shiro配置:shiro-config.xml

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> 
<!-- 缓存管理器 使用Ehcache实现 -->
<bean id="cacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
<property name="cacheManagerConfigFile" value="classpath:ehcache.xml" />
</bean>

<!-- <bean id="passwordHelper" class="com.shinowit.framework.security.PasswordHelper">
</bean> -->

<!-- 凭证匹配器 -->
<!-- <bean id="credentialsMatcher" class="com.shinowit.framework.security.credentials.RetryLimitSimpleCredentialsMatcher">
<constructor-arg ref="cacheManager" /> <property name="passwordHelper" ref="passwordHelper"
/> </bean> -->

<!-- Realm实现 -->
<bean id="userRealm" class="org.bsframe.shiro.UserRealm">
<property name="cachingEnabled" value="true" />
<property name="authenticationCachingEnabled" value="true" />
<property name="authenticationCacheName" value="authenticationCache" />
<property name="authorizationCachingEnabled" value="true" />
<property name="authorizationCacheName" value="authorizationCache" />
</bean>

<!-- 会话ID生成器 -->
<bean id="sessionIdGenerator"
class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" />

<!-- 会话Cookie模板 -->
<bean id="sessionIdCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="sid" />
<property name="httpOnly" value="true" />
<property name="maxAge" value="180000" />
</bean>

<bean id="rememberMeCookie" class="org.apache.shiro.web.servlet.SimpleCookie">
<constructor-arg value="rememberMe" />
<property name="httpOnly" value="true" />
<property name="maxAge" value="2592000" />
<!-- 30天 -->
</bean>

<!-- rememberMe管理器 -->
<bean id="rememberMeManager" class="org.apache.shiro.web.mgt.CookieRememberMeManager">
<property name="cipherKey"
value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}" />
<property name="cookie" ref="rememberMeCookie" />
</bean>

<!-- 会话DAO -->
<bean id="sessionDAO"
class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO">
<property name="activeSessionsCacheName" value="shiro-activeSessionCache" />
<property name="sessionIdGenerator" ref="sessionIdGenerator" />
</bean>

<!-- 会话验证调度器 -->
<bean id="sessionValidationScheduler"
class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler">
<property name="sessionValidationInterval" value="1800000" />
<property name="sessionManager" ref="sessionManager" />
</bean>

<!-- 会话管理器 -->
<bean id="sessionManager"
class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name="globalSessionTimeout" value="1800000" />
<property name="deleteInvalidSessions" value="true" />
<property name="sessionValidationSchedulerEnabled" value="true" />
<property name="sessionValidationScheduler" ref="sessionValidationScheduler" />
<property name="sessionDAO" ref="sessionDAO" />
<property name="sessionIdCookieEnabled" value="true" />
<property name="sessionIdCookie" ref="sessionIdCookie" />
</bean>

<!-- 安全管理器 -->
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
<property name="realm" ref="userRealm" />
<property name="sessionManager" ref="sessionManager" />
<property name="cacheManager" ref="cacheManager" />
<property name="rememberMeManager" ref="rememberMeManager" />
</bean>

<!-- 相当于调用SecurityUtils.setSecurityManager(securityManager) -->
<bean
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod"
value="org.apache.shiro.SecurityUtils.setSecurityManager" />
<property name="arguments" ref="securityManager" />
</bean>

<!--下面的loginUrl有两个必要条件,一个登陆校验失败以后会强制客户端redirect到这个url, 另外一个是登陆的表单(含有用户名及密码)必须action到这个url -->
<!-- 自定义的能够接收校验码的身份验证过滤器 跳转问题太他妈诡异了,不用了,自己写代码控制如何跳转了 <bean id="formAuthenticationFilter"
class="com.shinowit.framework.security.filter.ValidFormAuthenticationFilter">
<property name="usernameParam" value="loginName"/> <property name="passwordParam"
value="loginPass"/> <property name="loginUrl" value="/login/"/> </bean> -->

<!-- Shiro的Web过滤器 -->
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
<property name="securityManager" ref="securityManager" />
<property name="loginUrl" value="/login/" />
<property name="unauthorizedUrl" value="/unauthorized.jsp" />
<property name="filters">
<map>
<entry key="authc">
<bean
class="org.apache.shiro.web.filter.authc.PassThruAuthenticationFilter" />
</entry>
</map>
</property>
<property name="filterChainDefinitions">
<value>
/login.jsp = anon
/user/** = anon
/scheduleTaskJob = anon
/category/** = anon
/cxf/** = anon
/services/** = anon
/springrest/** = anon
/question/** = anon
/teacher/** = anon
/** = authc

</value>
</property>
</bean>

<!-- Shiro生命周期处理器 -->
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

</beans>


9.Ehcache缓存配置:ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="1200"
timeToLiveSeconds="1200"
overflowToDisk="false">
</defaultCache>

<cache name="test"
maxElementsInMemory="1000"
maxElementsOnDisk="5000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="0">
</cache>

</ehcache>


10.自定义Realm: UserRealm.java

package org.bsframe.shiro;

import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.bsframe.dao.UserDAO;
import org.bsframe.entity.User;
import org.springframework.beans.factory.annotation.Autowired;

public class UserRealm extends AuthorizingRealm {

@Autowired
private UserDAO userDAO;

//授权
@Override
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
String username = (String) principals.getPrimaryPrincipal();

SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

Set<String> roles = userDAO.findUserRoles(username);
authorizationInfo.setRoles(roles);

Set<String> permissions = userDAO.findUserPermissions(username);
authorizationInfo.setStringPermissions(permissions);

return authorizationInfo;
}

//认证
@Override
protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

//        UsernamePasswordToken login_token = (UsernamePasswordToken) token;
//
//        //校验码判断逻辑
//        //取得用户输入的校验码
//        String userInputValidCode = login_token.getValidCode();
//
//        //取得真实的正确校验码
//        String realRightValidCode = (String) SecurityUtils.getSubject().getSession().getAttribute("rand");
//
//        if (null == userInputValidCode || !userInputValidCode.equalsIgnoreCase(realRightValidCode)) {
//            throw new ValidCodeException("验证码输入不正确");
//        }

//以上校验码验证通过以后,查数据库
String username = (String) token.getPrincipal();
User user = userDAO.findByUsername(username);

if (user == null) {
throw new UnknownAccountException();//没找到帐号
}

if (Boolean.FALSE.equals(user.getEnable())) {
throw new LockedAccountException(); //帐号锁定
}

//交给AuthenticatingRealm使用CredentialsMatcher进行密码匹配,如果觉得人家的不好可以自定义实现
SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
user.getUsername(), //用户名
user.getPassword(), //密码
getName()  //realm name
);
return authenticationInfo;
}

@Override
public void clearCachedAuthorizationInfo(PrincipalCollection principals) {
super.clearCachedAuthorizationInfo(principals);
}

@Override
public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
super.clearCachedAuthenticationInfo(principals);
}

@Override
public void clearCache(PrincipalCollection principals) {
super.clearCache(principals);
}

public void clearAllCachedAuthorizationInfo() {
getAuthorizationCache().clear();
}

public void clearAllCachedAuthenticationInfo() {
getAuthenticationCache().clear();
}

public void clearAllCache() {
clearAllCachedAuthenticationInfo();
clearAllCachedAuthorizationInfo();
}

}


11.自定义用户名密码Token: CustomUsernamePasswordToken.java

package org.bsframe.shiro;

import org.apache.shiro.authc.UsernamePasswordToken;

public class CustomUsernamePasswordToken extends UsernamePasswordToken {

private static final long serialVersionUID = 1L;
//用于存储用户输入的校验码
private String validCode;

public CustomUsernamePasswordToken(String username, char[] password,boolean rememberMe, String host, String validCode) {
//调用父类的构造函数
super(username,password,rememberMe,host);
this.validCode=validCode;
}

public String getValidCode() {
return validCode;
}

public void setValidCode(String validCode) {
this.validCode = validCode;
}
}


12.Dao层代码示例: UserMapper.java

package org.bsframe.dao;

import java.util.Set;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.bsframe.entity.User;

public interface UserMaper{

/**
* 添加新用户
* @param user
* @return
*/
//使用UserMapper.xml文件配置sql语句
public User findByUsername(String username);

@Insert("insert into user(username, password, nickname) values(#{username}, #{password}, #{nickname})")
public int addUser(User user);

@Select("select r.name from user u,role r,user_role ur where u.id = ur.userid and r.id = ur.roleid and u.username = #{username}")
public Set<String> findUserRoles(String username);

@Select("select p.url from user u, role r, permission p, user_role ur, role_permission rp where u.username= #{username} and u.id=ur.userid and r.id=ur.roleid and r.id=rp.roleid and p.id=rp.permissionid")
public Set<String> findUserPermissions(String username);

@Select("select * from user where nickname = #{nickname}")
public User findByNickname(String nickname);

@Select("select * from user where id = #{id}")
public User findUserById(Integer id);

}


13.Dao层Mapper配置文件: UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.bsframe.dao.UserDAO">

<select id="findByUsername" resultType="user">
select * from user where username  = #{username}
</select>

</mapper>


14.Service代码示例: UserServiceImpl.java

package org.bsframe.service.impl;

import org.bsframe.dao.UserDAO;
import org.bsframe.entity.User;
import org.bsframe.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService{

@Autowired
private UserMapper userMapper;

public int addUser(User user) {

return userMapper.addUser(user);
}

public User findUserById(Integer id) {
return userMapper.findUserById(id);
}

public User findByUsername(String name) {
return userMapper.findByUsername(name);
}

}


15.Controller层代码示例:UserController.java

package org.bsframe.web.controller;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.bsframe.entity.Sysres;
import org.bsframe.entity.User;
import org.bsframe.service.impl.UserServiceImpl;
import org.bsframe.web.util.VerifyCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Controller
@RequestMapping("/user")
public class UserController extends BaseController{

@Autowired
private UserServiceImpl userServiceImpl;

@RequestMapping(value="/findByUsername" , method = RequestMethod.GET)
public @ResponseBody User findByUsername(@RequestParam("name") String name){
return this.userServiceImpl.findByUsername(name);
}

@RequestMapping(value = "/login", method = RequestMethod.POST)
public String isLogin(HttpServletRequest request) {

String loginName = request.getParameter("username");
String loginPassword = request.getParameter("password");

HttpSession session = request.getSession(true);
String errorMessage = "";

Subject user = SecurityUtils.getSubject();

UsernamePasswordToken token = new UsernamePasswordToken(loginName, loginPassword);
token.setRememberMe(true);

try {
user.login(token);
String userID = (String) user.getPrincipal();
session.setAttribute("USERNAME", userID);
return "admin";
} catch (UnknownAccountException uae) {
errorMessage = "用户认证失败:" + "username wasn't in the system.";
} catch (IncorrectCredentialsException ice) {
errorMessage = "用户认证失败:" + "password didn't match.";
} catch (LockedAccountException lae) {
errorMessage = "用户认证失败:" + "account for that username is locked - can't login.";
} catch (AuthenticationException e) {
errorMessage = "登录失败错误信息:" + e;
e.printStackTrace();
token.clear();
}
session.setAttribute("ErrorMessage", errorMessage);
return "error";
}

/**
* 获取当前用户的用户名
* @return 跳转到展示当前用户姓名的页面
*/
@RequestMapping(value = "/getCurrent", method = RequestMethod.GET)
public ModelAndView getCurrent(HttpServletRequest request,HttpServletResponse response){

ModelAndView mv = new ModelAndView();
try {
//获取当前用户的姓名
String userName = getLoginUserName();
//放入到request中
mv.addObject("userName", userName);
//设置跳转页面
mv.setViewName("/top");
} catch (Exception e) {
e.printStackTrace();
mv.addObject("message", "获取用户出错!");
mv.setViewName("/exception");
}
return mv;
}

@RequestMapping(value="getMenu",method=RequestMethod.GET)
public ModelAndView getMenu(HttpServletRequest request,HttpServletResponse response){
ModelAndView mav =new ModelAndView();
try{
List<Sysres> slist= new ArrayList<Sysres>();
Sysres s = new Sysres();
s.setId(1l);
s.setName("通用类别管理");
s.setUrl("/category/toCategory");
s.setResdesc("toCategory");
s.setParentid(2l);
slist.add(s);

mav.setViewName("/left");
mav.addObject("menuList", slist);
return mav;
}catch(Exception e){
e.printStackTrace();
mav.addObject("message", "获取菜单出错!");
mav.setViewName("/exception");
return mav;
}
}

/**
* 用户登出
*/
@RequestMapping(value="/logout",method=RequestMethod.GET)
public String logout(HttpServletRequest request){
SecurityUtils.getSubject().logout();
String logout = InternalResourceViewResolver.FORWARD_URL_PREFIX + "/login.jsp";
return logout;
}

/**
* 获取验证码图片和文本(验证码文本会保存在HttpSession中)
*/
@RequestMapping("/getVerifyCodeImage")
public void getVerifyCodeImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
//设置页面不缓存
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
String verifyCode = VerifyCodeUtil.generateTextCode(VerifyCodeUtil.TYPE_NUM_ONLY, 4, null);
//将验证码放到HttpSession里面
request.getSession().setAttribute("verifyCode", verifyCode);
System.out.println("本次生成的验证码为[" + verifyCode + "],已存放到HttpSession中");
//设置输出的内容的类型为JPEG图像
response.setContentType("image/jpeg");
BufferedImage bufferedImage = VerifyCodeUtil.generateImageCode(verifyCode, 90, 30, 3, true, Color.WHITE, Color.BLACK, null);
//写给浏览器
ImageIO.write(bufferedImage, "JPEG", response.getOutputStream());
}

}


13.Maven jar包管理:pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zouhao</groupId>
<artifactId>bsframe</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.zouhao</groupId>
<artifactId>bsframe-moduel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<modules>
<module>bsframe-core</module>
<module>bsframe-entity</module>
<module>bsframe-dao</module>
<module>bsframe-service</module>
<module>bsframe-shiro</module>
<module>bsframe-web</module>
</modules>

<properties>
<spring.version>4.1.6.RELEASE</spring.version>
<!-- mybatis版本号 -->
<mybatis.version>3.2.4</mybatis.version>
<!-- mybatis分页插件 -->
<mybatis-pagehelper.version>4.0.3</mybatis-pagehelper.version>
<!-- log4j日志文件管理包版本 -->
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<commons-lang3.version>3.3</commons-lang3.version>
<commons-collections.version>3.2.1</commons-collections.version>

<!-- shiro版本号 -->
<shiro.version>1.2.3</shiro.version>
<ehcache.version>2.6.9</ehcache.version>
<servlet-api.version>3.1.0</servlet-api.version>

<cxf.version>2.7.8</cxf.version>

</properties>

<!-- 通用jar依赖管理,各个子项目都默认依赖 -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- 日志文件管理包 -->
<!-- log start -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- log end -->

<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons-collections.version}</version>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>

<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>

<!-- 一般jar依赖管理,各个子项目按需依赖,不用使用version -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.2</version>
</dependency>

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${mybatis-pagehelper.version}</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.2</version>
</dependency>

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.1.0</version>
</dependency>

<!-- apache shior maven start -->

<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>${ehcache.version}</version>
</dependency>

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-ehcache</artifactId>
<version>${shiro.version}</version>
</dependency>

<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-quartz</artifactId>
<version>${shiro.version}</version>
</dependency>
<!-- apache shiro maven end -->

<!-- cxf setting starting -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-core</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-simple</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-databinding-aegis</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-databinding-xmlbeans</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-databinding-jaxb</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-local</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-jms</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>${cxf.version}</version>
</dependency>

<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-management</artifactId>
<version>${cxf.version}</version>
</dependency>
<!-- CXF REST SETTING -->
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0-m10</version>
</dependency>

<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.13</version>
</dependency>

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-solr</artifactId>
<version>1.5.2.RELEASE</version>
</dependency>

<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-core</artifactId>
<version>5.4.0</version>
</dependency>

</dependencies>
</dependencyManagement>
</project>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: