`
sdcharles
  • 浏览: 51453 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

关于struts2中应用拦截器与filter对权限进行控制

阅读更多

我的项目采用了struts2+ExtJs的框架,在extjs的导航树中应用了iframe,监听树节点的click事件,如:html:'<iframe............>'调用了对应的jsp文件,这种框架的结合实际上大部分采用了ajax的方式来取后台的数据.如struts2.xml文件中这样配置

 

  <package name="login" extends="json-default">
		<action name="login" class="com.wscm.action.main.LoginAction" method="loginValid">
			<result type="json">
				<param name="includeProperties">success,tip</param>
			</result>
		</action>       
  </package>

 

 有人说这样的配置,由于继承了json-default无法应用struts2中的拦截器,网上大部分的拦截器例子是继承了struts-default这个包,但是昨天仔细看struts2的源文件发现json-default也是继承了struts-default这个包,所以在

 

 <package name="login" extends="json-default">
...................
  </package>

 

 配置拦截器也是起作用的.注意的是login这个包就别拦截了,如果拦截了就永远也无法登录了,当然如果把它配置在其它的action中也是可以的,只不过要在拦截器类把它放行就可以了,不过我还是喜欢这样配置,简单,拦截器类写起来也简单下面就是那个简单的拦截器类,利用session进行判断:

 

public class AuthorityIntercept extends AbstractInterceptor {
	public String intercept(ActionInvocation invocation) throws Exception{
		ActionContext ctx = invocation.getInvocationContext();
		Map session = ctx.getSession();
		String username = (String)session.get("username");
		if(username!=null){
			return invocation.invoke();
		}
		System.out.println("非法登录拦截!");
		return "login";
	}
}

 在配置文件中这样写

 <package name="ajax-json" extends="json-default">    
<interceptors>
  	<interceptor name="loginintercept" class="com.wscm.common.AuthorityIntercept"/>
  		<interceptor-stack name="logininterceptStack">
  			<interceptor-ref name="defaultStack" />
  			<interceptor-ref name="loginintercept" />
  		</interceptor-stack>
    </interceptors>
  	<default-interceptor-ref name="logininterceptStack" />
  	<global-results>
            <result name="login" type="redirect">/login.jsp</result>
    </global-results>  
		<action name="findallyhxxk" class="com.wscm.action.yygl.YhxxkAction" method="findAllYhxxk">
			<result type="json">
				<param name="root">page</param>
				<param name="excludeProperties">conditions,limit,start,success,objCondition</param>
			</result>
		</action>
		<action name="findmaxyhbh" class="com.wscm.action.yygl.YhxxkAction" method="findMaxYhbh">
			<result type="json">
				<param name="root">yhbh</param>
			</result>
		</action>
		<action name="saveyhxxk" class="com.wscm.action.yygl.YhxxkAction" method="saveYhxxk">
			<result type="json">
				<param name="includeProperties">success,tip</param>
			</result>
		</action>
  </package>

 

注意:上述配置中红色的那一行,<result name="login" type="redirect">/login.jsp</result>返回的那个视图实际上是不起作用的,我试过好多次了,后来仔细有最大的可能就是我们继承了json-default它的的返回类型是json格式的,这一点可以从源文件json-default.xml中找到,尽管没有按配置的视图资源进行跳转,但是如果未经登录打开了其中的某个页面时,再点击其中的应用时(实际上是调用上述ajax-json包中的action)是会拦截的,因为测试时那个"非法登录拦截!"打印出来了.

上述这样的确可以拦截应用但是有一点不太爽,就是未经登录应用中的jsp页面还是被打开了,虽然没什么实际性的内容(实际测试如果那个页面中如果打开时就调用ajax-json包中的action是会自动跳转到登录页面的,即使未显式的配置拦截器,我的理解是调用了struts-default中内置的有个管理session的拦截器,如果此处不对请高人指点).看struts2的源文件发现struts2的拦截器拦截的是action而不是jsp文件,如果想拦截jsp文件网上有人说可以将所有的jsp文件放入web-inf目录下,这个未经测试,不过估计可以.仔细看struts2的拦截器其实核心也是应用了filter,这样我们可以写一个filrter类配置在web.xml中对那些非法打开的jsp文件跳转到登录页面.如下是就是那个filter类:

 

public class AuthFilter implements Filter {
	private static Log log = LogFactory.getLog(AuthFilter.class);

    public void init(FilterConfig filterConfig) throws ServletException { 
        if(log.isDebugEnabled()){ 
            log.debug("初始化权限过滤器。"); 
        } 
    }
    public void doFilter(ServletRequest servletRequest, 
            ServletResponse servletResponse, FilterChain filterChain) 
            throws IOException, ServletException { 
        /** 
         * 1,doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括 
         * 表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过 
         * 滤器中忽略此参数。最后一个参数为FilterChain,此参数用来调用servlet或JSP页。 
         */
        HttpServletRequest request = (HttpServletRequest) servletRequest; 
        /** 
         * 如果处理HTTP请求,并且需要访问诸如getHeader或getCookies等在ServletRequest中 
         * 无法得到的方法,就要把此request对象构造成HttpServletRequest 
         */ 
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String currentURL = request.getRequestURI(); // 取得根目录所对应的绝对路径:
        HttpSession session = request.getSession(false);
        //如果jsp就验证(login.jsp,authImg.jsp图形验证码除外) 
        if (currentURL.indexOf("login.jsp")==-1 && currentURL.indexOf("authImg.jsp")==-1 && currentURL.indexOf(".jsp")>-1 ) { 
            if(log.isDebugEnabled()){ 
                log.debug("对jsp文件进行权限验证。"+"请求的URL:"+currentURL);             
            }
            // 判断当前页是否是重定向以后的登录页面页面,如果是就不做session的判断,防止出现死循环 
            if(session == null || session.getAttribute("username") == null ){ 
                response.sendRedirect(request.getContextPath()+"/login.jsp"); 
                return ; 
            } 
        } 
        // 加入filter链继续向下执行 
        filterChain.doFilter(request, response); 
        /** 
         * 调用FilterChain对象的doFilter方法。Filter接口的doFilter方法取一个FilterChain对象作 为它 
         * 的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另 
         * 一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。 
         */ 
    }


    public void destroy() {

    } 
}

 这个类的源码也是从网上一个资料中摘抄的,不过关键位置做了修改,尤其要注意的是上述红色的地方authImg.jsp,那是我的一个产生图形验证码的类,在页面中用jsp方式来调用.对于login.jsp,authImg.jsp一定要放行,否则前者会造成无法打开登录页面,后者就不会产生验证码,当然如果登录窗口不含

有验证码或者不用这种方式调用的,可以不管它.

我是filter与拦截器配合完美实现了权限验证拦截,当然了把拦截器去掉放在filter中拦截也是可以的,但是觉得这样简单.拦截器应用简单功能强大,唯一不足的就是无法拦截jsp文件.

分享到:
评论
3 楼 wnfd369 2012-07-02  
2 楼 wzwahl36 2012-03-23  
使用struts + extjs做管理系统时,使用拦截器拦截action来验证是否登录,如果没有登录,会跳转到login.jsp,现在的问题就是拦截到了,但是不能跳转~~

这个问题在你的博文中也提到了,请问这个问题怎么解决?
因为这个web系统还有一个前台主页,如果采用过滤器的话,这个url太难解析了~

如果博主知道怎么解决这个问题,email:wzwahl36@qq.com
thx.
1 楼 xiaofengyu 2011-07-12  
你好,我也遇到了你所描述的问题,但不同的是访问json-default包下的action,它根本就没有进入到自定义的AuthorityIntercept中,不知道为什么,请教一下!PS:我的AuthorityIntercept 继承的是MethodFilterInterceptor

相关推荐

Global site tag (gtag.js) - Google Analytics