SpringMVC shiro 项目 jeesite框架,启动后可以访问,等待约30分钟或更久之后,第一次访问会卡住。
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC shiro 项目 jeesite框架,启动后可以访问,等待约30分钟或更久之后,第一次访问会卡住。相关的知识,希望对你有一定的参考价值。
项目是SpringMVC + shiro的,数据库就不说了因为感觉不是数据库问题。项目启动后,可以正常访问,流程是标准的:1浏览器访问xx.html 服务端发送html给浏览器 (没有拦截)2浏览器获得html,解析。3浏览器知道要访问哪些资源了,开始向服务器要css,js等4浏览器渲染画面 执行js等5浏览器想服务器发送业务请求,服务器执行请求(action)。。。(进拦截器)如果等待了一段时间,大概30分钟或更久之后,每到这时,第一次访问时(任何客户端),跟上面步骤一样,步骤1 首先访问xx.html。这时火狐debug发现,卡住了,后台服务发现,shiro 的 sessionManager 的 getSessionId( 执行了,也过掉了,然后就没有然后了。。此时 浏览器没有走步骤2,3,4.... 后台自然不会走具体action。 不知道卡在哪了。之后可能是两种情况,一 如图片,直接失败了二 火狐能看到等了大概30几秒或更多, 然后 浏览器拿到html了,开始走步骤2,3,4.... 后面都很顺畅。此问题发生在,长时间等待之后 第一次访问服务器的时候, 一旦有人访问过,卡过之后,其他人 包括第一次访问的人 接着再访问 就都不会遇到此情况。求解。。。如果是springmvc配置 或者shiro的配置的话,可能是什么地方配置的有问题导致的。(应该不是拦截器,因为xx.html 不进拦截器)
应该是session超时导致的,shiro的默认设置会话的全局过期时间30分钟:追问静态画面的访问,session里没有记录信息吧,何来超时呢。
并且为何第一次访问 卡顿这么久,超过30秒,这段时间应该没有运算什么, 是在等待什么吗
Shiro权限框架与SpringMVC整合
1.Shiro整合SpringMVC
我们学习Shiro框架肯定是要应用到Web项目上的,所以我们需要整合Shiro和SpringMVC
整合步骤:
第一步:SpringMVC框架的配置
spring-mvc.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:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd"> <!-- 开启mvc注解驱动 --> <mvc:annotation-driven/> <!-- 放开静态资源的访问 --> <mvc:default-servlet-handler/> <!-- 配置视图解释器 --> <mvc:view-resolvers> <mvc:jsp prefix="/WEB-INF/views/" suffix=".jsp"/> </mvc:view-resolvers> </beans>
spring-context.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd"> <!-- 注解组件扫描 --> <context:component-scan base-package="com.gjs.shiro"> <!-- 排除不扫描的包 --> <context:exclude-filter type="regex" expression="pojo"/> </context:component-scan> </beans>
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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>shiro-springmvc-xml</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置编码过滤器 --> <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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置前端控制器 --> <servlet> <servlet-name>MVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定配置类 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring*.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
第二步:Shiro配置
shiro.ini:
[main] shiroRealm=com.gjs.shiro.realm.ShiroRealm securityManager.realms=$shiroRealm
ShiroRealm:
package com.gjs.shiro.realm; import org.apache.shiro.authc.AuthenticationException; import org.apache.shiro.authc.AuthenticationInfo; import org.apache.shiro.authc.AuthenticationToken; import org.apache.shiro.authc.SimpleAuthenticationInfo; import org.apache.shiro.authz.AuthorizationInfo; import org.apache.shiro.authz.SimpleAuthorizationInfo; import org.apache.shiro.realm.AuthorizingRealm; import org.apache.shiro.subject.PrincipalCollection; public class ShiroRealm extends AuthorizingRealm /** * 校验 */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException System.out.println("校验"); if ("admin".equals(token.getPrincipal())) return new SimpleAuthenticationInfo(token.getPrincipal(), "123456", this.getName()); return null; /** * 授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) System.out.println("授权"); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.addRole("role_admin"); info.addStringPermission("user:list"); info.addStringPermission("user:add"); return info;
第三步:springmvc和shiro整合
Shiro是使用Filter拦截请求的,SpringMVC是使用Servlet拦截请求的。而Filter的拦截请求优先级别高于Servlet,那么我们如何让Shiro交给SpringMVC代理?
Spring提供了一个Filter代理类,可以让Spring容器代理Filter的操作,DelegatingFilterProxy。实现了在过滤里面可以调用Spring容器的对象,可以让我们把原来配置在web.xml的过滤器配置在Spring配置文件里面(原来shiro配置在shiro.ini的配置也可以配置在Spring配置文件里)。
1.在web.xml添加配置:
<!-- 配置代理过滤器,用来代理指定的对象(过滤器) --> <filter> <filter-name>securityFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!-- 指定调用容器里面的对象名,如果不指定默认使用filter-name --> <init-param> <param-name>targetBeanName</param-name> <param-value>securityFilter</param-value> </init-param> <!-- 将目标过滤器的生命周期交给Spring容器代理 --> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>securityFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
修改后:
<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>shiro-springmvc-xml</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!-- 配置代理过滤器,用来代理指定的对象(过滤器) --> <filter> <filter-name>securityFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!-- 指定调用容器里面的对象名,如果不指定默认使用filter-name --> <init-param> <param-name>targetBeanName</param-name> <param-value>securityFilter</param-value> </init-param> <!-- 将目标过滤器的生命周期交给Spring容器代理 --> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>securityFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置编码过滤器 --> <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> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置前端控制器 --> <servlet> <servlet-name>MVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定配置类 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring*.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MVC</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
2.创建spring-shiro.xml配置文件
这个配置文件用来配置shiro的相关配置,并创建shiro过滤器用来给spring的代理过滤器调用
配置完毕我们之前的shiro的ini配置文件就可以删掉了
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 配置shiro过滤器给spring的代理过滤器调用 name属性需与web.xml中代理过滤器配置的对象名一致 --> <bean name="securityFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean"> <!-- 指定安全管理器 securityManager--> <property name="securityManager" ref="securityManager"/> <!-- 登录url --> <property name="loginUrl" value="/user/login"></property> <!-- 配置拦截过滤链 --> <property name="filterChainDefinitions"> <!-- shiro过滤器枚举值在org.apache.shiro.web.filter.mgt.DefaultFilter --> <value> /user/toLogin =anon /**=authc </value> </property> </bean> <!-- 配置SecurityManager 安全管理器 --> <bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager"> <!-- 配置securityManager的realm对象 --> <property name="realms" ref="shiroRealm"></property> </bean> <!-- 配置Realm --> <bean name="shiroRealm" class="com.gjs.shiro.realm.ShiroRealm"/> </beans>
3.权限控制器标签的使用
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags"%> <!-- 以认证跳转到主页 --> <shiro:authenticated> <jsp:forward page="/index"></jsp:forward> </shiro:authenticated> <!-- 未认证跳转到登录页面 --> <shiro:notAuthenticated> <jsp:forward page="/user/login"></jsp:forward> </shiro:notAuthenticated>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="shiro" uri="http://shiro.apache.org/tags" %> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <!-- 判断是否有指定的权限,有权限才显示 --> <shiro:hasPermission name="user:add"> 用户增加 </shiro:hasPermission> <shiro:hasPermission name="user:edit"> 用户编辑 </shiro:hasPermission> <shiro:hasPermission name="user:delete"> 用户删除 </shiro:hasPermission> <shiro:hasPermission name="user:list"> 用户列表 </shiro:hasPermission> </body> </html>
2.Shiro整合SpringMVC 基于注解
第一步:配置webx.xml
<!-- 配置代理过滤器,用来代理指定的对象(过滤器) --> <filter> <filter-name>securityFilter</filter-name> <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> <!-- 指定调用容器里面的对象名,如果不指定默认使用filter-name --> <init-param> <param-name>targetBeanName</param-name> <param-value>securityFilter</param-value> </init-param> <!-- 将目标过滤器的生命周期交给Spring容器代理 --> <init-param> <param-name>targetFilterLifecycle</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>securityFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
第二步:配置Shiro配置类
package com.gjs.rbac.config; import java.util.LinkedHashMap; import java.util.Map; import org.apache.shiro.mgt.SecurityManager; import org.apache.shiro.spring.web.ShiroFilterFactoryBean; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.gjs.rbac.realms.ShiroRealm; @Configuration public class ShiroConfig //1.配置shiro过滤器 用于给spring的代理过滤器调用 @Bean("securityFilter") public Object getShiroFilterFactoryBean() ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean(); factoryBean.setSecurityManager(this.getSecurityManager()); factoryBean.setSuccessUrl("/toIndex"); factoryBean.setLoginUrl("/user/login"); //定义过滤器链,使用LinkedHashMap是因为它是有顺序的(添加顺序) Map<String, String> filterChain =new LinkedHashMap<>(); filterChain.put("/user/toLogin", "anon"); filterChain.put("/**", "authc"); factoryBean.setFilterChainDefinitionMap(filterChain); try return factoryBean.getObject(); catch (Exception e) e.printStackTrace(); return null; //2.创建SecurityManager @Bean public SecurityManager getSecurityManager() DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(this.getShiroRealm()); return securityManager; //创建自定义的Realm @Bean public ShiroRealm getShiroRealm() ShiroRealm shiroRealm = new ShiroRealm(); return shiroRealm;
以上是关于SpringMVC shiro 项目 jeesite框架,启动后可以访问,等待约30分钟或更久之后,第一次访问会卡住。的主要内容,如果未能解决你的问题,请参考以下文章
JeeSite快速开发平台v4.2.2源码+在线代码生成功能