Spring HandlerInterceptor 接口究竟是如何工作的?一个教程例子的一些疑惑
How exactly work the Spring HandlerInterceptor interface? Some doubts about a tutorial example
我正在研究在 Spring MVC 应用程序中使用 拦截器 的教程。
因此,根据我的理解(如果我做错了断言请纠正我),JavaEE 拦截器用于横切关注点(AOP 开发)。拦截器与 Java EE 管理的 classes 结合使用,以允许开发人员在关联目标 class 上结合方法调用或生命周期事件调用拦截器方法。拦截器的常见用途是记录、审计和分析。
所以在我看来,拦截器基本上可以用于这样的任务:"When a specific method of a specific class is called do something before that this methos is executed or, at the contrary, "当调用特定 class 的特定方法时,在此之后做一些事情方法被执行.
这是真的还是我遗漏了什么?
所以在我的例子中我有以下情况:
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>
这意味着 SiteInterceptor 是为所有 http 请求(对于所有资源)定义的。
那么这是 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 之前和之后执行一些特定的横切任务(例如:“进入和退出时记录控制器方法)。但是我可以使用 Spring AOP 模块来完成相同的任务吗?更好的解决方案是什么?如果可以的话,为什么 Spring 会给我提供这个解决方案使用 Spring AOP?
执行相同的任务
2) interceptor 概念和 filter 概念之间是否存在某种关系?
HandlerInterceptor
确实是拦截器,但它们没有使用任何 AOP 基础结构。它们只是 Spring bean,被 Spring MVC 用来拦截请求并对其应用一些自定义处理。
关于 preHandle
、postHandle
、afterCompletion
的大部分问题都可以得到解答 by looking at the javadoc:
- preHandle:调用handler之前;如果处理程序是控制器,则在执行控制器方法之前
- postHandle:在控制器方法之后,但在渲染阶段之前
- afterCompletion:渲染后
其他问题:
- AOP 在那里不起作用,因为那些
HandlerInterceptor
总是接收相同的参数集(HttpServletRequest
、HttpServletResponse
等),而控制器方法可以有非常灵活的签名
HandlerInterceptor
是 Spring MVC 的局部概念,而 Servlet 过滤器是 Servlet 规范的一部分。他们不提供相同的可能性。 HandlerInterceptor
级别更高,允许在特定阶段挂钩行为。 Servlet 过滤器是 "lower" 级别,但可以通过 HTTP 更好地控制 reading/writing 字节
我正在研究在 Spring MVC 应用程序中使用 拦截器 的教程。
因此,根据我的理解(如果我做错了断言请纠正我),JavaEE 拦截器用于横切关注点(AOP 开发)。拦截器与 Java EE 管理的 classes 结合使用,以允许开发人员在关联目标 class 上结合方法调用或生命周期事件调用拦截器方法。拦截器的常见用途是记录、审计和分析。
所以在我看来,拦截器基本上可以用于这样的任务:"When a specific method of a specific class is called do something before that this methos is executed or, at the contrary, "当调用特定 class 的特定方法时,在此之后做一些事情方法被执行.
这是真的还是我遗漏了什么?
所以在我的例子中我有以下情况:
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>
这意味着 SiteInterceptor 是为所有 http 请求(对于所有资源)定义的。
那么这是 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 之前和之后执行一些特定的横切任务(例如:“进入和退出时记录控制器方法)。但是我可以使用 Spring AOP 模块来完成相同的任务吗?更好的解决方案是什么?如果可以的话,为什么 Spring 会给我提供这个解决方案使用 Spring AOP?
执行相同的任务2) interceptor 概念和 filter 概念之间是否存在某种关系?
HandlerInterceptor
确实是拦截器,但它们没有使用任何 AOP 基础结构。它们只是 Spring bean,被 Spring MVC 用来拦截请求并对其应用一些自定义处理。
关于 preHandle
、postHandle
、afterCompletion
的大部分问题都可以得到解答 by looking at the javadoc:
- preHandle:调用handler之前;如果处理程序是控制器,则在执行控制器方法之前
- postHandle:在控制器方法之后,但在渲染阶段之前
- afterCompletion:渲染后
其他问题:
- AOP 在那里不起作用,因为那些
HandlerInterceptor
总是接收相同的参数集(HttpServletRequest
、HttpServletResponse
等),而控制器方法可以有非常灵活的签名 HandlerInterceptor
是 Spring MVC 的局部概念,而 Servlet 过滤器是 Servlet 规范的一部分。他们不提供相同的可能性。HandlerInterceptor
级别更高,允许在特定阶段挂钩行为。 Servlet 过滤器是 "lower" 级别,但可以通过 HTTP 更好地控制 reading/writing 字节