欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于@ResponseBody 默認(rèn)輸出的誤區(qū)的解答

 更新時(shí)間:2020年04月14日 11:19:00   作者:冷冷gg  
這篇文章主要介紹了關(guān)于@ResponseBody 默認(rèn)輸出的誤區(qū)的解答,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

背景

@ResponseBody 默認(rèn)情況返回的數(shù)據(jù)格式是什么?所謂默認(rèn)情況 后臺(tái)接口不指定 produces MediaType

@Controller
public class DemoController {
 @ResponseBody
 @GetMapping(value = "/demo")
 public DemoVO demo() {
  return new DemoVO("lengleng", "123456");
 }
}

使用百度搜索 @ResponseBody 排名第一的答案, @ResponseBody 的作用其實(shí)是將 java 對(duì)象轉(zhuǎn)為 json 格式的數(shù)據(jù)。

正確答案

我們先來(lái)公布正確的答案。

@ResponseBody 的輸出格式,默認(rèn)情況取決于客戶端的 Accept 請(qǐng)求頭。

源碼剖析

RequestResponseBodyMethodProcessor

public class RequestResponseBodyMethodProcessor {
// 處理 ResponseBody 標(biāo)注的方法
@Override
public boolean supportsReturnType(MethodParameter returnType) {
  return (AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) ||
    returnType.hasMethodAnnotation(ResponseBody.class));
 }
// 處理返回值
@Override
public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType,
               ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {
  mavContainer.setRequestHandled(true);
  ServletServerHttpRequest inputMessage = createInputMessage(webRequest);
  ServletServerHttpResponse outputMessage = createOutputMessage(webRequest);
  // 處理返回值
  writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
 }
}

writeWithMessageConverters

protected <T> void writeWithMessageConverters(@Nullable T value, MethodParameter returnType,
            ServletServerHttpRequest inputMessage, ServletServerHttpResponse outputMessage) {
 HttpServletRequest request = inputMessage.getServletRequest();
 // 獲取請(qǐng)求頭中的目標(biāo)資源類型
 List<MediaType> acceptableTypes = getAcceptableMediaTypes(request);
 // 獲取接口指定支持的資源類型
 List<MediaType> producibleTypes = getProducibleMediaTypes(request, valueType, targetType);
 // 獲取能夠輸出資源類型
 List<MediaType> mediaTypesToUse = new ArrayList<>();
 for (MediaType requestedType : acceptableTypes) {
  for (MediaType producibleType : producibleTypes) {
   if (requestedType.isCompatibleWith(producibleType)) {
    mediaTypesToUse.add(getMostSpecificMediaType(requestedType, producibleType));
   }
  }
 }
 /// 排序
 MediaType.sortBySpecificityAndQuality(mediaTypesToUse);

 for (MediaType mediaType : mediaTypesToUse) {
  // 判斷資源類型是否是具體的類型,而不是帶通配符 * 這種
  if (mediaType.isConcrete()) {
   selectedMediaType = mediaType;
   break;
  }
  else if (mediaType.isPresentIn(ALL_APPLICATION_MEDIA_TYPES)) {
   selectedMediaType = MediaType.APPLICATION_OCTET_STREAM;
   break;
  }
 }

 selectedMediaType = selectedMediaType.removeQualityValue();
 // 查找支持選中資源類型的 HttpMessageConverter,輸出body
 for (HttpMessageConverter<?> converter : this.messageConverters) {
  GenericHttpMessageConverter genericConverter = (converter instanceof GenericHttpMessageConverter ?
   (GenericHttpMessageConverter<?>) converter : 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);
   return;
  }
 }
}

為什么我要去研究這個(gè)問(wèn)題

當(dāng)升級(jí)至 spring cloud alibaba 2.2.1 時(shí), sentinel 模塊 引入以下依賴

當(dāng)依賴中出現(xiàn) dataformat jar 時(shí)候, RestTemplate ,會(huì)在默認(rèn) Accept 請(qǐng)求頭增加

application/xml | text/xml | application/*+xml

public MappingJackson2XmlHttpMessageConverter(ObjectMapper objectMapper) {
 super(objectMapper, new MediaType("application", "xml", StandardCharsets.UTF_8),
   new MediaType("text", "xml", StandardCharsets.UTF_8),
   new MediaType("application", "*+xml", StandardCharsets.UTF_8));
 Assert.isInstanceOf(XmlMapper.class, objectMapper, "XmlMapper required");
}

當(dāng)我們使用 RestTemplate 調(diào)用接口時(shí)候,若不指定 Accept 會(huì)返回 XML ,導(dǎo)致不能平滑升級(jí)

到此這篇關(guān)于關(guān)于@ResponseBody 默認(rèn)輸出的誤區(qū)的解答的文章就介紹到這了,更多相關(guān)@ResponseBody 默認(rèn)輸出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論