成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

基于SpringBoot自定義接口響應消息格式及原理解析

開發 前端
當后臺在處理該請求時會認為你能接收任意類型的數據格式也就是MediaType=*/*,緊接著會獲取當前所有的HttpMessageConverter支持的MediaType,然后遍歷所有的MediaType。

環境:Springboot3.0.5

消息格式轉換原理

在默認情況下,RestController接口返回的數據格式是json,如下接口:

@RestController
@RequestMapping("/rmf")
public class ResponseMessageFormatController {


  @GetMapping("/index")
  public Users index() {
    return new Users(1, "張颯", 66, "男") ;
  }
  
}

接口返回

圖片

接口默認返回了json數據格式

通過Postman,我這里是沒有在Header中添加Accept。當后臺在處理該請求時會認為你能接收任意類型的數據格式也就是MediaType=*/*,緊接著會獲取當前所有的HttpMessageConverter支持的MediaType,然后遍歷所有的MediaType,找到第一個類型中只要不包含'*'的MediaType就直接返回,默認情況下application/json排在第一個,所以最終確定返回客戶端的數據格式將會是application/json,最后再遍歷所有的HttpMessageConverter找出支持applicatioin/json類型的HttpMessageConverter,最終確定了MappingJackson2HttpMessageConverter直接進行客戶端的輸出。

核心源碼:

public abstract class AbstractMessageConverterMethodProcessor {
  protected <T> void writeWithMessageConverters(...) {
    List<MediaType> acceptableTypes;
    try {
      // 獲取請求header中的Accept,如果請求中沒有,則返回 */* 接受任意類型
      acceptableTypes = getAcceptableMediaTypes(request);
    }
    // 獲取當前容器中所有的HttpMessageConverter支持的MediaType
    List<MediaType> producibleTypes = getProducibleMediaTypes(request, valueType, targetType);
    
    List<MediaType> compatibleMediaTypes = new ArrayList<>();
    // 確定具體輸出的應該是那種消息格式,
    determineCompatibleMediaTypes(acceptableTypes, producibleTypes, compatibleMediaTypes);
    // 遍歷
    for (MediaType mediaType : compatibleMediaTypes) {
      // 判斷當前的MediaType的類型[type] 和 子類型 [subtype] 中分別不是 * 和 *+
      // 就符合條件,找到第一個直接返回,這就確定了將會給客戶端返回的消息格式
      if (mediaType.isConcrete()) {
        selectedMediaType = mediaType;
        break;
      } else if (mediaType.isPresentIn(ALL_APPLICATION_MEDIA_TYPES)) {
        selectedMediaType = MediaType.APPLICATION_OCTET_STREAM;
        break;
      }
    }
    if (selectedMediaType != null) {
      selectedMediaType = selectedMediaType.removeQualityValue();
      // 遍歷所有的HttpMessageConverter,是否有能支持上面確定的selectedMediaType
      for (HttpMessageConverter<?> converter : this.messageConverters) {
        GenericHttpMessageConverter genericConverter =(converter instanceof GenericHttpMessageConverter ghmc ? ghmc : null);
        if (genericConverter != null ? ((GenericHttpMessageConverter) converter).canWrite(targetType, valueType, selectedMediaType) : converter.canWrite(valueType, selectedMediaType)) {
          body = getAdvice().beforeBodyWrite(body, returnType, selectedMediaType, (Class<? extends HttpMessageConverter<?>>) converter.getClass(), inputMessage, outputMessage);
          // 輸出結果
          ((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage);
        }
      }
    }
  }
}

以上是關于消息處理的部分源碼分析。

返回XML格式

如果需要返回xml格式的數據,我們只需引入下面依賴即可。

引入依賴:

<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

postman進行測試

圖片

正確的返回了xml格式

為什么引入上面的依賴后就可以直接通過設置Accept為application/xml就可以返回xml格式呢?

原理:

// 在這導入的JacksonHttpMessageConvertersConfiguration類中進行了配置
@Import({ JacksonHttpMessageConvertersConfiguration.class })
public class HttpMessageConvertersAutoConfiguration {
}


@Configuration(proxyBeanMethods = false)
class JacksonHttpMessageConvertersConfiguration {
  @Configuration(proxyBeanMethods = false)
  // 當前的類路徑下有XmlMapper類,該類就在上面引入的包中
  @ConditionalOnClass(XmlMapper.class)
  @ConditionalOnBean(Jackson2ObjectMapperBuilder.class)
  protected static class MappingJackson2XmlHttpMessageConverterConfiguration {
    @Bean
    @ConditionalOnMissingBean
    public MappingJackson2XmlHttpMessageConverter mappingJackson2XmlHttpMessageConverter(Jackson2ObjectMapperBuilder builder) {
      return new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build());
    }
  }  
}

當當前的類路徑下有XmlMapper就會自動的創建處理XML格式的MappingJackson2XmlHttpMessageConverter

自定義消息格式

如果客戶端要求接收的數據格式是yaml格式,這時候就需要自定義HttpMessageConverter

引入依賴:

<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-yaml</artifactId>
</dependency>

自定義HttpMessageConverter:

@Component
public class YamlHttpMessageConverter extends AbstractHttpMessageConverter<Object> {


  public YamlHttpMessageConverter() {
    super(new MediaType("application", "yaml")) ;
  }
  
  @Override
  protected boolean supports(Class<?> clazz) {
    return true ;
  }


  @Override
  protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage)
      throws IOException, HttpMessageNotReadableException {
    return null ;
  }


  @Override
  protected void writeInternal(Object t, HttpOutputMessage outputMessage)
      throws IOException, HttpMessageNotWritableException {
    try (OutputStream os = outputMessage.getBody()) {
      YAMLFactory factory = new YAMLFactory();
      // 該配置作用就是:去掉開頭的三個 '---'
      factory.configure(Feature.WRITE_DOC_START_MARKER, false) ;
      ObjectMapper mapper = new ObjectMapper(factory) ;
      os.write(mapper.writeValueAsString(t).getBytes(StandardCharsets.UTF_8)) ;
    }
  }


}

測試

圖片

正確的返回了yaml格式

責任編輯:武曉燕 來源: 實戰案例錦集
相關推薦

2023-08-26 19:04:40

配置write轉換器

2015-02-12 15:33:43

微信SDK

2021-03-16 10:39:29

SpringBoot參數解析器

2022-07-11 10:37:41

MapPart集合

2015-02-12 15:38:26

微信SDK

2022-11-01 11:15:56

接口策略模式

2024-02-22 08:06:45

JSON策略解析器

2022-06-30 14:02:07

鴻蒙開發消息彈窗組件

2022-03-09 23:02:30

Java編程處理模型

2023-11-16 09:01:37

Hadoop數據庫

2023-10-11 07:57:23

springboot微服務

2023-01-03 09:35:34

SpringbootStarter

2011-07-05 18:51:51

QT 控件 鼠標

2021-07-11 17:17:08

.NET 授權自定義

2023-02-27 09:38:36

Springbootstarter

2011-06-20 16:03:03

Qt 控件 鼠標

2014-12-10 10:37:45

Android自定義布局

2021-08-09 10:31:33

自定義授權響應

2021-05-14 06:15:48

SpringAware接口

2022-05-11 10:45:21

SpringMVC框架Map
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲乱码一区二区三区在线观看 | 国产精品一区二区三区久久 | 日日天天 | 日韩精品久久一区二区三区 | 久久精品免费观看 | 国产成人一区二区 | 亚洲欧美一区二区在线观看 | 久久国产精品99久久久久久丝袜 | 成人99 | 五月婷六月丁香 | 欧美视频免费在线 | 一级做受毛片免费大片 | 欧美99久久精品乱码影视 | xx视频在线 | 亚洲美女在线一区 | 日韩精品免费在线 | 久久久成人免费一区二区 | 色免费视频 | 日韩欧美在线一区 | 蜜桃日韩 | 看片国产 | 黄色中文字幕 | 在线国产99 | 91xxx在线观看 | 成年人在线播放 | 日韩在线欧美 | 日韩久久成人 | 久久精品国产清自在天天线 | 国产一区二区不卡 | 欧洲在线视频 | 欧美日韩视频在线播放 | 国产视频福利一区 | 国产成人免费视频 | www.97国产| 欧美 日韩 国产 一区 | 欧美在线亚洲 | 日日摸日日添日日躁av | 国产黄色免费网站 | 日本成人毛片 | 亚洲欧美一区二区三区1000 | 日韩欧美一二三区 |