HandlerExecutionChain和拦截器

在上一节中,您了解了Spring提供的不同处理程序映射。处理程序映射例如基于请求URL确定用户已发出请求的执行路径。找到适当的映射后,处理程序映射将返回所谓的HandlerExecutionChain,该指令指示调度程序Servlet如何进行。

HandlerExecutionChain由拦截器和一个处理程序(or controller)组成,一起提供访问业务逻辑和其他支持服务(如身份验证,日志记录和筛选)所需的全部内容。

HandlerExecutionChain始终包含处理请求的处理程序(换句话说,执行实际的逻辑)。 处理程序可以是任何类型。 对处理程序没有特定的要求,只要它能够处理请求即可,并且有一个适当的HandlerAdapter知道如何在HandlerExecutionChain中使用该处理程序。 默认情况下,Spring使用两个HandlerAdapter,一个用于调用从Controller接口派生的处理程序,另一个用于调用ThrowAwayController类型的处理程序。 本章后面将介绍不同类型的控制器。

HandlerExecutionChain也可能包含一个或多个HandlerInterceptor,它们能够拦截传入的请求。 拦截特别适合诸如日志记录,安全性和审计之类的操作。 有关概念本身的更深入讨论可以在第4章中找到。

我们已经讨论了传入请求所涉及的工作流程。让我们回顾一下拦截器:

  1. 在执行链中可用的任何HandlerInterceptor上调用preHandle(HttpServletRequest,HttpServletResponse,Object)。 在这种情况下,对象是链中的处理程序。 此调用允许您在允许实际处理程序执行其工作之前执行任何逻辑。 例如,您可以在此处检查是否允许用户发出此请求(可以使用进一步解释的UserRoleAuthorizationInterceptor进行此操作)。 根据调用的返回值,Spring将决定继续处理请求。 当返回false时,调度程序将假定拦截器已自行处理了请求(例如,当安全性约束应阻止用户发出请求时)。 在这种情况下,Spring将立即停止处理请求,这意味着将不会查询尚未调用preHandle()的其余拦截器,就像不会查询处理程序本身一样。 但是,任何在此刻之前成功返回true的拦截器都将接收afterCompletion()回调。

  2. 从HandlerExecutionChain中检索处理程序,然后开始寻找HandlerAdapter。 将检查所有可用的HandlerAdapter(在WebApplicationContext中注册或默认提供),以查看其中一个是否支持这样的处理程序(通常根据处理程序的类确定)。 在所有复杂情况下(可能很少见),都无需担心HandlerAdapter,其实现及其工作方式。 Spring的默认行为可以正常工作。

  3. 下一步是处理程序的实际执行。 这将执行您的实际业务逻辑,或者更好; 在进行一些初步的准备(例如数据绑定)之后,将请求委托给中间层。 请求执行完成后,您应该准备一个ModelAndView,其中包含JSP或例如Velocity模板呈现HTML页面或PDF文档所需的数据。

  4. 接下来,将使用postHandle(HttpServletRequest,HttpServletResponse,Object,ModelAndView)方法再次调用所有拦截器。在这里,您可以修改ModelAndView(可以向其中添加额外的属性,甚至可以删除某些东西)。这是您在渲染视图之前执行逻辑的最后机会。

  5. 接下来,将解析并渲染视图。我们将在本章后面介绍视图解析和渲染。

  6. 最后一步涉及在任何可用的拦截器上调用afterCompletion(HttpServletRequest,HttpServletResponse,Object,Exception)。对象是处理该请求所涉及的逻辑的处理程序。如果在请求完成期间发生了异常,则该异常也会传递到该异常中。

WebContentInterceptor

Spring提供了一些HandlerInterceptor的实现功能,这些实现功能是Web应用程序中经常需要的。其中之一就是WebContentInterceptor,它提供的功能可轻松修改Web应用程序的缓存行为,并提供有用的常规任务,例如限制Web应用程序支持的方法(GET,POST,PUT)。配置此拦截器的步骤如下(请注意,稍后将说明UserRoleAuthorizationInterceptor):

<bean >   
<property name="interceptors">     
<list>       
<ref local="contentInterceptor"/>      
 <ref local="userRoleAuthorizationInterceptor"/>   
 </list> 
</property>
 </bean>
      <bean>
         <property name="cacheSeconds">
         <value>30</value>
         </property>   
<property name="supportedMethods">
<value>GET</value>
</property> 
</bean>

下表显示了可用于内容拦截器的属性。
在这里插入图片描述

UserRoleAuthorizationInterceptor

Spring还具有一个简单的授权拦截器,该拦截器可以使用您指定的一组角色来检查用户的Principal。 将拦截器添加到处理程序映射中的方式与使用内容拦截器时相同。 UserRoleAuthorizationInterceptor具有称为authorizedRoles的属性,该属性是一个字符串数组。 拦截器直接委托给HttpServletRequest.isUserInRole(String)。 当发出请求的用户不具有拦截器配置中提到的角色时,会将HttpServletResponse.SC_FORBIDDEN发送到客户端,对应于状态码403。例如,使用web.xml描述符中的错误映射, 您可以将用户定向到适当的错误页面。 您还可以继承拦截器的子类,并重写handlerNotAuthorized(…)方法以执行自定义操作。

<bean>
   <property name="authorizedRoles">  
   	  <list>       
   	  	<value>administrator</value>     
       	<value>editor</value>   
      </list> 
    </property> 
   </bean>

重要
UsersRoleAuthorizationInterceptor可以与应用程序服务器的JAAS功能结合使用。 通常,UserRoleAuthorizationInterceptor仅在简单情况下就足够了:它并不旨在成为功能强大的常规安全解决方案。 要获得更完整的安全解决方案,包括高级功能(如单点登录),我们建议使用第10章中讨论的Spring Acegi安全系统。

Spring MVC提供的其他处理程序拦截器

Spring MVC提供的其他处理程序拦截器还涉及持久性和国际化:

OpenSessionInViewInterceptor和OpenPersistenceManagerInViewInterceptor:分别用于Hibernate和JDO。有关这些内容的更深入讨论,请参见第7章。

LocaleChangeInterceptor:使用它可以即时更改Web应用程序使用的语言环境。该特定的拦截器将在本章后面介绍。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值