Spring HandlerInterceptor接口究竟如何工作?对教程示例有些怀疑

时间:2015-12-03 19:21:40

标签: spring spring-mvc interceptor

我正在研究在Spring MVC应用程序中使用拦截器的教程。

所以,根据我的看法(如果我做错了断言,请纠正我),JavaEE拦截器用于交叉关注(AOP开发)。 nterceptors与Java EE托管类结合使用,允许开发人员结合方法调用或生命周期事件在关联的目标类上调用拦截器方法。拦截器的常见用途是记录,审计和分析。

所以在我看来,基本上拦截器可以用于以下任务:"当一个特定类的特定方法被调用时,在执行此方法之前执行某些操作或者,相反,"当某个特定类的特定方法被调用后,执行此方法

是真的还是我错过了什么?

所以在我的例子中我有以下情况:

1)进入 mvc-config.xml 文件(配置MVC的文件),我可以找到:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/*" />
        <bean class="spring.mvc.interceptor.SiteInterceptor" />
    </mvc:interceptor>

    <mvc:interceptor>
    <mvc:mapping path="/*" />
        <bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
            <property name="paramName" value="language" />
        </bean>
    </mvc:interceptor>
</mvc:interceptors>

定义2个不同的拦截器,第一个是:

    <mvc:interceptor>
        <mvc:mapping path="/*" />
        <bean class="spring.mvc.interceptor.SiteInterceptor" />
    </mvc:interceptor>

这意味着为所有http请求(针对所有资源)定义了 SiteInterceptor

然后这是 SiteInterceptor 代码:

public class SiteInterceptor implements HandlerInterceptor, MessageSourceAware {

    private MessageSource messageSource;

    @Override
    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;     
    }

    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("SiteInterceptor preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
            System.out.println("SiteInterceptor postHandle");   


    }

    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception exception)
            throws Exception {
        System.out.println("SiteInterceptor afterCompletion");  
        System.out.println("site.maintenance: " + messageSource.getMessage("site.maintenance", null, Locale.ENGLISH));


        System.out.println("site.maintenance: " + messageSource.getMessage("test.param", null, Locale.ENGLISH));
    }

}

所以我已经定义了一些方法和我所理解的:

  • preHandle():在处理被叫请求(例如页面)之前执行(所以它意味着什么?它是在执行控制器方法之前执行的)处理这个资源?还是什么?)

  • postHandle():什么时候执行?当控制器方法完成其执行时,在此之前呈现视图?或者是什么?

  • afterCompletion():是否在呈现视图时执行? (之后Spring视图解析器能够完成它的工作吗?)

你能帮我解释一下我的疑惑吗?

我的另一个疑问是:

1)因此在我看来,这些方法用于在控制器方法处理HttpRequest之前和之后执行某些特定的交叉任务(例如:&#34;当输入时退出和退出时控制器方法)。但是我可以使用 Spring AOP 模块执行相同的任务吗?什么是更好的解决方案?如果我可以使用 Spring AOP 执行相同的任务,为什么Spring会为我提供此解决方案?

2)拦截器概念与过滤器概念之间存在某种关系?

1 个答案:

答案 0 :(得分:2)

HandlerInterceptor确实是拦截器,但他们没有使用任何AOP基础设施。它们只是Spring bean,Spring MVC使用它来拦截请求并对它们应用一些自定义处理。

关于preHandlepostHandleafterCompletion的大多数问题都可以回答by looking at the javadoc

  • preHandle:在调用处理程序之前;如果处理程序是控制器,则它在执行Controller方法之前
  • postHandle:在Controller方法之后,但在渲染阶段之前
  • afterCompletion:渲染后

其他问题:

  1. AOP不会在那里工作,因为那些HandlerInterceptor总是收到同一组参数(HttpServletRequestHttpServletResponse等),而Controller方法可以有非常灵活的签名
  2. HandlerInterceptor是Spring MVC的本地概念,而Servlet过滤器是Servlet规范的一部分。他们没有提供相同的可能性。 HandlerInterceptor是更高级别,允许在特定阶段挂钩行为。 Servlet过滤器是“较低”级别,但可以更好地控制通过HTTP读取/写入字节