最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

背景

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

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

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

正確答案

我們先來公布正確的答案。

@ResponseBody 的輸出格式,默認情況取決于客戶端的 Accept 請求頭。

源碼剖析

RequestResponseBodyMethodProcessor

public class RequestResponseBodyMethodProcessor {
// 處理 ResponseBody 標注的方法
@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();
 // 獲取請求頭中的目標資源類型
 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;
  }
 }
}

為什么我要去研究這個問題

當升級至 spring cloud alibaba 2.2.1 時, sentinel 模塊 引入以下依賴

當依賴中出現(xiàn) dataformat jar 時候, RestTemplate ,會在默認 Accept 請求頭增加

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");
}

當我們使用 RestTemplate 調(diào)用接口時候,若不指定 Accept 會返回 XML ,導致不能平滑升級

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

相關(guān)文章

最新評論

龙陵县| 淳化县| 霍城县| 安达市| 突泉县| 嘉义市| 师宗县| 凤凰县| 玛曲县| 固镇县| 长武县| 同仁县| 上杭县| 佛学| 金湖县| 牡丹江市| 柞水县| 兰坪| 正安县| 北京市| 绵阳市| 衢州市| 沁源县| 昌黎县| 莆田市| 策勒县| 漳浦县| 噶尔县| 吴堡县| 云龙县| 大渡口区| 女性| 长海县| 涿州市| 雷波县| 聊城市| 南华县| 安吉县| 通城县| 乌拉特后旗| 宁南县|