spring mvc学习

1 概述

在web层,在框架的控制器实现方面,spring mvc对请求处理期间涉及的各种关注点进行了分离。

  • HandlerMapping 用于处理web请求与具体请求处理控制器间的映射匹配

  • 设置LocaleResolver用于国际化处理

  • viewResolver用于灵活的视图选择。

在表现层,spring运用逻辑命名视图,通过引入ViewResolver和view分离了视图类型的选择和渲染。

2 spring mvc 流程

spring mvc 通过分离主控制器与次级控制器的概念来分离流程控制逻辑与具体的web请求处理逻辑

spring mvc的主级控制器,负责接受并处理所有的web请求,对于具体的处理逻辑,交给它下一级控制器去实现。

servlet 处理web请求所作的工作。

  • 获取请求信息,比如请求路径,请求参数

  • 根据请求信息,调用具体服务对象处理具体web请求

  • 将要在视图中显示的数据模型通过request进行传递。

2.1 HandleMapping(web请求处理协调)

spring mvc 为了能够灵活处理映射的匹配,引入了HandleMapping用于管理web请求到具体的处理类之间的映射。以获取对应当前web请求的具体处理类controller.

2.2Controller(web请求的具体处理者)

Controller是对应DispatcherServlet的次级控制器,它本身对应了某个具体web请求的处理逻辑。在使用HandleMapping 查找到当前web请求对应的controler实例后,其即可获取HandleMapping所返回的结果,并调用其处理方法来处理当前web请求。 处理请求后,将返回ModeAndView实例,主要包含两下两部分信息。

  • 视图逻辑名称 用于决定用户显示那个视图

  • 模型数据 需要将这些数据并入视图显示中

2.3 viewResolver和view

用于屏蔽web框架在使用不同的web视图技术时的差异性。

  • 获取模型数据

  • 获取视图模板文件

  • 结合视图模板和模型数据

  • 将视图结果通过HttpServletResponses输出到客户端

其中view接口定义,用来统一抽象视图的生成策略,DispatcherServlet只需要根据controller处理完毕后通过modelAndview返回逻辑视图的名称找到具体的view实现,然后委派给view实现类,view在根据模型数据处理最终的渲染结果

而viewResolver用于处理逻辑视图与具体的view实例之间的映射关系

2.4 流程图

3 HandleMapping

所有这些次级控制器类型,在springmvc中称作Handle。而HandleMapping要处理的就是web请求到相应的Handler之间的映射关系。

public interface HandlerMapping {
	@Nullable
	HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

}

getHandle方法返回了HandlerExecutionChain用于处理具体web的请求Handler.

HandlerMapping的几种常用实现。

  • SimpleUrlHandlerMapping

  • ControllerClassNameHandlerMapping

  • DefaultAnnotationHandlerMapping

  • BeanNameUrlHandlerMapping

默认为BeannameHandlerMappping,需要我们保证视图模板中的请求路径必须与容器中对应的Handler的beanName一致。 我们可以使用SimpleUrlHandlerMapping解除之间的耦合。

这写HandlerMapping实现ordeedu接口,默认优先级最低,可以通过优先级来进行实现mapping的排序。

4 controller

是springmvc支持的用于处理web请求的handler类型之一。 AbstractController是整个Controller继承层次的起源,通过继承WebContentGenerator实现了

  • 管理当前controller所支持的请求方法类型(get/post)

  • 管理页面缓存设置,是否允许浏览器缓存当前页面

  • 管理执行流程在会话上的同步(Session)

4.1 数据绑定

使用数据绑定的最主要好处,就不需要在通过request.getParameter(String)方法遍历获取每个请求参数,然后根据需要转型为自己需要的类型。数据绑定功能帮助我们自动提取HttpservletRequest中的相应参数,然后转型为需要的对象类型。

  • 首先mvc将提取web请求中的所有参数名称,然后获取对应参数值,并放入一个值对象(PropertyValue),最后拥有其集合

  • 有了即将绑定到目标command对象数据原后,将这些数据根据目标对象中的各个域属性定义的类型进行转型,并设置到对象

  • 通过BeanWrapperImpl所依赖的一系列自定义的PropertyEditor进行类型转换。 ** 整个流程以ServletRequestDataBinder的形式进行了封装**

4.2 数据验证

使用的是validated的注解用于数据验证功能,而Errors则用于负责承载验证过程中出现的错误信息。

5 ModelAndView

controller在将web请求处理完成后,返回modelAndView实例,一部分为视图相关内容,可以是逻辑视图名称 ,也可以是具体的view实例,另一部分则是模型数据,视图渲染过程中将会把这些模型数据合并入最终的视图输出。用于解除具体的web请求处理Controler与视图渲染间的紧密耦合

模型数据: modelAndView以ModelMap的形式来保持模型数据,通过添加将数据加入到modelMap,最终将会在视图渲染阶段,由具体的view实现类获取并使用

5.1 视图定位器 viewResolver

根据Controller所返回的ModelAndVIew的逻辑视图名,为DispatcherServlet返回一个可用的view实例

在ViewResolver的实现类上AbstractCachingViewResolver默认启用了view的缓存功能

面向单一视图类型的ViewResolver 该类直接或间接地继承自UrlBasedViewResolver,我们不需要为它们配置具体的视图逻辑名到具体的view映射关系,只需要指定视图模板所在的位置,这些viewResolver就会按照逻辑视图名,构造对应的view实例并返回。

  • InternalResourceViewResolver 用于处理jsp模板类型的视图映射

  • XsltViewResolver 只负责根据视图名查找并返回xstlview类型的view实例

一般viewResolver内部可以根据**[prefix]+viewName+[suffix]**这样的url找到对应的模板文件,并构造对应的view实例而返回。

面向多视图类型的viewResolver 我们需要通过配置方式明确指定逻辑视图名与具体视图间的关系

  • ResourceBundleViewResolver 其构建在ResourceBundle,继承了ResourceBundle国际化支持的能力。将映射关系保存在properties文件中,内部将通过PropertiesBeanDefinitionReader加载这些配置信息。

  • xmlViewResolver 最主要的区别为所采用的配置文件格式不一样,ResourceBundleViewResolver按照spring ioc 容器所接受的properties配置格式配置逻辑视图与具体视图间的关系,而xmlViewResolver则是按照spring ioc容器所接受的xml配置文件格式来加载映射信息

  • baseNameViewResolver 可以直接将view实例注册到当前的DispatcherServlet所使用的特定的webApplicationContext中,不需要像XmlViewResolver在开辟空间。

5.2 view

public interface View {

	String RESPONSE_STATUS_ATTRIBUTE = View.class.getName() + ".responseStatus";


	String PATH_VARIABLES = View.class.getName() + ".pathVariables";


	String SELECTED_CONTENT_TYPE = View.class.getName() + ".selectedContentType";


	@Nullable
	default String getContentType() {
		return null;
	}


	void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)
			throws Exception;

}

主要的职责是在render方法中实现最终的视图渲染工作。

end
  • 作者:王富贵(联系作者)
  • 发表时间:2021-08-14 18:08
  • 版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 评论