Struts2拦截器Filter

拦截器

拦截器Filter是Struts2的核心。

Struts2的拦截器与Servlet中的过滤器相似。
在执行Action的execute()方法之前,Struts2先执行struts.xml中引用的拦截器,在执行完所有引用的拦载器的doIntercept()方法后,会执行Action的execute()方法。在Struts2的拦截器体系中,Struts2的内建拦截器完成了该框架的大部分操作,所以在实际的开发过程中通常是使用系统的拦截器。

在这里插入图片描述
拦截器的实现原理

Struts2拦截器的实现原理相对简单,当请求Action时,Struts2会查找配置文件(struts.xml),并根据其配置实例化相对的拦截器对象,然后串成一个列表,最后一个一个地调用列表中的拦截器。
比如:应用要求用户登陆,且必须为指定用户名才可以查看系统中某个视图资源;否则,系统直接转入登陆页面。对于上面的需求,可以在每个Action的执行实际处理逻辑之前,先执行权限检查逻辑,但这种做法不利于代码复用。因为大部分Action里的权限检查代码都大同小异,故将这些权限检查的逻辑放在拦截器中进行将会更加优雅。

拦截器什么时候执行?

在Action类对象创建之后,execute()方法调用之前之后执行(响应到客户端之前)。

拦截器的分类
系统拦截器(默认拦截器)
自定义拦截器
当系统拦截器满足不了需求,就要自定义拦截器.

系统拦截器
系统拦截器有很多,这里重点讲解:Timer和Token
struts-default.xml中intercept有很多系统拦截器

Timer 时间拦截器
作用:测试方法执行所耗的时间。

<action name="person" class="com.zking.action.PersonAction">
    <result>/success.jsp</result>
    <!--系统时间拦截器-->
    <interceptor-ref name="timer"></interceptor>
    <!--系统拦截器栈,使用拦载器一定要带这个栈才生效,这是个好习惯-->
    <interceptor-ref name="defaultStack"/>
</action>

说明:
当访问PersonAction类里所有方法之前,都会触发Timer拦截器,该拦截器显示方法执行消耗时间秒。
运行后发现并没有显示什么时间,原因是2.3缺少了commons-logging-1.1.jar日志包或log4j2日志包,项目中加入该包后再测试。

Token令牌拦截器

作用:解决表单重复提交问题。
办法一:重定向,不让地址栏出现action地址。(这里不再描述)
办法二:令牌,进Action要令牌(当天的火车票,进站时、出站时用,再想进站就要有新的票了)

令牌具体实现步骤:
(1)在表单中使用<s:token>会随机产生的一个字符串,隐藏的文本域。

<form action="" method="post">
    <s:token></s:token>
    ……
</form>

运行JSP页面后,会随机产生一个字符串的token:
在这里插入图片描述
第二步:在struts.xml中配置令牌的拦截器

<action name="person*" class="com.action.PersonAction">
<result>/success.jsp</result>
<!--令牌拦截器-->
<interceptor-ref name="token">
<!--这里可以配置token拦截器的排队方法-->
<!-- param name="excludeMethods">...</param -->
</interceptor>
<!-- 当出现重复提交时,自动跳转到error.jsp -->
<result name="invalid.token">/error.jsp</result>
<interceptor-ref name="defaultStack" />
</action>

可在error.jsp页面中添加<s:actionerror>显示重复提交信息。

自定义拦截器
(1)创建拦截器类
继承MethodFilterInterceptor类,并重写doIntercept方法,在方法中写业务逻辑。

public class MyInterceptor extends MethodFilterInterceptor {

//ActionInvocation为当前Action的运行状态
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
ActionContext ac = invocation.getInvocationContext();
//获得session  
Map session = ac.getSession();
User user = (User)session.get("user");
if(null==user){
   return “login”;
}
//通过放行
invocation.invoke();
return "usreMain";
}
}

先在拦截器doIntercept()方法中获取parameters对象:

Map paramMap = invocation.getInvocationContext().getParameters();

然后用parameters对象获取参数(是一个字符串数组):

String[] names = (String[])paramMap.get("user.userName");
String username = names[0];

配置拦截器

<struts>
<package name="mypack" extends="struts-default" namespace=”/admin”>
    <!--1. 声明自定义拦截器-->
<interceptors>
<interceptor name="loginInterceptor" class="com.zking.interceptor.MyInterceptor">
</interceptor>
</interceptors>

<action name="login" class="com.zking.LoginAction">
    <result name="success">success.jsp</result>
    <!--2. Action中引用自定义拦截器-->
    <interceptor-ref name="loginInterceptor"></interceptor-ref>
    <interceptor-ref name="defaultStack" />
</action>
</package>
</struts>

配置Action中某些方法执行时,不进行拦截:

<interceptor-ref name="loginInterceptor">
    <!-- 忽略login、add方法 -->
    <param name="excludeMethods">login,add</param>
</interceptor-ref>

案例:
我们尝试编写一个Session过滤用的拦截器,该拦截器查看用户Session中是否存在特定的属性(LOGIN属性)如果不存在,中止后续操作定位到LOGIN,否则执行原定操作,代码为:

public class CheckLoginInterceptor extends AbstractInterceptor {
    public static final String LOGIN_KEY = "LOGIN";
    public static final String LOGIN_PAGE = "global.login";
 
    public String intercept(ActionInvocation actionInvocation) throws Exception {
 
        //获得Action对象
        Object action = actionInvocation.getAction();
         //对LoginAction不做该项拦截
        if (action instanceof LoginAction) {
            return actionInvocation.invoke();
        }
 
        // 确认Session中是否存在LOGIN
        Map session = actionInvocation.getInvocationContext().getSession();

        String login = (String) session.get(LOGIN_KEY);
        if (login != null && login.length() > 0) {
            // 存在的情况下进行后续操作
            return actionInvocation.invoke();
        } else {
            // 否则终止后续操作,返回LOGIN
            System.out.println("请登录");
            return LOGIN_PAGE;
        }
    }
}

注册拦截器:

<interceptors>
    <interceptor name="login" class="com.zking.util.CheckLoginInterceptor"/>
    <interceptor-stack name="teamwareStack">
        <interceptor-ref name="login"/>
        <interceptor-ref name="defaultStack"/>
    </interceptor-stack>
</interceptors>

将上述拦截器设定为默认拦截器:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Struts2 中,可以使用拦截来防止 XSS 攻击。以下是一些步骤: 1. 创建一个类,继承 org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter。 ```java public class XSSFilter extends StrutsPrepareAndExecuteFilter { @Override protected void postInit(FilterConfig filterConfig) throws ServletException { super.postInit(filterConfig); // 添加 XSS 拦截 addFilter(new FilterHolder(new XSSInterceptor()), "/*", null); } } ``` 这个类的作用是在 Struts2 启动时添加一个 XSS 拦截。 2. 创建一个 XSS 拦截。 ```java public class XSSInterceptor implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 对请求参数进行 XSS 过滤 HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; filterChain.doFilter(new XSSRequestWrapper(request), response); } @Override public void destroy() { } } ``` 这个拦截的作用是对请求参数进行 XSS 过滤。 3. 创建一个 XSSRequestWrapper 类,继承 HttpServletRequestWrapper。 ```java public class XSSRequestWrapper extends HttpServletRequestWrapper { public XSSRequestWrapper(HttpServletRequest request) { super(request); } @Override public String getParameter(String name) { String value = super.getParameter(name); if (value != null) { value = Jsoup.clean(value, Whitelist.basic()); } return value; } } ``` 这个类的作用是重写 getParameter 方法,在获取请求参数时进行 XSS 过滤。 4. 在 web.xml 中添加过滤配置。 ```xml <filter> <filter-name>xssFilter</filter-name> <filter-class>com.example.XSSFilter</filter-class> </filter> <filter-mapping> <filter-name>xssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` 这个配置的作用是将 XSSFilter 拦截应用于所有的请求。 以上是一个简单的 Struts2 XSS 拦截的配置。但是需要注意的是,这个拦截只能对请求参数进行 XSS 过滤,对于响应内容的过滤需要使用其他的方案来解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值