SpringBoot自定义MessageConverter
例如引入xml依賴:
開啟協(xié)商功能:
spring:contentnegotiation:favor-parameter: true #開啟請(qǐng)求參數(shù)內(nèi)容協(xié)商模式進(jìn)行不同返回類型測(cè)試:
? 1、判斷當(dāng)前響應(yīng)頭中是否已經(jīng)有確定的媒體類型。MediaType
? 2、獲取客戶端(PostMan、瀏覽器)支持接收的內(nèi)容類型。(獲取客戶端Accept請(qǐng)求頭字段)【application/xml】
? contentNegotiationManager 內(nèi)容協(xié)商管理器 默認(rèn)使用基于請(qǐng)求頭的策略
? HeaderContentNegotiationStrategy 確定客戶端可以接收的內(nèi)容類型
? 3、遍歷循環(huán)所有當(dāng)前系統(tǒng)的 MessageConverter,看誰(shuí)支持操作這個(gè)對(duì)象(Person)
? 4、找到支持操作Person的converter,把converter支持的媒體類型統(tǒng)計(jì)出來(lái)。
? 5、客戶端需要【application/xml】。服務(wù)端能力【10種、json、xml】
? 6、進(jìn)行內(nèi)容協(xié)商的最佳匹配媒體類型
? 7、用支持將對(duì)象轉(zhuǎn)為最佳匹配媒體類型 的converter。調(diào)用它進(jìn)行轉(zhuǎn)化 。
上圖導(dǎo)入了jackson處理xml的包,xml的converter就會(huì)自動(dòng)進(jìn)來(lái)
WebMvcConfigurationSupport jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader);if (jackson2XmlPresent) {Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();if (this.applicationContext != null) {builder.applicationContext(this.applicationContext);}messageConverters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));}在開發(fā)過(guò)程中,我們可能對(duì)返回的數(shù)據(jù)有自己的要求
實(shí)現(xiàn)多協(xié)議數(shù)據(jù)兼容。json、xml、x-guigu
- @ResponseBody 響應(yīng)數(shù)據(jù)出去 調(diào)用 RequestResponseBodyMethodProcessor 處理
- Processor 處理方法返回值。通過(guò) MessageConverter 處理
- 所有 MessageConverter 合起來(lái)可以支持各種媒體類型數(shù)據(jù)的操作(讀、寫)
- 內(nèi)容協(xié)商找到最終的 messageConverter;
SpringMVC的什么功能。一個(gè)入口給容器中添加一個(gè) WebMvcConfigurer
注意:如果使用的是configureMessageConverter,那么是覆蓋了默認(rèn)的所有messageconverter
自定義converter
將自定義的converter添加進(jìn)去:
@Beanpublic WebMvcConfigurer webMvcConfigurer(){return new WebMvcConfigurer() {@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new GuiguMessageConverter());}}}上面的方式是以請(qǐng)求頭的形式,進(jìn)行內(nèi)容協(xié)商的,如果以參數(shù)的形式,會(huì)方便一些。
我們可以看到,內(nèi)容協(xié)商功能是由contentNegotiationManager實(shí)現(xiàn)的,在它下面有兩種策略:
- ParameterContentNegotiationStrategy(基于請(qǐng)求參數(shù))
- HeadContentnegotiationStrategy(基于請(qǐng)求頭)
而請(qǐng)求參數(shù)的策略,默認(rèn)只支持xml,json兩種方式,那么看到這里,思路自然也就有了,那就是自定義內(nèi)容協(xié)商管理器contentNegotiationManager。
@Overridepublic void configureContentNegotiation(ContentNegotiationConfigurer configurer) {//Map<String, MediaType> mediaTypesMap<String, MediaType> mediaTypes = new HashMap<>();mediaTypes.put("json",MediaType.APPLICATION_JSON);mediaTypes.put("xml",MediaType.APPLICATION_XML);mediaTypes.put("gg",MediaType.parseMediaType("application/x-guigu"));//指定支持解析哪些參數(shù)對(duì)應(yīng)的哪些媒體類型ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes); // parameterStrategy.setParameterName("ff");HeaderContentNegotiationStrategy headeStrategy = new HeaderContentNegotiationStrategy();configurer.strategies(Arrays.asList(parameterStrategy,headeStrategy));}效果:
但是在這里要注意:如果我們自定義了參數(shù)策略,他的頭策略反而會(huì)失效,這時(shí)就需要debug了。。。。在spingboot中,有可能我們添加的自定義的功能會(huì)覆蓋默認(rèn)很多功能,導(dǎo)致一些默認(rèn)的功能失效,這里的解決方法是在configureContentNegotiation中也添加自定義頭策略.
總結(jié)
以上是生活随笔為你收集整理的SpringBoot自定义MessageConverter的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2021年KOL市场研究报告
- 下一篇: SpringBoot拦截器与过滤器