点击链接加入群【JavaEE(SSH+IntelliJIDE+Maven)】:http://jq.qq.com/?_wv=1027&k=L2rbHv
将 Shiro 作为应用的权限基础 五:SpringMVC+Apache Shiro+JPA(hibernate)整合配置
配置web.xml,applicationContext.xml, spring-mvc.xml,applicationContext-shiro.xml,而且都有详细的说明。
web.xml是web项目最基本的配置文件,看这个配置,可以快速知道web项目使用什么框架,它就像一个面板,切入我们想用的插件。
applicationContext.xml是spring的基本配置,主要配置数据源、JPA实体管理器工厂、事务;
spring-mvc.xml是SpringMVC的配置;
applicationContext-shiro.xml是shiro的配置,主要配置securityManager、shiroFilter;
web.xml
<?xml version="1.0"encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:applicationContext*.xml</param-value> </context-param> <!--防止发生java.beans.Introspector内存泄露,应将它配置在ContextLoaderListener的前面 --> <!--详细描述见http://blog.csdn.net/jadyer/article/details/11991457 --> <listener> <listener-class> org.springframework.web.util.IntrospectorCleanupListener </listener-class> </listener> <!--实例化Spring容器 --> <!--应用启动时,该监听器被执行,它会读取Spring相关配置文件,其默认会到WEB-INF中查找applicationContext.xml--> <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> <!-- 配置编码过滤器 --> <filter> <filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置spring管理OpenEntityManagerInViewFilter--> <!-- OpenEntityManagerInViewFilter会让 session一直到view层调用结束后才关闭 Spring针对Hibernate的非JPA实现用的是OpenSessionInViewFilter, 原理与这个大同小异 --> <filter> <filter-name>hibernateFilter</filter-name> <filter-class> org.springframework.orm.jpa.support .OpenEntityManagerInViewFilter </filter-class> </filter> <filter-mapping> <filter-name>hibernateFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Shiro filter--> <!-- 这里filter-name必须对应applicationContext.xml中定义的 <beanid="shiroFilter"/> --> <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> <!-- 配置Log4j 把log4j 的默认配置文件(log4j.properties)放在classpath中, 通常是/web-inf/classes目录下.这种方式是log4j的 默认配置方式, 无须其他配置。 缺点就是无法灵活的通过配置文件来指定log4j.properties的文件位置 webAppRootKey是log4j在容器中的唯一标识,缺省为"webapp.root" --> <!-- <context-param> <param-name>webAppRootKey</param-name> <param-value>spring_springmvc_jpa.root</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <listener> <listener-class> org.springframework.web.util.Log4jConfigListener </listener-class> </listener> --> <!-- SpringMVC核心分发器 --> <servlet> <servlet-name>dispatcherServlet</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> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> <!--默认欢迎页 --> <!-- Servlet2.5中可直接在此处执行Servlet应用,如 <welcome-file> servlet/InitSystemParamServlet </welcome-file> --> <!-- 这里使用了SpringMVC提供的<mvc:view-controller>标签, 实现了首页隐藏的目的,详见spring-mvc.xml --> <!-- <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> --> </web-app>
applicationContext.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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd "> <!-- 注解支持 --> <context:annotation-config /> <!-- 启动组件扫描,排除@Controller组件,该组件由SpringMVC配置文件扫描--> <context:component-scan base-package="org.shiro.demo"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 属性文件位置 --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 数据源 --> <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> <!-- 数据库驱动 --> <property name="driverClass"value="${jdbc.driverClassName}" /> <!-- 相应驱动的jdbcUrl--> <property name="jdbcUrl"value="${jdbc.url}" /> <!-- 数据库的用户名 --> <property name="username"value="${jdbc.username}" /> <!-- 数据库的密码 --> <property name="password"value="${jdbc.password}" /> </bean> <!-- JPA实体管理器工厂 --> <bean id="entityManagerFactory" class= "org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource"ref="dataSource" /> <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" /> <!-- 加入定制化包路径 --> <property name="packagesToScan" value="org.shiro.demo.entity" /> <property name="jpaProperties"> <props> <prop key="hibernate.current_session_context_class"> thread</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <!--validate/update/create --> <prop key="hibernate.show_sql">false</prop> <prop key="hibernate.format_sql">false</prop> <!-- 建表的命名规则 --> <prop key="hibernate.ejb.naming_strategy"> org.hibernate.cfg.ImprovedNamingStrategy</prop> </props> </property> </bean> <!-- 设置JPA实现厂商的特定属性 --> <bean id="hibernateJpaVendorAdapter" class= "org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="databasePlatform" value="${hibernate.dialect}"/> </bean> <!-- 事务管理器 --> <bean id="txManager" class= "org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <!-- 注解式事务 --> <tx:annotation-driventr ansaction-manager="txManager" /> </beans>
spring-mvc.xml
<?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"> <!--启用SpringMVC的注解功能,它会自动注册 HandlerMapping、HandlerAdapter、ExceptionResolver的相关实例--> <mvc:annotation-driven /> <!-- SpringMVC的扫描范围 --> <context:component-scan base-package="org.shiro.demo.controller" /> <!--默认访问跳转到登录页面,即定义无Controller的path<->view直接映射 --> <mvc:view-controller path="/"view-name="redirect:/login"/> <!-- 静态文件访问 --> <mvc:resources mapping="/resources/**"location="/resources/" /> <!-- 配置SpringMVC的视图解析器 --> <!--其viewClass属性的默认值就是 org.springframework.web.servlet.view.JstlView --> <bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> --> <property name="prefix"value="/" /> <property name="suffix"value=".jsp" /> </bean> <!-- 配置SpringMVC的异常解析器 --> <bean class= "org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!-- 发生授权异常时,跳到指定页 --> <prop key= "org.apache.shiro.authz.UnauthorizedException"> /system/error </prop> <!--SpringMVC在超出上传文件限制时,会抛出org.springframework.web.multipart.MaxUploadSizeExceededException--> <!--遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/error_fileupload.jsp页面--> <!-- <propkey="org.springframework.web.multipart.MaxUploadSizeExceededException">WEB-INF/error_fileupload</prop>--> </props> </property> </bean> </beans>
ehcache-shiro.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" xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsd" default-lazy-init="true"> <description>Shiro安全配置</description> <!-- shiro securityManager --> <!--Shiro默认会使用Servlet容器的Session, 可通过sessionMode属性来指定使用Shiro原生Session --> <!--即<property name="sessionMode"value="native"/>, 详细说明见官方文档 --> <!--这里主要是设置自定义的单Realm应用,若有多个Realm, 可使用'realms'属性代替 --> <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <property name="realm" ref="shiroDbRealm" /> <!-- <property name="cacheManager" ref="myShiroEhcacheManager" /> --> <!-- <property name="sessionMode" value="native"/> <property name="sessionManager" ref="sessionManager"/> --> </bean> <!-- 用户授权信息Cache,采用EhCache --> <bean id="myShiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager"> <property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml" /> </bean> <!--继承自AuthorizingRealm的自定义Realm, 即指定Shiro验证用户的认证和授权 --> <bean id = "shiroDbRealm" class="org.shiro.demo.service.realm.ShiroDbRealm" depends-on="baseService"> <property name = "userService" ref="userService" /> </bean> <!--Shiro主过滤器本身功能十分强大,其强大之处就在于它支持任何基于URL路径表达式的、自定义的过滤器的执行 --> <!-- Shiro Filter --> <bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- Shiro的核心安全接口,这个属性是必须的 --> <property name="securityManager" ref="securityManager" /> <!--要求登录时的链接,非必须的属性, 默认会自动寻找Web工程根目录下的"/login.jsp"页面 --> <property name="loginUrl" value="/" /> <!-- 登录成功后要跳转的连接(本例中此属性用不到, 因为登录成功后的处理逻辑在LoginController里硬编码为main.jsp了) --> <property name="successUrl" value="/system/main" /> <!-- 用户访问未对其授权的资源时,所显示的连接 --> <property name="unauthorizedUrl" value="/system/error" /> <!-- Shiro过滤链的定义 --> <!-- 此处可配合这篇文章来理解各个过滤连的作用 http://blog.csdn.net/jadyer/article/details/12172839 --> <!--下面value值的第一个'/'代表的路径是相对于 HttpServletRequest.getContextPath()的值来的 --> <!--anon:它对应的过滤器里面是空的,什么都没做, 这里.do和.jsp后面的*表示参数,比方说login.jsp?main这种 --> <!-- authc:该过滤器下的页面必须验证后才能访问,它是Shiro内置的一个拦截器 org.apache.shiro.web.filter.authc.FormAuthenticationFilter --> <property name = "filterChainDefinitions"> <value> /login = anon /validateCode = anon /** = authc </value> </property> </bean> <!-- 保证实现了Shiro内部lifecycle函数的bean执行 --> <bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" /> <!-- 开启Shiro的注解,实现对Controller的方法级权限检查(如 @RequiresRoles,@RequiresPermissions), 需借助SpringAOP扫描使用Shiro注解的类,并在必要时进行安全逻辑验证 --> <!--配置以下两个bean即可实现此功能 --> <!-- Enable Shiro Annotations for Spring-configured beans. Only run after thelifecycleBeanProcessor has run --> <bean class= "org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" depends-on="lifecycleBeanPostProcessor"> <property name="proxyTargetClass" value="true" /> </bean> <bean class= "org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor"> <property name="securityManager" ref="securityManager" /> </bean> </beans>