一、Spring MVC 的数据转换和格式化
前面的应用,都只是用HandlerAdapter去执行处理器。
处理器和控制器不是一个概念,处理器是在控制器功能的基础上加上了一层包装,有了这层包装,在HTTP请求达到控制器之前它就能够对HTTP的各类消息进行处理。
首先当一个请求到达 DispatcherServlet 的时候,需要找到对应的HandlerMapping,然后根据 HandlerMapping 去找到对应的 HandlerAdapter 执行处理器。处理器在要调用的控制器之前,需要先获取 HTTP (即jsp文件对应的网页)发送过来的信息,然后将其转变为控制器的各种不同类型的参数,这就是各类注解能够得到丰富类型参数的原因。
它首先用 HTTP 的消息转换器(HttpMessageConverter)对消息转换,但是这是一个比较原始的过程,它是String 类型和文件类型比较简易的转换,还需要进一步转换为 POJO 或者其他丰富的参数类型。为了拥有这样的能力,Spring 4 提供了转换器和格式化器,这样通过注解的信息和参数的类型,它就能把 HTTP 发送过来的各种消息转换为控制器所需要的各类参数了。
当处理器处理完了这些参数的转换,它就会进行验证,验证表单的方法已经提过。完成了这些内容,下一步就是调用开发者所提供的控制器了,将之前转换成功的参数传递进去,这样我们开发的控制器就能够得到丰富的 Java 类型的支持了,进而完成控制器的逻辑,控制器完成了对应的逻辑,返回结果后,处理器如果可以找到对应处理结果类型的 HttpMessageConverter 的实现类,它就会调用对应的 HttpMessageConverter 的实现类方法对控制器返回的结果进行 HTTP 转换,这一步不是必须的,可以转换的前提是能够找到对应的转换器,做完这些处理器的功能就完成了。
接下来就是关于视图解析和视图解析器的流程了,整个过程是比较复杂的,有时候要自定义一些特殊的转换规则,比如如果需要和第三方合作,合作方可能提供的不是一个良好的JSON 格式,而是一些特殊的规则,这个时候就可能需要使用自定义的消息转换规则,把消息类型转换为对应的 Java 类型,从而简化开发。
对于 Spirng MVC ,在XML上配置了<mvc:annotation-driven>,或者 Java 配置的注解上加入@EnableWebMvc 的时候,Spring IoC 容器会自定义生成一个关于转换器和格式化器的类实例----------FormattingConversionServiceFactoryBean,这样就可以从 Spring IoC容器中获取这个对象了。FormattingConversionServiceFactoryBean可以生成DefaultFormattingConversionService类对象,类对象继承了一些类,并实现了许多接口。
其中,顶层接口是ConversionService接口,它还实现了转换器的注册机(ConverterRegistry)和格式化器注册机(FormatterRegistry)两个接口。
而事实上 Spring MVC 已经注册了一些常用的转换器和格式化器。
在运行控制器之前,处理器就会使用这些转换器把 HTTP 的数据转换为对应的类型,用以填充控制器的参数,这就是为什么可以在控制器保持一定的规则下就能得到参数的原因。
当控制器返回数据模型后,再通过 Spirng MVC 后面对应的流程渲染数据,然后显示给客户端。
在Java类型转换之前,在 Spring MVC 中,为了应对 HTTP 请求,它还定义了HttpMessageConverter,它是一个总体的接口,通过它可以读入HTTP的请求内容,即在读取 HTTP 请求的参数和内容的时候会先用 HttpMessageConverter 读出,做一次简单转换为 Java 类型,主要是字符串,然后就可以使用各类转换器进行转换了,在逻辑业务处理完成后,还可以通过它把数据转换为相应给用户的内容。
对于转换器而言,在 Spring 中有两大类,一种是由 Converter 接口所定义的,另外一种是 GenericConverter,它们都可以使用注册机注册。但是,它们都是来自于 Spring Core 项目,它的作用范围是 Java 内部各种类型之间的转换。
1.HttpMessageConverter 和 JSON 消息转换器
HttpMessageConverter 是定义从 HTTP 接收请求信息和应答给用户的,用的比较多的实现类是 MappingJackson2HttpMessageConverter,这是一个关于 JSON 消息的转换类,通过它能够把控制器返回的结果在处理器内转换为 JSON 数据。
(1)注册MappingJackson2HttpMessageConverter
jsonConverter中的application/json;charset=UTF-8表示 HTTP 相应请求的类型是一个 JSON 类型,当在控制器中使用 @ResponseBody 的时候,Spring MVC 便会将应答请求转变为关于 JSON 的类型。这样的一次转换,就意味着处理器会在控制器返回结果后,遍历其项目中定义的各类HttpMessageConverter 实现类,由于 MappingJackson2HttpMessageConverter 定义为支持 JSON 数据的转换,它和@ResponseBody 所定义的相应类型一样,因此 Spirng MVC 就知道采用 MappingJackson2HttpMessageConverter 将控制器返回的结果进行处理,这样就转换为了 JSON 数据集了。
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="jsonConverter" /> </list> </property> </bean> <bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean>
(2)通过 @ResponseBody 注解可以使用上面配置的消息转换器
当通过@ResponseBody注解后,Spring MVC 就会将控制器返回的结果通过类型判断找到 MappingJackson2HttpMessageConverter 实例,进而在处理器内部转变成 JSON 类型。
@RequestMapping(value = "/getRole") // 注解,使得Spring MVC把结果转化为JSON类型响应,进而找到转换器 @ResponseBody public Role getRole(Long id) { Role role = roleService.getRole(id); return role; }
(3)测试(复习:这里getRole(Long id)是通过默认的参数一致性进行参数传递的,不需要加注解)
日志:
第一行,返回 JDBC 连接后,然后,第二行是关键:
通过之前定义过的处理器规则:将[[email protected]]转换成"application/json"形式,通过[[email protected]] 实例
org.springframework.jdbc.datasource.DataSourceUtils: Returning JDBC Connection to DataSource org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor: Written [[email protected]] as "application/json" using [org.springfr[email protected]1ec15d1b] org.springframework.web.servlet.DispatcherServlet: Null ModelAndView returned to DispatcherServlet with name ‘dispatcher‘: assuming HandlerAdapter completed request handling org.springframework.web.servlet.FrameworkServlet: Successfully completed request org.springframework.beans.factory.support.AbstractBeanFactory: Returning cached instance of singleton bean ‘SqlSessionFactory‘
HttpMessageConverter 的主要作用在于 Java 和 HTTP 之间的消息转换。
2.一对一转换器(Converter)
3.数组和集合转换器 GenericConverter
4.格式化器(Formmater)
二、为控制器添加通知
三、处理异常
四、国际化
1.概述
2.MessageSource接口
3.CookieLocaleResolver 和 SessionLocalerResolver
4.国际化拦截器(LocaleChangeInterceptor)
5.开发国际化
原文地址:https://www.cnblogs.com/BigJunOba/p/9781132.html