亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

SpringBoot自定義MessageConvert詳細(xì)講解

 更新時(shí)間:2023年01月11日 15:38:37   作者:zoeil  
正在學(xué)習(xí)SpringBoot,在自定義MessageConverter時(shí)發(fā)現(xiàn):為同一個(gè)返回值類型配置多個(gè)MessageConverter時(shí),可能會(huì)發(fā)生響應(yīng)數(shù)據(jù)格式錯(cuò)誤,或406異常(客戶端無法接收相應(yīng)數(shù)據(jù))。在此記錄一下解決問題以及追蹤源碼的過程

前言

對(duì)于頁面攜帶的請(qǐng)求頭中的AcceptSpringBoot有對(duì)應(yīng)的10種MessageConvert可以支持寫出對(duì)應(yīng)的媒體類型,比如application/xml、application/json……

我們還可以通過向容器放入一個(gè)WebMvcConfigurer

實(shí)現(xiàn)定制化SpingMVC,自定義一個(gè)MessageConvert處理特殊的協(xié)議比如application/x-person

實(shí)現(xiàn)多協(xié)議數(shù)據(jù)兼容。json、xml、x-person

原理

0、@ResponseBody 響應(yīng)數(shù)據(jù)出去 調(diào)用 RequestResponseBodyMethodProcessor 處理

1、Processor 處理方法返回值。通過 MessageConverter 處理

2、所有 MessageConverter 合起來可以支持各種媒體類型數(shù)據(jù)的操作(讀、寫)

3、內(nèi)容協(xié)商找到最終的 messageConverter;

實(shí)現(xiàn)

/* 條件
 *
 * 1、瀏覽器發(fā)請(qǐng)求直接 返回xml   [application/xml]   jacksonXmlConverter
 * 2、如果是ajax請(qǐng)求 返回json   [application/json]  jacksonJsonConverter
 * 3、如果是app發(fā)請(qǐng)求,返回自定義協(xié)議數(shù)據(jù) [application/x-person]   xxxxConverter
 *
 * 步驟:
 *  1、添加自定義的MessageConverter進(jìn)系統(tǒng)底層
 *  2、系統(tǒng)底層就會(huì)統(tǒng)計(jì)出所有MessageConverter能操作哪些類型
 *  3、客戶端內(nèi)容協(xié)商 [person--->person]
 */

person類

@Data
public class Person {
    public String username;
    public Integer age;
    public Pet pet;
}

pet類

@Data
public class Pet {
    public String name;
    public Integer age;
}
PersonMessageConvert
/*
 * 自定義的Convert
 */
public class PersonMessageConvert implements HttpMessageConverter<Person> {
    @Override
    public boolean canRead(Class<?> clazz, MediaType mediaType) {
        return false;
    }
    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return clazz.isAssignableFrom(Person.class);
    }
    /*
     * @Description 服務(wù)器需要統(tǒng)計(jì)所有MessageConvert都能寫出哪些類型,我們這里也要自定義
     * @Param
     **/
    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return MediaType.parseMediaTypes("application/x-person");
    }
    @Override
    public Person read(Class<? extends Person> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    }
    @Override
    public void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
        //自定義協(xié)會(huì)數(shù)據(jù)的寫出
        String data = person.getUsername() + ";" + person.getAge() + ";" +person.getPet() + ";";
        //寫出去
        OutputStream body = outputMessage.getBody();
        body.write(data.getBytes());
    }
}

方法

    @ResponseBody
    @GetMapping("/test/person")
    public Person getPeroson() {
        Person person = new Person();
        person.setUsername("張三");
        person.setAge(18);
        person.setPet(new Pet());
        return person;
    }

WebMvcConfigurer

    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
                converters.add(new PersonMessageConvert());
            }
       }
    }

測(cè)試

拓展

如何實(shí)現(xiàn)訪問路徑攜帶format參數(shù)指明協(xié)商協(xié)議

比如:http://localhost:8080/test/person?format=x-person

記得先開啟基于參數(shù)的內(nèi)容協(xié)商

spring:
  mvc:
    contentnegotiation:
      favor-parameter: true

@Bean
    public WebMvcConfigurer webMvcConfigurer() {
        return new WebMvcConfigurer() {
            /*
             * 自定義內(nèi)容協(xié)商策略
             */
            @Override
            public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
                Map<String, MediaType> mediaTypeMap = new HashMap<>();
                mediaTypeMap.put("json", MediaType.APPLICATION_JSON);
                mediaTypeMap.put("xml", MediaType.APPLICATION_XML);
                mediaTypeMap.put("x-person",MediaType.parseMediaType("application/x-person"));
                //指定支持解析那些參數(shù)的媒體類型
                ParameterContentNegotiationStrategy parametertrategy = new ParameterContentNegotiationStrategy(mediaTypeMap);
                HeaderContentNegotiationStrategy headerStrategy = new HeaderContentNegotiationStrategy();
                configurer.strategies(Arrays.asList(parametertrategy, headerStrategy));
            }
            @Override
            public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
                converters.add(new PersonMessageConvert());
            }
        };
    }

測(cè)試

注意:有可能我們添加的自定義的功能會(huì)覆蓋默認(rèn)很多功能,導(dǎo)致一些默認(rèn)的功能失效。比如上面的ContentNegotiationConfigurer 就會(huì)覆蓋原來的默認(rèn)ContentNegotiationConfigurer

到此這篇關(guān)于SpringBoot自定義MessageConvert詳細(xì)講解的文章就介紹到這了,更多相關(guān)SpringBoot MessageConvert內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java this關(guān)鍵字的使用詳解

    Java this關(guān)鍵字的使用詳解

    this 關(guān)鍵字是 Java 常用的關(guān)鍵字,可用于任何實(shí)例方法內(nèi)指向當(dāng)前對(duì)象,也可指向?qū)ζ湔{(diào)用當(dāng)前方法的對(duì)象,或者在需要當(dāng)前類型對(duì)象引用時(shí)使用
    2021-11-11
  • 修改及反編譯可運(yùn)行Jar包實(shí)現(xiàn)過程詳解

    修改及反編譯可運(yùn)行Jar包實(shí)現(xiàn)過程詳解

    這篇文章主要介紹了如何修改及反編譯可運(yùn)行Jar包,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • 詳解SpringBoot中添加@ResponseBody注解會(huì)發(fā)生什么

    詳解SpringBoot中添加@ResponseBody注解會(huì)發(fā)生什么

    這篇文章主要介紹了詳解SpringBoot中添加@ResponseBody注解會(huì)發(fā)生什么,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Skywalking改成適配阿里云等帶Http?Basic的Elasticsearch服務(wù)

    Skywalking改成適配阿里云等帶Http?Basic的Elasticsearch服務(wù)

    這篇文章主要介紹了改造Skywalking支持阿里云等帶Http?Basic的Elasticsearch服務(wù)
    2022-02-02
  • Java設(shè)計(jì)模式之java命令模式詳解

    Java設(shè)計(jì)模式之java命令模式詳解

    這篇文章主要介紹了Java設(shè)計(jì)模式編程中命令模式的使用,在一些處理請(qǐng)求響應(yīng)的場(chǎng)合經(jīng)??梢杂玫矫钅J降木幊趟悸?需要的朋友可以參考下
    2021-09-09
  • Java同步鎖Synchronized底層源碼和原理剖析(推薦)

    Java同步鎖Synchronized底層源碼和原理剖析(推薦)

    這篇文章主要介紹了Java同步鎖Synchronized底層源碼和原理剖析,釋放后,進(jìn)入減減操作、直到為0然后喚醒隊(duì)列,讓他們?nèi)帄Z鎖,循環(huán)前面步驟,對(duì)Java同步鎖Synchronized相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-05-05
  • SpringBoot的@Value給靜態(tài)變量注入application.properties屬性值

    SpringBoot的@Value給靜態(tài)變量注入application.properties屬性值

    這篇文章主要介紹了SpringBoot的@Value給靜態(tài)變量注入application.properties屬性值,Spring是一個(gè)開源的框架,主要是用來簡化開發(fā)流程,通過IOC,依賴注入(DI)和面向接口實(shí)現(xiàn)松耦合,需要的朋友可以參考下
    2023-05-05
  • 字節(jié)二面SpringBoot可以同時(shí)處理多少請(qǐng)求

    字節(jié)二面SpringBoot可以同時(shí)處理多少請(qǐng)求

    這篇文章主要為大家介紹了字節(jié)二面之SpringBoot可以同時(shí)處理多少請(qǐng)求面試分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • Java編程接口調(diào)用的作用及代碼分享

    Java編程接口調(diào)用的作用及代碼分享

    這篇文章主要介紹了Java編程接口調(diào)用的作用及代碼分享,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • java之Object類用法實(shí)例

    java之Object類用法實(shí)例

    這篇文章主要介紹了java之Object類用法實(shí)例,是Java程序設(shè)計(jì)中比較重要的概念,以實(shí)例的形式對(duì)其定義及用法做了較為深入的講解,需要的朋友可以參考下
    2014-10-10

最新評(píng)論