我的项目采用了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文件.