• 面试题:struts 拦截器和过滤器


    拦截器和过滤器的区别

    过滤器是servlet规范中的一部分,任何java web工程都可以使用。

    拦截器是struts2框架自己的,只有使用了struts2框架的工程才能用。

    过滤器在url-pattern中配置了/*之后,可以对所有要访问的资源拦截。

    拦截器它是只有进入struts2核心内部之后,才会起作用,如果访问的是jsp,html,css,image或者js是不会进行拦截的。

    同时,拦截器还是AOP编程思想的具体体现形式。AOP(Aspect-Oriented Programming)简单的说就是:

    在不修改源码的基础上,已有的方法进行动态增强。

    在struts2中,拦截器它就是对我们的动作方法进行增强。(其实就是把重复性的代码提取出来,然后放到拦截器中,统一管理,统一调用)

    1.1.1 拦截器的执行时机

    在访问struts2核心内部时,在动作方法执行之前先正序执行,然后执行动作方法,执行完动作方法和结果视图之后,再倒序执行。所以它是先进后出,是个栈的结构。

    1.2自定义拦截器
    在程序开发过程中,如果需要开发自己的拦截器类,就需要直接或间接的实现com.opensymphony.xwork2.interceptor.Interceptor接口。其定义的代码如下:
    public interface Interceptor extends Serializable {
    void init();
    void destroy();
    String intercept(ActionInvocation invocation) throws Exception;
    }
    该接口提供了三个方法,其具体介绍如下。
    void init():该方法在拦截器被创建后会立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化
    void destroy():该方法与init方法相对应,在拦截器实例被销毁之前,将调用该方法来释放和拦截器相关的资源它在拦截器的生命周期内,也只被调用一次
    String intercept(ActionInvocation invocation) throws Exception:该方法是拦截器的核心方法,用来添加真正执行拦截工作的代码,实现具体的拦截操作。它返回一个字符串作为逻辑视图系统根据返回的字符串跳转到对应的视图资源每拦截一个动作请求, 该方法就会被调用一次。该方法的ActionInvocation参数包含了被拦截的Action的引用,可以通过该参数的invoke()方法,将控制权转给下一个拦截器或者转给Action的execute()方法。
    如果需要自定义拦截器,只需要实现Interceptor接口的三个方法即可。然而在实际开发过程中,除了实现Interceptor接口可以自定义拦截器外,更常用的一种方式是继承抽象拦截器类AbstractIntercepter。该类实现了Interceptor接口,并且提供了init()方法和destroy()方法的空实现。使用时,可以直接继承该抽象类,而不用实现那些不必要的方法。拦截器类AbstractInterceptor中定义的方法如下所示:
    public abstract class AbstractInterceptor implements Interceptor {
    public void init() {}
    public void destroy() {}
    public abstract String intercept(ActionInvocation invocation)
    throws Exception;
    }
    从上述代码中可以看出,AbstractInterceptor类已经实现了Interceptor接口的所有方法,一般情况下,只需继承AbstractInterceptor类,实现interceptor()方法就可以创建自定义拦截器。
    只有当自定义的拦截器需要打开系统资源时,才需要覆盖AbstractInterceptor类的init()方法和destroy()方法。与实现Interceptor接口相比,继承AbstractInterceptor类的方法更为简单。
    当然还有更简单的,AbstractInterceptor还有一个子类,MethodFilterInterceptor,该类中提供了两个属性,可以告知拦截器对哪些方法进行拦截或者对哪些方法排除。

    下图展示的就是拦截器的类结构视图:


    1.2.1自定义步骤
    通过在拦截器类视图上我们可以得知,我们定义拦截器可以有三种办法:
    第一种:定义一个类,实现Interceptor接口
    第二种:定义一个类,继承AbstractInterceptor
    第三种:定义一个类,继承MethodFilterInterceptor
    在这三种方式中,我们选择第二种和第三种都可以。那么后两种有什么区别呢?
    我们来看看AbstractorInteractor类中的代码:

    我们再来看看MethodFilterInterceptor中的代码:

    看完两个类之后,我们有了结论。即:选择第三种方式,比第二种多了一个功能,就是告知拦截器哪些方法我们需要拦截,哪些方法我们不需要拦截。(注意:不要想着很傻的问题,在需要拦截和不需要拦截的属性中提供同一个方法)
    根据以上的内容,我们开始编写我们自己的拦截器。

    1.1.1 拦截器的放行

    上一章节,我们演示时,发现没有放行,在拦截器中如何放行呢?我们之前已经介绍过几个拦截器了,例如ServletConfigInterceptor拦截器,可以看看它是怎么放行的。拦截器的方式:

    invocation.invoke()方法。请看下面的代码:

    /**

     * 自定义拦截器

    */

    public class MyInterceptor extends AbstractInterceptor {

     

    @Override

    public String intercept(ActionInvocation invocation) throws Exception {

    System.out.println("执行动作方法之前:MyInterceptor拦截了。。。。");

    String rtValue = invocation.invoke();//放行

    System.out.println("执行动作方法之后:MyInterceptor拦截了。。。。");

    System.out.println(rtValue);

    return rtValue;

    }

     

    }

    当上面的代码执行完,发现actionjsp都执行了。那么这个rtValue值是什么呢?

    1.1.2 拦截器的返回值

    其实拦截器的返回值,就是我们Action中,执行的动作方法返回值。

    Struts注解开发

    1.1.1 @Action

    出现的位置:

    它只能出现在Action类上或者动作方法上。一般情况下都是写在动作方法上。

    作用:

    指定当前动作方法的动作名称。也就是xml配置时action标签的name属性。

    属性:

    value指定动作名称。

    results[]它是一个数组,数据类型是注解。用于指定结果视图。此属性可以没有,当没有该属性时,表示不返回任何结果视图。即使用response输出响应正文。

    interceptorRefs[]它是一个数组,数据类型是注解。用于指定引用的拦截器。

     

     

     

    1.1.1 @Result

     

    出现的位置:

     

    它可以出现在动作类上,也可以出现在Action注解中。

     

    作用:

     

    出现在类上,表示当前动作类中的所有动作方法都可以用此视图。

     

    出现在Action注解中,表示当前Action可用此视图。

     

    属性:

     

    name指定逻辑结果视图名称。

     

    type指定前往视图的方式。例如:请求转发,重定向,重定向到另外的动作。

     

    location指定前往的地址。可以是一个页面,也可以是一个动作。

     

  • 相关阅读:
    css 负边距 小记
    javascript Array 方法学习
    使用自定义字体 @font-face 小试
    mongodb 基本指令学习 (2)
    mongodb 基本指令学习
    ASP.NET MVC AJAX调用JsonResult方法并返回自定义错误信息
    MVC MVVM Knockout 常遇问题总结
    关于 mvc 中 连字符
    在一般处理程序中,把Form Post过来的表单集合转换成对象 ,仿 MVC post,反射原理
    EF经验分享_jimmyzzc
  • 原文地址:https://www.cnblogs.com/shan1393/p/9058341.html
Copyright © 2020-2023  润新知