关于struts2中应用拦截器与filter对权限进行控制
我的项目采用了struts2+ExtJs的框架,在extjs的导航树中应用了iframe,监听树节点的click事件,如:html:'<iframe............>'调用了对应的jsp文件,这种框架的结合实际上大部分采用了ajax的方式来取后台的数据.如struts2.xml文件中这样配置
?
?
?有人说这样的配置,由于继承了json-default无法应用struts2中的拦截器,网上大部分的拦截器例子是继承了struts-default这个包,但是昨天仔细看struts2的源文件发现json-default也是继承了struts-default这个包,所以在
?
?
?配置拦截器也是起作用的.注意的是login这个包就别拦截了,如果拦截了就永远也无法登录了,当然如果把它配置在其它的action中也是可以的,只不过要在拦截器类把它放行就可以了,不过我还是喜欢这样配置,简单,拦截器类写起来也简单下面就是那个简单的拦截器类,利用session进行判断:
?
<result name="login" type="redirect">/login.jsp</result> </global-results> <action name="findallyhxxk" method="findAllYhxxk"><result type="json"><param name="root">page</param><param name="excludeProperties">conditions,limit,start,success,objCondition</param></result></action><action name="findmaxyhbh" method="findMaxYhbh"><result type="json"><param name="root">yhbh</param></result></action><action name="saveyhxxk" 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文件.
1 楼 xiaofengyu 2011-07-12 你好,我也遇到了你所描述的问题,但不同的是访问json-default包下的action,它根本就没有进入到自定义的AuthorityIntercept中,不知道为什么,请教一下!PS:我的AuthorityIntercept 继承的是MethodFilterInterceptor 2 楼 wzwahl36 2012-03-23 使用struts + extjs做管理系统时,使用拦截器拦截action来验证是否登录,如果没有登录,会跳转到login.jsp,现在的问题就是拦截到了,但是不能跳转~~
这个问题在你的博文中也提到了,请问这个问题怎么解决?
因为这个web系统还有一个前台主页,如果采用过滤器的话,这个url太难解析了~
如果博主知道怎么解决这个问题,email:wzwahl36@qq.com
thx.