org.springframework.web.context.request
使用HttpMessageConverter
==========================
HttpMessageConverter接口可以将请求信息转换为一个对象(类型为T),并将对象(类型为T)绑定到请求方法的参数中或输出为响应信息。DispatcherServlet默认已经安装了RequestMethodHandlerAdapter作为HandlerAdapter组件的实现类,HttpMessageConverter即由RequestMethodHandlerAdapter使用,将请求信息转换为对象,或将对象转换为响应信息。
HttpMessageConverter的实现类
============================
Spring为HttpMessageConverter提供了众多的实现类:
实现类
=======
实现类
=======
默认的HttpMessageConverter
===========================
RequestMappingHandlerAdapter已经默认装配了以下的HttpMessageConverter:
-
StringHttpMessageConverter
-
ByteArrayHttpMessageConverter
-
SourceHttpMessageConverter
-
AllEncompassingFormHttpMessageConverter
装配其他类型的HttpMessageConverter
===============================
如果需要装配其他类型的HttpMessageConverter,可以在Spring的Web容器上下文中自行定义一个RequestMappingHandlerAdapter,注册若干HttpMessageConverter。如果在Spring web容器中显式定义了一个RequestMappingHandlerAdapter,则Spring MVC将使用它 覆盖 默认的RequestMappingHandlerAdapter。
使用HttpMessageConverter
==========================
-
可以使用@RequestBody、@ResponseBody对处理方法进行标注
-
可以使用HttpEntity、ResponseEntity作为处理方法的入参或返回值
RestTemplate是Spring的模板类,可以使用该类调用Web服务端的服务,它支持Rest风格的URL。
结论
======
-
当控制器处理方法使用到@RequestBody、@ResponseBody 或 HttpEntity、ResponseEntity 时,Spring MVC才会使用注册的HttpMessageConvertor对请求、相应消息进行处理。
-
当控制器处理方法使用到@RequestBody、@ResponseBody 或 HttpEntity、ResponseEntity时,Spring 首先根据请求头或响应的Accept属性选择匹配的 HttpMessageConverter,进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter,若找不到可用的 HttpMessageConverter 将报错。
-
@RequestBody、@ResponseBody不需要成对出现。
处理XML和JSON
==============
Spring MVC提供了几个处理XML和JSON格式的请求、响应消息的HttpMessageConverter:
-
MarshallingHttpMessageConverter:处理XML
-
Jaxb2RootElementHttpMessageConverter:处理XML,底层使用JAXB
-
MappingJackson2HttpMessageConverter:处理JSON格式
只要在Spring Web容器中为RequestMappingHandlerAdapter装配好相应的HttpMessageConverter,并在交互中通过请求的Accept指定MIME类型,Spring MVC就可以是服务器端的处理方法和客户端透明的通过XML或JSON格式进行通信。
复制代码
使用@RestController
=====================
@RestController已经标注了@ResponseBody和@Controller,可以直接在控制器上标注该注解,就不用在每个@RequestMapping方法上添加@ResponseBody了。
AsyncRestTemplate
=====================
Spring 4.0提供了AsyncRestTemplate用于以异步无阻塞的方式进行服务访问。
public class WebApplicationInitilalizer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
ServletRegistration.Dynamic registration = servletContext.addServlet(“web”, new DispatcherServlet());
registration.setLoadOnStartup(1);
// 此处要设置为true
registration.setAsyncSupported(true);
registration.addMapping(“/”);
}
}
@RestController
public class AsyncController {
@RequestMapping(value = “/async”, method = RequestMethod.GET)
public Callable async() {
System.out.println(“hello!”);
return new Callable() {
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(5);
return “ASYNC”;
}
};
}
}
public class Main {
public static void main(String[] args) {
AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();
ListenableFuture<ResponseEntity> future = asyncRestTemplate.getForEntity(“http://localhost:8080/async”, String.class);
System.out.println(“return”);
future.addCallback(new ListenableFutureCallback<ResponseEntity>() {
@Override
public void onFailure(Throwable ex) {
System.out.println(“Failure”);
}
@Override
public void onSuccess(ResponseEntity result) {
System.out.println(“Success”);
}
});
}
}
复制代码
处理模型数据
==========
Spring MVC提供了多种途径输出模型数据:
-
ModelAndView:当处理方法返回值类型为ModelAndView时,方法体即可通过该对象添加模型数据;
-
@ModelAttribute:在方法入参标注该注解后,入参的对象就会放到数据模型中;
-
Map和Model:如果方法入参为org.framework.ui.Model、org.framework.ui.ModelMap、java.util.Map,当处理方法返回时,Map中的数据会自动添加到模型中;
-
@SessionAttributes:将模型中的某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性。
三、处理方法的数据绑定
===============
Spring会根据请求方法签名的不同,将请求中的信息以一定方式转换并绑定到请求方法的入参中,还会进行数据转换、数据格式化及数据校验等。
数据绑定流程
==========
数据绑定
========
Spring MVC通过反射对目标签名进行分析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是DataBinder。Spring MVC主框架将ServletRequest对象及处理方法的入参对象实例传递给 DataBinder,DataBinder 首先调用装配在 Spring Web 上下文中的 ConversionService 组件进行数据类型转换、数据格式化等工作,将ServletRequest中的消息填充到入参对象中, 然后调用Validator组件对已经绑定了请求消息数据的入参对象进行数据合法性校验,最 终生成数据绑定结果BindingResult对象。BindingResult包含了已完成数据绑定的入参 对象,还包含相应的校验错误对象。Spring MVC抽取BindingResult中的入参对象及校验错误对象,将它们赋给处理方法的相应入参。
数据转换
========
类型转换模块位于org.framework.core.convert包中,同时由于历史原因,Spring还支持JDK的PropertyEditor。
ConversionService简介
=======================
ConversionService 是 Spring 类型转换体系的核心接口,它定义了以下4个方法:
-
boolean canConvert(Class sourceType, Class targetType):判断是否可以将一个Java类转换为另一个Java类。
-
Boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType):需转换的类将以成员变量的方式出现在宿主类中。TypeDescriptor不但描述了需转换类的信息,还描述了从宿主类的上下文信息,如成员变量上的注解,成员变量是否以数组、集合或Map的方式呈现等。类型转换逻辑可以利用这些信息做出 各种灵活的控制。
-
T convert(Object source, Class targetType):将原类型对象转换为目标类型对象。
-
Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType):
将对象从原类型对象转换为目标类型对象,此时往往会用到所在宿主类的上下 文信息。
第一个和第三个接口方法类似于PmpertyEditor,它们不关注类型对象所在的上下文 信息,只简单地完成两个类型对象的转换,唯一的区别在于这两个方法支持任意两个类型的转换。而第二个和第四个接口方法会参考类型对象所在宿主类的上下文信息,并利用这些信息进行类型转换。
使用ConversionService
=======================
可以利用 org.springframework.context.support.ConversionServiceFactoryBean 在 Spring 的 上下文中定义一个ConversionService。Spring将自动识别出上下文中的ConversionService, 并在Bean属性配置及Spring MVC处理方法入参绑定等场合使用它进行数据转换。该FactoryBean创建ConversionService内建了很多转换器,可完成大多数Java类型的转换工作。除了包括将String对象转换为各种基础类型的对象外,还包括String、 Number、Array、Collection、Map、Properties 及 Object 之间的转换器。可通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器:
复制代码
Spring支持的转换器
================
Spring 在 org.springframework.core.convert.converter 包中定义了3种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到ConversionServiceFactoryBean中。这3种类型的转换器接口分别为:
-
Converter<S, T>:将S类型的对象转换为T类型的对象
-
GenericConverter:根据源类对象及目标类对象所在的宿主类的上下文信息进行类型转换工作。该类还有一个子接口ConditionalGenericConverter,它添加了一个接口方法根据源类型及目标类型所在宿主类的上下文信息决定是否要进行类型转换。
-
ConverterFactory:
ConversionServiceFactoryBean 的 converters 属性可接受 Converter、ConverterFactory、 GenericConverter或ConditionalGenericConverter接口的实现类,并把这些转换器的转换逻辑统一封装到一个 ConversionService 实例对象中(GenericConversionService)。Spring 在Bean属性配置及Spring MVC请求消息绑定时将利用这个ConversionService实例完成类型转换工作。
在Spring中使用@lnitBinder 和 WebBindingInitializer装配自定义编辑器
=========================================================
Spring也支持JavaBeans的PropertyEditor。可以在控制器中使用@InitBinder添加自定义的编辑器,也可以通过 WebBindingInitializer 装配在全局范围内使用的编辑器。
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(User.class, new PropertyEditorSupport() {
@Override
public void setAsText(String text) throws IllegalArgumentException {
User user = new User();
user.setName(text);
this.setValue(user);
}
});
}
复制代码
如果希望在全局范围内使用,则可实现WebBindingInitializer接口并在该实现类中注册。
-
实现WebBindingInitializer接口并在initBinder接口方法中注册了自定义的编辑器。
-
在 Spring 上下文中通过 RequestMappingHandlerAdapter 装配自定义的Initializer。
顺序
======
对于同一个类型对象来说,如果既在ConversionService中装配了自定义转换器,又通过WebBindinglnitializer装配了自定义编辑器,同时还在控制器中通过@InitBinder装 配了自定义编辑器,那么Spring MVC将按以下优先顺序查找对应类型的编辑器:
-
查询通过@InitBinder装配的自定义编辑器。
-
查询通过ConversionService装配的自定义转换器。
-
查询通过WebBindingInitializer装配的自定义编辑器。
数据格式化
=========
Spring的转换器并不提供输入及输出信息格式化的工作,一般需要转换的源类型数据(一般是字符串)都是具有一定格式的,在不同的本地化环境中, 同一类型的数据还会相应地呈现不同的显示格式。Spring引入了一个新的格式化框架,这个框架位于org.springframework.format类包中。
最重要的 Formatter接口
====================
注解驱动格式化AnnotationFormatterFactory
=====================================
为了让注解和格式化的属性类型关联起来,Spring在Formatter所在的包中还提供了一个 AnnotationFormatterFactory 接口。
启用注解驱动格式化功能
===============
对属性对象的输入/输出进行格式化,从本质上讲依然属于“类型转换”的范畴。 Spring就是基于对象转换框架植入“格式化”功能的。Spring 在格式化模块中定义了一个实现 ConversionService 接口的 FormattingConversionService实现类,该实现类扩展了 GenericConversionService,因此它既具有类型转换功能,又具有格式化功能。
FormattingConversionService 也拥有一个对应的 FormattingConversionServiceFactoryBean 工厂类,后者用于在Spring上下文中构造一个FormattingConversionService。通过这个工厂类,既可以注册自定义的转换器,还可以注册自定义的注解驱动逻辑。由于 FormattingConversionServiceFactoryBean 在内部会自动注册 NumberFormatAnnotationFormatterFactory 和 JodaDateTimeFormatAnnotationFormatterFactory,因此装配了 FormattingConversionServiceFactoryBean 后,就可以在 Spring MVC 入参绑定及模型数据输出时使用注解驱动的格式化功能。
值得注意的是,
mvc:annotation-driven/ 标签内部默认创建的ConversionService实例就是一个 FormattingConversionServiceFactoryBean。
数据校验
========
Spring拥有自己独立的数据校验框架,同时支持JSR-303标准的校验框架。Spring 的DataBinder在进行数据绑定时,可同时调用校验框架完成数据校验工作。在Spring MVC中,则可直接通过注解驱动的方式进行数据校验。
LocalValidatorFactoryBean 既实现了 Spring 的 Validator 接口,又实现了 JSR-303 的 Validator 接口。只要在 Spring 容器中定义了一个 LocalValidatorFactoryBean,即可将其注入需要数据校验的Bean中。值得注意的是,Spring本身没有提供JSR-303的实现,所以必须将JSR-303的实现 者(如Hibernate Validator)的JAR文件放到类路径下,Spring将自动加载并装配好 JSR-303的实现者。
mvc:annotation-driven/
会默认装配一个 LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid注解,即可让Spring MVC在完成数据绑定后执行数据校验工作。
四、视图和视图解析器
==============
五、本地化
=========
Spring提供了以下4个本地化解析器。
- AcceptHeaderLocaleResolver:根据 HTTP 报文头的 Accept-Language 参数确定本 地化类型。如果没有显式定义本地化解析器,则Spring MVC默认采用 AcceptHeaderLocaleResolver。
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
分享
这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!
Spring Cloud实战
Spring Boot实战
面试题整理(性能优化+微服务+并发编程+开源框架+分布式)
想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-jU1l9lXN-1710391338207)]
[外链图片转存中…(img-hBQVwY0a-1710391338208)]
[外链图片转存中…(img-jsEPI0FB-1710391338209)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-WYo8NWAW-1710391338209)]
分享
这次面试我也做了一些总结,确实还有很多要学的东西。相关面试题也做了整理,可以分享给大家,了解一下面试真题,想进大厂的或者想跳槽的小伙伴不妨好好利用时间来学习。学习的脚步一定不能停止!
[外链图片转存中…(img-BWQhu2UD-1710391338210)]
Spring Cloud实战
[外链图片转存中…(img-bF1i87Jx-1710391338210)]
Spring Boot实战
[外链图片转存中…(img-S3OxW5sR-1710391338211)]
面试题整理(性能优化+微服务+并发编程+开源框架+分布式)