wordpress站内搜索,网站建设与维护试题及答案,重庆免费网站制作,创建网站域名#x1f4e2; 大家好#xff0c;我是 【战神刘玉栋】#xff0c;有10多年的研发经验#xff0c;致力于前后端技术栈的知识沉淀和传播。 #x1f497; #x1f33b; CSDN入驻不久#xff0c;希望大家多多支持#xff0c;后续会继续提升文章质量#xff0c;绝不滥竽充数… 大家好我是 【战神刘玉栋】有10多年的研发经验致力于前后端技术栈的知识沉淀和传播。 CSDN入驻不久希望大家多多支持后续会继续提升文章质量绝不滥竽充数欢迎多多交流。 文章目录 写在前面的话MessageConverters技术说明基础示例执行过程注意事项 源码知识回顾总结陈词 写在前面的话
前几篇博文大致了解了SpringMVC请求流程中的参数与返回值的源码分析后续的几篇博文会将流程中涉及的若干关键环节单独拿出来讲解并结合实战中的运用帮助领略SpringMVC带来的定制和扩展能力。 本篇文章先介绍一下 MessageConverters 相关内容。
相关博文 《学会 SpringMVC 系列 · 基础篇》 《学会 SpringMVC 系列 · 剖析篇上》 《学会 SpringMVC 系列 · 剖析入参处理》 《学会 SpringMVC 系列 · 剖析出参处理》 《学会 SpringMVC 系列 · 返回值处理器》 《程序猿入职必会1 · 搭建拥有数据交互的 SpringBoot 》 MessageConverters
技术说明
作用MessageConverters 主要负责将 Controller 方法的返回值转换为 HTTP 响应的内容。 工作原理当 Controller 方法返回一个对象时Spring MVC 使用消息转换器将该对象转换为 HTTP 响应体的内容。消息转换器负责将 Java 对象转换为特定的媒体类型例如 JSON、XML、HTML 等。Spring 提供了各种内置的消息转换器来支持不同的数据格式。 示例如果你的 Controller 方法返回一个对象Spring MVC 将根据请求的 Accept 头部信息和返回值类型选择适当的消息转换器将对象转换为对应的媒体类型。 基础示例
描述写了一个测试的效果针对Student类型入参做了一个特定转换操作部分代码见下方。 补充要实现自定义消息转换器入参和出参都适用就继承 AbstractHttpMessageConverter实现相应方法有点类似参数解析器。 Step1、自定义消息转换器
public class MyMessageConverter extends AbstractHttpMessageConverterStudent {/*** 新建一个我们自定义的媒体类型application/xxx-lw*/public MyMessageConverter() {super(new MediaType(application, xxx-lw, StandardCharsets.UTF_8));}/*** 支持的类型*/Overrideprotected boolean supports(Class? clazz) {return Student.class.isAssignableFrom(clazz);}/*** 入参处理器*/Overrideprotected Student readInternal(Class? extends Student clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {String str StreamUtils.copyToString(inputMessage.getBody(), StandardCharsets.UTF_8);String[] split str.split(,);String name split[0].split(#)[1];String age split[1].split(#)[1];return Student.builder().name(name).age(Integer.parseInt(age)).id(1).build();}/*** 重写writeInternal 处理如何输出数据到response。*/Overrideprotected void writeInternal(Student user, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {String outStr 获取到名称为 user.getName() 年龄 user.getAge() 岁的人;outputMessage.getBody().write(outStr.getBytes());}
}Step2、配置消息转换器
//下方两个配置方式保留一个是JSON序列化解析的逻辑和MyMessageConverter无关/*** 扩展原有方式实现*/
Override
public void extendMessageConverters(ListHttpMessageConverter? converters) {for (HttpMessageConverter? httpMessageConverter : converters) {if (MappingJackson2HttpMessageConverter.class.isAssignableFrom(httpMessageConverter.getClass())) {MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter (MappingJackson2HttpMessageConverter) httpMessageConverter;ObjectMapper objectMapper mappingJackson2HttpMessageConverter.getObjectMapper();objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializerObject() {Overridepublic void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {jsonGenerator.writeString();}});mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);}}converters.add(0, new MyMessageConverter());
}/*** 添加自定义消息转换器* BigInteger转String* NULL转空字符串*/
Override
public void configureMessageConverters(ListHttpMessageConverter? converters) {MappingJackson2HttpMessageConverter jackson2HttpMessageConverter new MappingJackson2HttpMessageConverter();ObjectMapper objectMapper SpringContextHolder.getBean(ObjectMapper.class);SimpleModule simpleModule new SimpleModule();simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);objectMapper.registerModule(simpleModule);jackson2HttpMessageConverter.setObjectMapper(objectMapper);converters.add(0, jackson2HttpMessageConverter);
}Step3、编写测试接口
/*** 测试自定义消息转换器*/
RequestMapping(/stuTest)
public Student stuTest(RequestBody Student stu) {return Student.builder().id(1).name(stu.getName()).age(stu.getAge()).email(null).build();
}Step4、启动服务PostMan测试效果信息如下
curl --location http://localhost:8083/stuTest \
--header Content-Type: application/xxx-lw \
--header Cookie: JSESSIONID2BFDA24061FF974C50BECD540FB916D1 \
--data name#张三,age#20返回结果获取到名称为张三年龄20岁的人 执行过程
1、由于添加了RequestBody直接进入 RequestResponseBodyMethodProcessor#resolveArgument 2、接着代码走到 AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters选取合适的入参转换 3、由于 MyMessageConverter 是首个转换器supports 方法也满足被触发其 read 方法实际是 MyMessageConverter#readInternal 4、接着执行核心业务方法 5、接着代码走到 AbstractMessageConverterMethodArgumentResolver#writeWithMessageConverters选取合适的出参转换 6、这里 MyMessageConverter 继续被匹配执行 write 方法实际是 MyMessageConverter#writeInternal 7、最后就是 outputMessage.getBody().flush()流程结束。 Tips这里看到read前后有beforeBodyRead和afterBodyRead也都是可以扩展的write 只有 beforeBodyWrite 方法因为写完就结束了。 【截图补充】 AbstractMessageConverterMethodArgumentResolver#readWithMessageConverters可以看到注册的自定义消息转换器已经在第一个判断符合要求后会执行。 可以看出找到符合的消息转换器直接break了代表消息转换器只会执行一个。 注意事项
如果接口入参去掉RequestBody注解再测试一下。 那现象是进入自定义的入参解析器不会进入入参转换器。但由于结果还是ResponseBody因此还是会进入出参转换器。 这个也是很好理解的 源码知识回顾
本篇为 SpringMVC 源码分析系列文章正片开始前先总结回顾一下全流程。
【一次请求的主链路节点】 DispatcherServlet#doDispatch入口方法 DispatcherServlet#getHandler根据path找到对应的HandlerExecutionChain DispatcherServlet#getHandlerAdapter根据handle找到对应的HandlerAdapter HandlerExecutionChain#applyPreHandle触发拦截器的前置逻辑 AbstractHandlerMethodAdapter#handle核心逻辑 HandlerExecutionChain#applyPostHandle触发拦截器的后置逻辑
【核心handle方法的主链路节点】 RequestMappingHandlerAdapter#handleInternal入口方法 RequestMappingHandlerAdapter#invokeHandlerMethod入口方法2 ServletInvocableHandlerMethod#invokeAndHandle入口方法3 InvocableHandlerMethod#invokeForRequest参数和实际执行的所在3.1 InvocableHandlerMethod#getMethodArgumentValues参数处理3.1.1 InvocableHandlerMethod#doInvoke实际执行3.1.2) HandlerMethodReturnValueHandlerComposite#handleReturnValue返回处理3.2)
【针对 RequestBody 和 ResponseBody 场景】 总结陈词
本篇博文继请求链路源码分析后继续介绍了MessageConverters的用法它既可以用在入参处理也可以用于返回值处理挺方便的欲知后事如何请听下回分解。 后续会逐步分享企业实际开发中的实战经验有需要交流的可以联系博主。
文章转载自: http://www.morning.jrgxx.cn.gov.cn.jrgxx.cn http://www.morning.thbnt.cn.gov.cn.thbnt.cn http://www.morning.lcwhn.cn.gov.cn.lcwhn.cn http://www.morning.gslz.com.cn.gov.cn.gslz.com.cn http://www.morning.krdmn.cn.gov.cn.krdmn.cn http://www.morning.zntf.cn.gov.cn.zntf.cn http://www.morning.wqpsf.cn.gov.cn.wqpsf.cn http://www.morning.xjkfb.cn.gov.cn.xjkfb.cn http://www.morning.mtxrq.cn.gov.cn.mtxrq.cn http://www.morning.httzf.cn.gov.cn.httzf.cn http://www.morning.ltffk.cn.gov.cn.ltffk.cn http://www.morning.dfkby.cn.gov.cn.dfkby.cn http://www.morning.hxycm.cn.gov.cn.hxycm.cn http://www.morning.xbxks.cn.gov.cn.xbxks.cn http://www.morning.rzbcz.cn.gov.cn.rzbcz.cn http://www.morning.tplht.cn.gov.cn.tplht.cn http://www.morning.qrwdg.cn.gov.cn.qrwdg.cn http://www.morning.zcwtl.cn.gov.cn.zcwtl.cn http://www.morning.c7495.cn.gov.cn.c7495.cn http://www.morning.ttdxn.cn.gov.cn.ttdxn.cn http://www.morning.kbynw.cn.gov.cn.kbynw.cn http://www.morning.qxnns.cn.gov.cn.qxnns.cn http://www.morning.fkmyq.cn.gov.cn.fkmyq.cn http://www.morning.mgtrc.cn.gov.cn.mgtrc.cn http://www.morning.xsjfk.cn.gov.cn.xsjfk.cn http://www.morning.ngcbd.cn.gov.cn.ngcbd.cn http://www.morning.ptlwt.cn.gov.cn.ptlwt.cn http://www.morning.mxhys.cn.gov.cn.mxhys.cn http://www.morning.rgmd.cn.gov.cn.rgmd.cn http://www.morning.nhrkl.cn.gov.cn.nhrkl.cn http://www.morning.yydeq.cn.gov.cn.yydeq.cn http://www.morning.rbtny.cn.gov.cn.rbtny.cn http://www.morning.kjlia.com.gov.cn.kjlia.com http://www.morning.nswcw.cn.gov.cn.nswcw.cn http://www.morning.rmfwh.cn.gov.cn.rmfwh.cn http://www.morning.qkrzn.cn.gov.cn.qkrzn.cn http://www.morning.cykqg.cn.gov.cn.cykqg.cn http://www.morning.wxccm.cn.gov.cn.wxccm.cn http://www.morning.yhdqq.cn.gov.cn.yhdqq.cn http://www.morning.qxlhj.cn.gov.cn.qxlhj.cn http://www.morning.saastob.com.gov.cn.saastob.com http://www.morning.rzmkl.cn.gov.cn.rzmkl.cn http://www.morning.fdfdz.cn.gov.cn.fdfdz.cn http://www.morning.skbkq.cn.gov.cn.skbkq.cn http://www.morning.kqfdrqb.cn.gov.cn.kqfdrqb.cn http://www.morning.rjnm.cn.gov.cn.rjnm.cn http://www.morning.hhskr.cn.gov.cn.hhskr.cn http://www.morning.ffbl.cn.gov.cn.ffbl.cn http://www.morning.nwtmy.cn.gov.cn.nwtmy.cn http://www.morning.fxwkl.cn.gov.cn.fxwkl.cn http://www.morning.kjkml.cn.gov.cn.kjkml.cn http://www.morning.qbzfp.cn.gov.cn.qbzfp.cn http://www.morning.srgwr.cn.gov.cn.srgwr.cn http://www.morning.mehrim.com.gov.cn.mehrim.com http://www.morning.kxgn.cn.gov.cn.kxgn.cn http://www.morning.yfphk.cn.gov.cn.yfphk.cn http://www.morning.sjqml.cn.gov.cn.sjqml.cn http://www.morning.hbtarq.com.gov.cn.hbtarq.com http://www.morning.ndnhf.cn.gov.cn.ndnhf.cn http://www.morning.gynkr.cn.gov.cn.gynkr.cn http://www.morning.kyjyt.cn.gov.cn.kyjyt.cn http://www.morning.rjrnx.cn.gov.cn.rjrnx.cn http://www.morning.zpfr.cn.gov.cn.zpfr.cn http://www.morning.nfzzf.cn.gov.cn.nfzzf.cn http://www.morning.ldwxj.cn.gov.cn.ldwxj.cn http://www.morning.bszmy.cn.gov.cn.bszmy.cn http://www.morning.jglqn.cn.gov.cn.jglqn.cn http://www.morning.pgfkl.cn.gov.cn.pgfkl.cn http://www.morning.xbwqg.cn.gov.cn.xbwqg.cn http://www.morning.ychrn.cn.gov.cn.ychrn.cn http://www.morning.jcffp.cn.gov.cn.jcffp.cn http://www.morning.qhnmj.cn.gov.cn.qhnmj.cn http://www.morning.rmqlf.cn.gov.cn.rmqlf.cn http://www.morning.qxdrw.cn.gov.cn.qxdrw.cn http://www.morning.dtnjr.cn.gov.cn.dtnjr.cn http://www.morning.kfsfm.cn.gov.cn.kfsfm.cn http://www.morning.ypmqy.cn.gov.cn.ypmqy.cn http://www.morning.knpmj.cn.gov.cn.knpmj.cn http://www.morning.prsxj.cn.gov.cn.prsxj.cn http://www.morning.nhpmn.cn.gov.cn.nhpmn.cn