目录
2.1.2、HandlerMapping执行序列(Chain Of HandlerMapping)
2.2.4、AbstractWizardFormController
2.4.2、ViewResolver查找序列(Chain of ViewResolver)
3.1.1、使用MultipartResolver进行文件上传的简单分析
3.2.3、告知Handler与HandlerAdaptor的存在
3.3、框架内处理流程拦截与HandlerInterceptor
3.3.4、HandlerInterceptor之外的选择(Filter)
3.4、框架内的异常处理与HandlerExceptionResolver
3.5.3、Locale的变更与LocaleChangeHandler
3.6.3、切换主题的ThemeChangeInterceptor
4.2.1、自定义用于基于注解的Controller的HandlerMapping
4.2.2、自定义用于基于注解的Controller的HandlerAdaptor
4.3.4、通过@SessionAttribute管理Session数据
1、鸟瞰Spring MVC
Spring MVC框架的处理控制器的实现策略,与其他的请求驱动的Web框架的总体思路上是相似的,通过引入Front Controller和Page Controller的概念来分离流程控制逻辑与具体的Web请求处理逻辑。org.springframework.web.servlet.DispatcherServlet就是Spring MVC框架中的Front Controller,它负责接收并处理所有的web请求,只不过针对具体的处理逻辑,它会委派给它的下一级控制器去实现,即org.springframework.web.servlet.mvc.Controller,而org.springframework.web.servlet.mvc.Controller则对应Page Controller的角色定义。
DispatcherServlet的处理流程可以简单概括如下:
1、HandlerMapping(Web请求的处理协调者)
在Web请求到达DispatcherServlet之后,Dispatcher将寻求具体的HandlerMapping实例,以获取对应当前Web请求的具体处理类,即org.springframework.web.servlet.Controller。
2、org.springframework.web.servlet.mvc.Controller(Web请求的具体处理者)
org.springframework.web.servlet.mvc.Controller是对应DispatcherServlet的次级控制器,它本身实现了对应某个具体Web请求的处理逻辑。在我们所使用的HandlerMapping查找到当前Web请求对应哪个org.springframework.web.servlet.mvc.Controller的具体实例之后,DispatcherServlet即可获得HandlerMapping所返回的结果,并调用org.springframework.web.servlet.mvc.Controller的出来方法来处理当前的Web请求。
org.springframework.web.servlet.mvc.Controller的处理方法执行完毕之后,将返回一个org.springframework.web.servlet.ModelAndView实例,ModelAndView包含了如下两部分信息:
- 视图的逻辑名称(或者具体的视图实例)。DispatcherServlet就根据该视图的逻辑名称,来觉得用户显示哪个视图。
- 模型数据。视图渲染过程中需要将这些模型数据并入视图的显示中。
有了ModelAndView所包含的视图与模型二者的信息之后,DispatcherServlet就可着手视图的渲染工作了。
3、ViewResolver和View
Spring MVC通过引入org.springframework.web.servlet.View接口定义,来统一的抽象视图的生成策略。之后,DispatcherServlet只需要根据Spring Controller处理完毕之后通过ModelAndView返回的逻辑视图名称查找具体的view实现。然后委派该具体的View实现类来根据模型数据,输出具体的视图内容即可。
与HandlerMapping帮助DispatcherServlet查找具体的SpringController以处理Web请求类似,DispatcherServlet现在需要依赖于某一个org.springframework.web.servlet.ViewResolver来帮它处理逻辑视图与具体View实例之间的映射对应关系。ViewResolver将根据ModelAndView中的逻辑视图名查找相应的view实现类,然后将查找的结果返回DispatcherServlet。DispatcherServlet最终会将ModelAndView中的模型数据交给返回的view来处理最终的视图渲染工作。
至此,整个DispatcherServlet的处理流程即告结束。
2、Spring MVC的主要角色
2.1、HandlerMapping
HandlerMapping帮助DispatcherServlet进行Web请求的URL到具体处理类的匹配。在Spring MVC中,并不局限于使用org.springframework.web.servlet.mvc.Controller作为DispatcherServlet的次级控制器来进行具体的Web请求的处理。我们还可以使用其他类型的次级控制器,包括Spring MVC提供的除了Controller之外的次级控制器类型,或者第三方Web开发框架中的Page Controller组件,而所有这些次级控制器类型,在Spring MVC中都称作Handler。HandlerMapping要处理的也就是Web请求到相应Handler之间的映射关系。
HandlerMapping的定义如下:
public interface HandlerMapping {
String PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE = HandlerMapping.class.getName()+".pathWithinHandlerMapping";
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
2.1.1、可用的HandlerMapping
Spring MVC默认提供了多个HandlerMapping的实现供我们选用,除了BeanNameUrlHandlerMapping之外,还有如下几个:
- SimpleUrlHandlerMapping。较之BeanNameUrlHandlerMapping,该实现类进一步解除了请求URL与Handler的beanName之间的耦合,并且支持更灵活的映射表达方式。
- ControllerClassNameHandlerMapping。
- DefaultAnnotationHandlerMapping。
SimpleUrlHandlerMapping
使用BeanNameHandlerMapping进行Web请求到具体Handler的映射管理,需要我们保证视图模板中的请求路径,必须与容器中对应的Handler的beanName一致。
SimpleUrlHandlerMapping允许视图一方和handler一方自由活动,只不过最后由SimpleUrlHandlerMapping进行“统筹”。
使用SimpleUrlHandlerMapping的另一个好处就是,我们可以使用类似于ANT路径形式的模式匹配,这样我们就可以通过各种表达式,将一组或者多组拥有某种相似特征的Web处理请求映射给相应的Handler处理。
2.1.2、HandlerMapping执行序列(Chain Of HandlerMapping)
在基于Spring MVC的Web应用程序中,我们可以为DispatcherServlet提供多个HandlerMapping供其使用。DispatcherServlet在选用HandlerMapping的过程中,将根据我们所指定的一系列HandlerMapping的优先级进行排序,然后优先使用优先级在前的HandlerMapping。如果当前的HandlerMapping能够返回可用的Handler,DispatcherServlet则使用当前返回的Handler进行Web请求处理,而不再继续询问其他的HandlerMapping。否则,DispatcherServlet将继续按照各个HandlerMapping的优先级进行询问,直到获取一个可用的Handler为止。
HandlerMapping的优先级规定遵循Spring框架内一贯的Ordered接口所规定的语义。Spring MVC中可用的HandlerMapping实现全都实现了Ordered接口。
如果不为HandlerMapping明确指定order,那么默认值为Integer.MAX_VALUE,对应最低优先级。
2.2、Controller
Controller是Spring MVC框架支持的用于处理具体Web请求的handler类型之一。
public interface Controller{
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
- 自由挥洒派的Controller。AbstractController和MultiActionController归为自由挥洒一派,这一派的做事风格为,从HttpServletRequest中获取参数,然后验证,调用业务层逻辑,最终返回一个ModelAndView,甚至,可以直接通过HttpServletResponse输出最终的视图。
- 规范操作派的Controller。以BaseCommandController为首的规范操作一派,对Web处理过程中的某些通用逻辑做了进一步的规范化封装,规范化的方面主要包括:
- 自动抽取请求参数并绑定到指定的Command对象。
- 提供了统一的数据验证方式,BaseCommandController及其子类可以接收一组org.springframework.validation.Validator以进行数据验证,我们可以根据具体数据提供相应的Validator实现。
- 规范化了表单(Form)请求的处理流程,并且对简单的多页面表单请求处理提供支持。
2.2.1、AbstractController
AbstractController是整个Controller集成层次的起源,该类通过模板方法模式(Template Method Pattern)帮我们解决了如下几个通用的关注点:
- 管理当前Controller所支持的请求方法类型(GET/POST)
- 管理页面的缓存设置,即是否允许浏览器缓存当前页面
- 管理执行流程在会话(Session)上的同步
而我们所要做的,只不过是在AbstractController所公开的handleRequestInternal(request,response)模板方法中实现具体Web请求处理过程中的其他逻辑。
2.2.2、MultiActionController
MultiActionController继承了AbstractController,所以也就拥有了AbstractController所处理的那些通用关注点的能力。除此之外,MultiActionController还提供了以下功能。
- 请求参数到Command对象的绑定。
- 通过Validator的数据验证。这个功能与MultiActionController的数据绑定是一起的,一旦启用了到Command对象的数据绑定,那么,绑定过程中MultiActionController会自动调用我们注册的一系列Validator进行数据验证。当然,即使不用数据绑定功能,也同样可以自行决定是否调用相应的Validaor。
- 细化的异常处理方法。可以定义一系列的异常处理方法,用于处理Web请求处理过程中所抛出的特定类型的异常。
为了在MultiActionController中处理多个请求,我们需要定义多个Web请求处理方法,分别对应每个Web请求的处理。这些Web请求处理方法可以定义在MultiActionController的子类中,也可以定义在某一个将来可以指定给MultiActionController的委派对象(delegate)内,但Web请求处理方法的签名必须符合一定的要求,如下所示:
方法的返回值有三种类型,分别对应如下语义:
- 返回ModelAndView表示正常的Web处理方法,后继的ViewResolver和View处理流程,依照之前的DispatcherServlet的流程进行。
- 返回Map表明只返回了模型数据,而没有返回逻辑视图名。这时,将寻求默认的视图名。这个工作由org.springframework.web.servlet.RequestToViewNameTranslator负责。
- 返回void,则表明既没有返回模型数据,也没有返回逻辑视图名。这是我们认为,当前Web请求处理方法自行处理掉了视图的渲染和输出。
1、MultiActionController的助理MethodNameResolver
org.springframework.web.servlet.mvc.multiaction.MethodNameResolver的主要工作,就是帮助MultiActionController决定当前Web请求应该交给哪个方法来处理,其定义如下:
public interface MethodNameResolver{ String getHandlerMethodName(HttpServletRequest request) throws NoSuchRequestHandlingMethodException; }
MethodNameResolver为MultiActionController提供了灵活的Web请求到对应处理方法的映射策略,包括根据Web请求的URL进行映射,或者根据某个参数值进行映射等。MethodNameResolver本身作为一个策略接口定义,在Spring MVC框架内默认提供了如下三种策略实现。
1、InternalPathMethodNameResolver
如果没有为MultiActionController明确指定任何MethodNameResolver,那么InternalPathMethodNameResolver将作为默认的MethodNameResolver实现,以进行Web请求与具体处理方法间的映射解析。InternalPathMethodNameResolver将提取URL最后一个(/)之后的部分并去除扩展名,作为要返回的方法名称。比如:
如果将/simplefx/macontroller/*通过HandlerMapping指定映射到某个MultiActionController实现来处理,那么对应以上4组URL的Web请求,将分别由这个MultiActionController的listing、create、update以及delete4个方法来处理。
当然,我们也可以通过设定InternalPathMethodNameResolver的prefix和suffix来有限的修饰映射行为,比如:
当使用如上的InternalPathMethodNameResolver定义来映射刚才4组URL的时候,对应的处理方法名应该变成rate_listing、rate_create、rate_update以及rate_delete。
2、PropertiesMethodNameResolver
PropertiesMethodNameResolver与InternalPathMethodNameResolver的唯一相同点在于,它们都是基于请求的URL进行映射(二者有共同的父类AbstractUrlMethodNameResolver)。通过Pro

本文深入探讨Spring MVC框架的核心组件,包括HandlerMapping、Controller、ModelAndView、ViewResolver以及视图处理。详细介绍了不同类型的Controller实现,如AbstractController、MultiActionController等,以及视图定位器ViewResolver的实现和视图渲染。此外,还讨论了基于注解的Controller,揭示了Spring MVC处理Web请求的完整流程。















最低0.47元/天 解锁文章
3023

被折叠的 条评论
为什么被折叠?



