谈一谈struts2和springmvc的拦截器
2013-08-02 23:11
316 查看
最近涉及到了两个项目,都需要考虑全局的拦截器,其功能就是判断session的登陆状态,如果session信息完好,可以从中取得相应的信息,则放行,否则拦截,进入重定向的uri。
既然是全局的拦截器,其拦截的东西当然会很多也就是会很忙,相应的其功能也会非常丰富,可以在其中进行多种功能的拦截,本文就只考虑session的拦截。
以前是使用Filter加一个全局的过滤器,过滤web.xml中配置的url,通过request获取session,如果符合判断条件,则放行,否则做出相应的处理。从原理上来说,使用框架的拦截器跟Filter是一样的,只不过封装的更好,更能更加强大,通用性更强。
从源码上来看:
Filter接口:
SpringMVC拦截器接口:
struts2拦截器接口:
可以看到接口中都是有三个方法,作用就是在做前置工作、本职工作、后续工作。但配置上稍有不同,先谈SpringMVC:
jeecms-servlet-admin.xml(部分)
AdminContextInterceptor.java(部分)
/**
* 在业务处理器处理请求之前被调用
* 如果返回false
* 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
*
* 如果返回true
* 执行下一个拦截器,直到所有的拦截器都执行完毕
* 再执行被拦截的Controller
* 然后进入拦截器链,
* 从最后一个拦截器往回执行所有的postHandle()
* 接着再从最后一个拦截器往回执行所有的afterCompletion()
*/
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// 获得站点
CmsSite site = getSite(request, response);
CmsUtils.setSite(request, site);
// Site加入线程变量
CmsThreadVariable.setSite(site);
// 获得用户
CmsUser user = null;
if (adminId != null) {
// 指定管理员(开发状态)
user = cmsUserMng.findById(adminId);
if (user == null) {
throw new IllegalStateException("User ID=" + adminId
+ " not found!");
}
} else {
// 正常状态
Integer userId = authMng
.retrieveUserIdFromSession(session, request);
if (userId != null) {
user = cmsUserMng.findById(userId);
}
}
// 此时用户可以为null
CmsUtils.setUser(request, user);
// User加入线程变量
CmsThreadVariable.setUser(user);
String uri = getURI(request);
// 不在验证的范围内
if (exclude(uri)) {
return true;
}
// 用户为null跳转到登陆页面
if (user == null) {
response.sendRedirect(getLoginUrl(request));
return false;
}
// 用户不是管理员,提示无权限。
if (!user.getAdmin()) {
request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
"login.notAdmin"));
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return false;
}
// 不属于该站点的管理员,提示无权限。
if (!user.getSites().contains(site)) {
request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
"login.notInSite"));
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return false;
}
boolean viewonly = user.getViewonlyAdmin();
// 没有访问权限,提示无权限。
if (auth && !user.isSuper()
&& !permistionPass(uri, user.getPerms(), viewonly)) {
request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
"login.notPermission"));
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return false;
}
return true;
}
struts2的拦截器:
web.xml
从这个配置可以看出,struts2依然采取过滤器的方式,这个配置与过滤器一模一样,只是struts2进行了若干封装而已。
struts.xml配置:
AuthorityInterceptor.java
既然是全局的拦截器,其拦截的东西当然会很多也就是会很忙,相应的其功能也会非常丰富,可以在其中进行多种功能的拦截,本文就只考虑session的拦截。
以前是使用Filter加一个全局的过滤器,过滤web.xml中配置的url,通过request获取session,如果符合判断条件,则放行,否则做出相应的处理。从原理上来说,使用框架的拦截器跟Filter是一样的,只不过封装的更好,更能更加强大,通用性更强。
从源码上来看:
Filter接口:
public interface Filter { public void init(FilterConfig filterConfig) throws ServletException; public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException; public void destroy(); }
SpringMVC拦截器接口:
public interface HandlerInterceptor { boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception; void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception; }
struts2拦截器接口:
public interface Interceptor extends Serializable { void destroy(); void init(); String intercept(ActionInvocation invocation) throws Exception; }
可以看到接口中都是有三个方法,作用就是在做前置工作、本职工作、后续工作。但配置上稍有不同,先谈SpringMVC:
<servlet> <servlet-name>JeeCmsAdmin</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/jeecms-servlet-admin.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JeeCmsAdmin</servlet-name> <url-pattern>/jeeadmin/jeecms/*</url-pattern> </servlet-mapping>
jeecms-servlet-admin.xml(部分)
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <list> <ref bean="adminContextInterceptor"/> <ref bean="adminLocaleIntercept"/> <ref bean="fireWallInterceptor"/> </list> </property> </bean> <bean id="adminContextInterceptor" class="com.jeecms.cms.web.AdminContextInterceptor"> <property name="auth" value="true"/> <property name="loginUrl" value="/jeeadmin/jeecms/login.do"/> <property name="returnUrl" value="/jeeadmin/jeecms/index.do"/> <property name="excludeUrls"> <list> <value>/login.do</value> <value>/logout.do</value> </list> </property> </bean> <bean id="adminLocaleIntercept" class="com.jeecms.cms.web.AdminLocaleInterceptor"/> <bean id="fireWallInterceptor" class="com.jeecms.cms.web.FireWallInterceptor"> </bean>
AdminContextInterceptor.java(部分)
/**
* 在业务处理器处理请求之前被调用
* 如果返回false
* 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
*
* 如果返回true
* 执行下一个拦截器,直到所有的拦截器都执行完毕
* 再执行被拦截的Controller
* 然后进入拦截器链,
* 从最后一个拦截器往回执行所有的postHandle()
* 接着再从最后一个拦截器往回执行所有的afterCompletion()
*/
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// 获得站点
CmsSite site = getSite(request, response);
CmsUtils.setSite(request, site);
// Site加入线程变量
CmsThreadVariable.setSite(site);
// 获得用户
CmsUser user = null;
if (adminId != null) {
// 指定管理员(开发状态)
user = cmsUserMng.findById(adminId);
if (user == null) {
throw new IllegalStateException("User ID=" + adminId
+ " not found!");
}
} else {
// 正常状态
Integer userId = authMng
.retrieveUserIdFromSession(session, request);
if (userId != null) {
user = cmsUserMng.findById(userId);
}
}
// 此时用户可以为null
CmsUtils.setUser(request, user);
// User加入线程变量
CmsThreadVariable.setUser(user);
String uri = getURI(request);
// 不在验证的范围内
if (exclude(uri)) {
return true;
}
// 用户为null跳转到登陆页面
if (user == null) {
response.sendRedirect(getLoginUrl(request));
return false;
}
// 用户不是管理员,提示无权限。
if (!user.getAdmin()) {
request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
"login.notAdmin"));
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return false;
}
// 不属于该站点的管理员,提示无权限。
if (!user.getSites().contains(site)) {
request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
"login.notInSite"));
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return false;
}
boolean viewonly = user.getViewonlyAdmin();
// 没有访问权限,提示无权限。
if (auth && !user.isSuper()
&& !permistionPass(uri, user.getPerms(), viewonly)) {
request.setAttribute(MESSAGE, MessageResolver.getMessage(request,
"login.notPermission"));
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return false;
}
return true;
}
struts2的拦截器:
web.xml
<filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.FilterDispatcher </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
从这个配置可以看出,struts2依然采取过滤器的方式,这个配置与过滤器一模一样,只是struts2进行了若干封装而已。
struts.xml配置:
<struts> <constant name="struts.objectFactory" value="spring" /> <constant name="struts.devMode" value="true" /> <constant name="struts.i18n.encoding" value="UTF-8"/> <!-- 全局拦截器 add by fdk --> <package name="checkLogin" extends="struts-default"> <interceptors> <interceptor name="noLogin" class="com.tjhq.exception.AuthorityInterceptor" /> <interceptor-stack name="appStack"> <interceptor-ref name="defaultStack" />(必须加,否则出错) </interceptor-stack> <interceptor-stack name="defaultPaginationInterceptorStack">(这句是设置所有Action自动调用的拦截器堆栈) <interceptor-ref name="noLogin" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultPaginationInterceptorStack" /> <global-results> <result name="login" type="redirect">${pageContext.request.contextPath}/login.jsp</result> </global-results> </package> <package name="strutsCheckLogin" extends="struts-default"> <interceptors> <interceptor name="noLogin" class="com.tjhq.exception.AuthorityInterceptor" /> <interceptor-stack name="appStack"> <interceptor-ref name="defaultStack" /> </interceptor-stack> <interceptor-stack name="defaultPaginationInterceptorStack"> <interceptor-ref name="noLogin" /> <interceptor-ref name="appStack" /> </interceptor-stack> </interceptors> <default-interceptor-ref name="defaultPaginationInterceptorStack" /> <global-results> <result name="login" type="redirect">${pageContext.request.contextPath}/login.jsp</result> <result name="noframe" type="redirect">${pageContext.request.contextPath}/pages/error.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="noframe" exception="com.tjhq.exception.AppException"></exception-mapping> </global-exception-mappings> </package> <include file="struts2/pub.xml" /> <include file="struts2/collect.xml" /> <include file="struts2/audit.xml" /> <include file="struts2/publish.xml" /> <include file="struts2/search.xml" /> <include file="struts2/statistics.xml" /> <include file="struts2/sysmanager.xml" /> <include file="struts2/portal.xml" /> <include file="struts2/compre.xml" /> </struts>
AuthorityInterceptor.java
public String intercept(ActionInvocation ai) throws Exception { ActionContext ctx = ai.getInvocationContext(); Map session = ctx.getSession(); if(ServletActionContext.getRequest().getSession().getAttribute(Constants.USER_ID_SESSION)==null){ this.setSessionByUserId(session); } String ACCOUNT_ID = (String)session.get(Constants.USER_ID_SESSION); SysUserBean sb = (SysUserBean)session.get(Constants.USER_ACCOUNT_SESSION); if(sb != null && ACCOUNT_ID != null && ACCOUNT_ID.length()>0){ _logger.info("user loginning"); return ai.invoke();//放行,进入下一个拦截器 } _logger.info("intercept user is not login"); session.put("message", Dresource.getPropertie(Constants.PropertyKeys.NOT_LOGIN)); return "login";//进入上文蓝色位置 }
相关文章推荐
- 谈一谈struts2和springmvc的拦截器
- SpringMVC文件上传、拦截器、与Spring的整合以及与Struts2的比较
- SpringMVC 拦截器和过滤器的区别&&Struts2拦截器和过滤器的区别
- SpringMVC—Struts2拦截器学习网址整理
- springMVC高级部分(数据校验,数据错误回显(自定义格式错误显示),拦截器,异常处理,文件上传,文件下载,springmvc运行流程以及springmvc和struts2对比)
- SpringMVC和Struts2中拦截器实现思路思想
- SpringMVC的拦截器的实现(实现类似Struts2模型的模型填充)
- SpringMVCAop编程(对比Struts2的拦截器)
- SpringMVC—Struts2拦截器学习网址整理
- springmvc和struts2拦截器的简单使用以及配置
- 对比记录JDKproxy,cglibProxy,struts2拦截器,springMVC拦截器
- SpringMVC学习(五)——拦截器示例
- springmvc的拦截器
- web项目:漏洞修复(3)_struts2拦截器
- 九、Struts2之拦截器
- SpringMVC拦截器(资源和权限管理)
- 4.5.5: Struts2的拦截器机制---配置默认拦截器
- Struts2拦截器配置
- struts2 与springmvc深入对比(二)
- SpringMVC与struts2区别和第一个springMVC应用