• 谈一谈struts2和springmvc的拦截器


    最近涉及到了两个项目,都需要考虑全局的拦截器,其功能就是判断session的登陆状态,如果session信息完好,可以从中取得相应的信息,则放行,否则拦截,进入重定向的uri。

    既然是全局的拦截器,其拦截的东西当然会很多也就是会很忙,相应的其功能也会非常丰富,可以在其中进行多种功能的拦截,本文就只考虑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(部分)

    1.  /** 
    2.      * 在业务处理器处理请求之前被调用 
    3.      * 如果返回false 
    4.      *     从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链 
    5.      *  
    6.      * 如果返回true 
    7.      *    执行下一个拦截器,直到所有的拦截器都执行完毕 
    8.      *    再执行被拦截的Controller 
    9.      *    然后进入拦截器链, 
    10.      *    从最后一个拦截器往回执行所有的postHandle() 
    11.      *    接着再从最后一个拦截器往回执行所有的afterCompletion() 
    12.      */  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";//进入上文蓝色位置
    	}




  • 相关阅读:
    断点调试
    内部类
    继承2
    继承
    构造函数
    方法
    二维数组
    HTML 一
    使用mySQL与数据库进行交互(一)
    使用mySQL与数据库进行交互(二)
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3233979.html
Copyright © 2020-2023  润新知