關(guān)于@ResponseBody 默認(rèn)輸出的誤區(qū)的解答
背景
@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)文章希望大家以后多多支持腳本之家!
- 詳解SpringBoot中添加@ResponseBody注解會(huì)發(fā)生什么
- 詳解SpringBoot定制@ResponseBody注解返回的Json格式
- SpringBoot使用@ResponseBody返回圖片的實(shí)現(xiàn)
- 解決使用@ResponseBody后返回500錯(cuò)誤的問(wèn)題
- spring boot @ResponseBody轉(zhuǎn)換JSON 時(shí) Date 類型處理方法【兩種方法】
- Springmvc 4.x利用@ResponseBody返回Json數(shù)據(jù)的方法
- spring+mybatis 通過(guò)@ResponseBody返回結(jié)果中文亂碼的解決方法
- springMvc注解之@ResponseBody和@RequestBody詳解
- SpringMVC中解決@ResponseBody注解返回中文亂碼問(wèn)題
- @ResponseBody 和 @RequestBody 注解的區(qū)別
- SpringMVC注解之@ResponseBody注解原理
相關(guān)文章
java代碼實(shí)現(xiàn)C盤(pán)文件統(tǒng)計(jì)工具
今天周末,給大家分享基于java代碼實(shí)現(xiàn)C盤(pán)文件統(tǒng)計(jì)工具,在這小編使用的版本是Maven-3.9.9,jdk1.8,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2021-07-07java serialVersionUID解決序列化類版本不一致問(wèn)題面試精講
這篇文章主要為大家介紹了serialVersionUID解決序列化類版本不一致問(wèn)題的面試精講,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10Java實(shí)現(xiàn)多個(gè)sheet頁(yè)數(shù)據(jù)導(dǎo)出功能
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)多個(gè)sheet頁(yè)數(shù)據(jù)導(dǎo)出功能的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03詳解使用Maven構(gòu)建多模塊項(xiàng)目(圖文)
這篇文章主要介紹了詳解使用Maven構(gòu)建多模塊項(xiàng)目(圖文),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-09-09Layui前后臺(tái)交互數(shù)據(jù)獲取java實(shí)例
下面小編就為大家分享一篇Layui前后臺(tái)交互數(shù)據(jù)獲取java實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01Java實(shí)現(xiàn)訂單超時(shí)未支付自動(dòng)取消的8種方法總結(jié)
這篇文章主要為大家介紹了Java實(shí)現(xiàn)訂單超時(shí)未支付自動(dòng)取消功能的8種不同方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-08-08Java實(shí)現(xiàn)學(xué)生管理系統(tǒng)(控制臺(tái)版本)
這篇文章主要為大家詳細(xì)介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)控制臺(tái)版本的學(xué)生管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06Java中實(shí)現(xiàn)String.padLeft和String.padRight的示例
本篇文章主要介紹了Java中實(shí)現(xiàn)String.padLeft和String.padRight,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09