日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

SpringBoot自定义MessageConverter

發布時間:2025/3/15 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SpringBoot自定义MessageConverter 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
  • 之前的文章我們知道,如果使用@ResponseBody,我們在發請求的時候,對請求頭進行設置,可以獲取到我們想要的返回數據格式,例如json數據,或者XML數據(當然這些都要導入對應的依賴,也要開啟基于請求參數的內容協商功能),這是服務器與瀏覽器進行內容協商后的結果。那么,如果我們想自定義返回的數據類型,如何設置?
    例如引入xml依賴:
  • <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId> </dependency>

    開啟協商功能:

    spring:contentnegotiation:favor-parameter: true #開啟請求參數內容協商模式

    進行不同返回類型測試:

  • MessageConverter原理
    ? 1、判斷當前響應頭中是否已經有確定的媒體類型。MediaType
    ? 2、獲取客戶端(PostMan、瀏覽器)支持接收的內容類型。(獲取客戶端Accept請求頭字段)【application/xml】
  • ? contentNegotiationManager 內容協商管理器 默認使用基于請求頭的策略

    ? HeaderContentNegotiationStrategy 確定客戶端可以接收的內容類型

    ? 3、遍歷循環所有當前系統的 MessageConverter,看誰支持操作這個對象(Person)
    ? 4、找到支持操作Person的converter,把converter支持的媒體類型統計出來。
    ? 5、客戶端需要【application/xml】。服務端能力【10種、json、xml】

    ? 6、進行內容協商的最佳匹配媒體類型
    ? 7、用支持將對象轉為最佳匹配媒體類型 的converter。調用它進行轉化 。

    上圖導入了jackson處理xml的包,xml的converter就會自動進來

    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()));}
  • 自定義 MessageConverter
    在開發過程中,我們可能對返回的數據有自己的要求

    實現多協議數據兼容。json、xml、x-guigu
    • @ResponseBody 響應數據出去 調用 RequestResponseBodyMethodProcessor 處理
    • Processor 處理方法返回值。通過 MessageConverter 處理
    • 所有 MessageConverter 合起來可以支持各種媒體類型數據的操作(讀、寫)
    • 內容協商找到最終的 messageConverter;
      SpringMVC的什么功能。一個入口給容器中添加一個 WebMvcConfigurer
    @Beanpublic WebMvcConfigurer webMvcConfigurer(){return new WebMvcConfigurer() {@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {}}}


    注意:如果使用的是configureMessageConverter,那么是覆蓋了默認的所有messageconverter
    自定義converter

    public class GuiguMessageConverter implements HttpMessageConverter<Person> {@Override//如果這里設置為true,那就可以讀@RequestBody的值public boolean canRead(Class<?> clazz, MediaType mediaType) {return false;}@Overridepublic boolean canWrite(Class<?> clazz, MediaType mediaType) {return clazz.isAssignableFrom(Person.class);}/*** 服務器要統計所有MessageConverter都能寫出哪些內容類型** application/x-guigu* @return*/@Overridepublic List<MediaType> getSupportedMediaTypes() {return MediaType.parseMediaTypes("application/x-guigu");}@Overridepublic Person read(Class<? extends Person> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {return null;}@Overridepublic void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {//自定義協議數據的寫出String data = person.getUserName()+";"+person.getAge()+";"+person.getBirth();//寫出去OutputStream body = outputMessage.getBody();body.write(data.getBytes());} }

    將自定義的converter添加進去:

    @Beanpublic WebMvcConfigurer webMvcConfigurer(){return new WebMvcConfigurer() {@Overridepublic void extendMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new GuiguMessageConverter());}}}
  • 以參數的形式進行內容協商(即將要返回的數據類型,加載url中)
    上面的方式是以請求頭的形式,進行內容協商的,如果以參數的形式,會方便一些。

    我們可以看到,內容協商功能是由contentNegotiationManager實現的,在它下面有兩種策略:
    • ParameterContentNegotiationStrategy(基于請求參數)
    • HeadContentnegotiationStrategy(基于請求頭)

    而請求參數的策略,默認只支持xml,json兩種方式,那么看到這里,思路自然也就有了,那就是自定義內容協商管理器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"));//指定支持解析哪些參數對應的哪些媒體類型ParameterContentNegotiationStrategy parameterStrategy = new ParameterContentNegotiationStrategy(mediaTypes); // parameterStrategy.setParameterName("ff");HeaderContentNegotiationStrategy headeStrategy = new HeaderContentNegotiationStrategy();configurer.strategies(Arrays.asList(parameterStrategy,headeStrategy));}

    效果:

    但是在這里要注意:如果我們自定義了參數策略,他的頭策略反而會失效,這時就需要debug了。。。。在spingboot中,有可能我們添加的自定義的功能會覆蓋默認很多功能,導致一些默認的功能失效,這里的解決方法是在configureContentNegotiation中也添加自定義頭策略.

    總結

    以上是生活随笔為你收集整理的SpringBoot自定义MessageConverter的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。