溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

發(fā)布時(shí)間:2021-12-16 10:21:23 來源:億速云 閱讀:144 作者:小新 欄目:編程語言

小編給大家分享一下SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

現(xiàn)象

本文使用的demo基于maven,是根據(jù)入門blog的例子繼續(xù)寫下去的。

我們先來看一看對(duì)應(yīng)的現(xiàn)象。 我們這里的配置文件 *-dispatcher.xml中的關(guān)鍵配置如下:

(視圖配置省略)

<mvc:resources location="/static/" mapping="/static/**"/>
<mvc:annotation-driven/>
<context:component-scan base-package="org.format.demo.controller"/>

pom中需要有以下依賴(Spring依賴及其他依賴不顯示):

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  jackson-core-asl
  <version>1.9.13</version>
</dependency>
<dependency>
  <groupId>org.codehaus.jackson</groupId>
  jackson-mapper-asl
  <version>1.9.13</version>
</dependency>

這個(gè)依賴是json序列化的依賴。

ok。我們?cè)贑ontroller中添加一個(gè)method:

@RequestMapping("/xmlOrJson")
@ResponseBody public Map

直接訪問地址:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

我們看到,短短幾行配置。使用@ResponseBody注解之后,Controller返回的對(duì)象 自動(dòng)被轉(zhuǎn)換成對(duì)應(yīng)的json數(shù)據(jù),在這里不得不感嘆SpringMVC的強(qiáng)大。

我們好像也沒看到具體的配置,唯一看到的就是*-dispatcher.xml中的一句配置: mvc:annotation-driven/。其實(shí)就是這個(gè)配置,導(dǎo)致了java對(duì)象自動(dòng)轉(zhuǎn)換成json對(duì)象的現(xiàn)象。

那么spring到底是如何實(shí)現(xiàn)java對(duì)象到j(luò)son對(duì)象的自動(dòng)轉(zhuǎn)換的呢? 為什么轉(zhuǎn)換成了json數(shù)據(jù),如果想轉(zhuǎn)換成xml數(shù)據(jù),那該怎么辦?

源碼分析

**本文使用的spring版本是4.0.2。  **

在講解 mvc:annotation-driven/這個(gè)配置之前,我們先了解下Spring的消息轉(zhuǎn)換機(jī)制。@ResponseBody這個(gè)注解就是使用消息轉(zhuǎn)換機(jī)制,最終通過json的轉(zhuǎn)換器轉(zhuǎn)換成json數(shù)據(jù)的。

HttpMessageConverter接口就是Spring提供的http消息轉(zhuǎn)換接口。有關(guān)這方面的知識(shí)大家可以參考"參考資料"中的 第二條鏈接,里面講的很清楚。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

下面開始分析 mvc:annotation-driven/這句配置:

這句代碼在spring中的解析類是:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

在AnnotationDrivenBeanDefinitionParser源碼的152行parse方法中:

分別實(shí)例化了RequestMappingHandlerMapping,ConfigurableWebBindingInitializer,RequestMappingHandlerAdapter等諸多類。

其中RequestMappingHandlerMapping和RequestMappingHandlerAdapter這兩個(gè)類比較重要。

RequestMappingHandlerMapping處理請(qǐng)求映射的,處理@RequestMapping跟請(qǐng)求地址之間的關(guān)系。

RequestMappingHandlerAdapter是請(qǐng)求處理的適配器,也就是請(qǐng)求之后處理具體邏輯的執(zhí)行,關(guān)系到哪個(gè)類的哪個(gè)方法以及轉(zhuǎn)換器等工作,這個(gè)類是我們講的重點(diǎn),其中它的屬性messageConverters是本文要講的重點(diǎn)。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

私有方法:getMessageConverters

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

從代碼中我們可以,RequestMappingHandlerAdapter設(shè)置messageConverters的邏輯:

1.如果 mvc:annotation-driven節(jié)點(diǎn)有子節(jié)點(diǎn)message-converters,那么它的轉(zhuǎn)換器屬性messageConverters也由這些子節(jié)點(diǎn)組成。

message-converters的子節(jié)點(diǎn)配置如下:

<mvc:annotation-driven>
  <mvc:message-converters>
    <bean class="org.example.MyHttpMessageConverter"/>
    <bean class="org.example.MyOtherHttpMessageConverter"/>
  </mvc:message-converters>
</mvc:annotation-driven>

2.message-converters子節(jié)點(diǎn)不存在或它的屬性register-defaults為true的話,加入其他的轉(zhuǎn)換器:ByteArrayHttpMessageConverter、StringHttpMessageConverter、ResourceHttpMessageConverter等。

我們看到這么一段:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

這些boolean屬性是哪里來的呢,它們是AnnotationDrivenBeanDefinitionParser的靜態(tài)變量。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

其中ClassUtils中的isPresent方法如下:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

看到這里,讀者應(yīng)該明白了為什么本文一開始在pom文件中需要加入對(duì)應(yīng)的jackson依賴,為了讓json轉(zhuǎn)換器jackson成為默認(rèn)轉(zhuǎn)換器之一。

mvc:annotation-driven的作用讀者也明白了。

下面我們看如何通過消息轉(zhuǎn)換器將java對(duì)象進(jìn)行轉(zhuǎn)換的。

RequestMappingHandlerAdapter在進(jìn)行handle的時(shí)候,會(huì)委托給HandlerMethod(具體由子類ServletInvocableHandlerMethod處理)的invokeAndHandle方法進(jìn)行處理,這個(gè)方法又轉(zhuǎn)接給HandlerMethodReturnValueHandlerComposite處理。

HandlerMethodReturnValueHandlerComposite維護(hù)了一個(gè)HandlerMethodReturnValueHandler列表。HandlerMethodReturnValueHandler是一個(gè)對(duì)返回值進(jìn)行處理的策略接口,這個(gè)接口非常重要。關(guān)于這個(gè)接口的細(xì)節(jié),請(qǐng)參考樓主的另外一篇博客:http://www.cnblogs.com/fangjian0423/p/springMVC-request-param-analysis.html。然后找到對(duì)應(yīng)的HandlerMethodReturnValueHandler對(duì)結(jié)果值進(jìn)行處理。

最終找到RequestResponseBodyMethodProcessor這個(gè)Handler(由于使用了@ResponseBody注解)。

RequestResponseBodyMethodProcessor的supportsReturnType方法:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

然后使用handleReturnValue方法進(jìn)行處理:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

我們看到,這里使用了轉(zhuǎn)換器。

具體的轉(zhuǎn)換方法:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

至于為何是請(qǐng)求頭部的Accept數(shù)據(jù),讀者可以進(jìn)去debug這個(gè)getAcceptableMediaTypes方法看看。 我就不羅嗦了~~~

ok。至此,我們走遍了所有的流程。

現(xiàn)在,回過頭來看。為什么一開始的demo輸出了json數(shù)據(jù)?

我們來分析吧。

由于我們只配置了 mvc:annotation-driven,因此使用spring默認(rèn)的那些轉(zhuǎn)換器。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

很明顯,我們看到了2個(gè)xml和1個(gè)json轉(zhuǎn)換器。 要看能不能轉(zhuǎn)換,得看HttpMessageConverter接口的public boolean canWrite(Class<?> clazz, MediaType mediaType)方法是否返回true來決定的。

我們先分析SourceHttpMessageConverter:

它的canWrite方法被父類AbstractHttpMessageConverter重寫了。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

發(fā)現(xiàn)SUPPORTED_CLASSES中沒有Map類(本文demo返回的是Map類),因此不支持。

下面看Jaxb2RootElementHttpMessageConverter:

這個(gè)類直接重寫了canWrite方法。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

需要有XmlRootElement注解。 很明顯,Map類當(dāng)然沒有。

最終MappingJackson2HttpMessageConverter匹配,進(jìn)行json轉(zhuǎn)換。(為何匹配,請(qǐng)讀者自行查看源碼)

實(shí)例講解

我們分析了轉(zhuǎn)換器的轉(zhuǎn)換過程之后,下面就通過實(shí)例來驗(yàn)證我們的結(jié)論吧。

首先,我們先把xml轉(zhuǎn)換器實(shí)現(xiàn)。

之前已經(jīng)分析,默認(rèn)的轉(zhuǎn)換器中是支持xml的。下面我們加上注解試試吧。

由于Map是jdk源碼中的部分,因此我們用Employee來做demo。

因此,Controller加上一個(gè)方法:

@RequestMapping("/xmlOrJsonSimple")
@ResponseBody public Employee xmlOrJsonSimple() { return employeeService.getById(1);
}

實(shí)體中加上@XmlRootElement注解

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

結(jié)果如下:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

我們發(fā)現(xiàn),解析成了xml。

這里為什么解析成xml,而不解析成json呢?

之前分析過,消息轉(zhuǎn)換器是根據(jù)class和mediaType決定的。

我們使用firebug看到:

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

我們發(fā)現(xiàn)Accept有xml,沒有json。因此解析成xml了。

我們?cè)賮眚?yàn)證,同一地址,HTTP頭部不同Accept??词欠裾_。

$.ajax({
    url: "${request.contextPath}/employee/xmlOrJsonSimple",
    success: function(res) {
        console.log(res);
    },
    headers: { "Accept": "application/xml" }
});

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

$.ajax({
    url: "${request.contextPath}/employee/xmlOrJsonSimple",
    success: function(res) {
        console.log(res);
    },
    headers: { "Accept": "application/json" }
});

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

驗(yàn)證成功。

關(guān)于配置

如果不想使用 mvc:annotation-driven/中默認(rèn)的RequestMappingHandlerAdapter的話,我們可以在重新定義這個(gè)bean,spring會(huì)覆蓋掉默認(rèn)的RequestMappingHandlerAdapter。

為何會(huì)覆蓋,請(qǐng)參考樓主的另外一篇博客: http://www.cnblogs.com/fangjian0423/p/spring-Ordered-interface.html

    `
  
    
      
      
      
    
  
`

或者如果只想換messageConverters的話。

<mvc:annotation-driven>
  <mvc:message-converters>
    <bean class="org.example.MyHttpMessageConverter"/>
    <bean class="org.example.MyOtherHttpMessageConverter"/>
  </mvc:message-converters>
</mvc:annotation-driven>

如果還想用其他converters的話。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

以上是spring-mvc jar包中的converters。

這里我們使用轉(zhuǎn)換xml的MarshallingHttpMessageConverter。

這個(gè)converter里面使用了marshaller進(jìn)行轉(zhuǎn)換

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

我們這里使用XStreamMarshaller。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

json沒有轉(zhuǎn)換器,返回406.

至于xml格式的問題,大家自行解決吧。 這里用的是XStream~。

使用這種方式,pom別忘記了加入xstream的依賴:

<dependency>
  <groupId>com.thoughtworks.xstream</groupId>
  xstream
  <version>1.4.7</version>
</dependency>

總結(jié)

寫了這么多,可能讀者覺得有點(diǎn)羅嗦。 畢竟這也是自己的一些心得,希望都能說出來與讀者共享。

剛接觸SpringMVC的時(shí)候,發(fā)現(xiàn)這種自動(dòng)轉(zhuǎn)換機(jī)制很牛逼,但是一直沒有研究它的原理,目前,算是了了一個(gè)小小心愿吧,SpringMVC還有很多內(nèi)容,以后自己研究其他內(nèi)容的時(shí)候還會(huì)與大家一起共享的。

文章難免會(huì)出現(xiàn)一些錯(cuò)誤,希望讀者們能指明出來。

參考資料

http://my.oschina.net/HeliosFly/blog/205343

http://my.oschina.net/lichhao/blog/172562

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html

詳解RequestBody和@ResponseBody注解

概述 在SpringMVC中,可以使用@ RequestBody和@ResponseBody兩個(gè)注解,分別完成請(qǐng)求報(bào)文到對(duì)象和對(duì)象到響應(yīng)報(bào)文的轉(zhuǎn)換,底層這種靈活的消息轉(zhuǎn)換機(jī)制,就是Spring3.x中新引入的HttpMessageConverter即消息轉(zhuǎn)換器機(jī)制。

#Http請(qǐng)求的抽象 還是回到請(qǐng)求-響應(yīng),也就是解析請(qǐng)求體,然后返回響應(yīng)報(bào)文這個(gè)最基本的Http請(qǐng)求過程中來。我們知道,在servlet標(biāo)準(zhǔn)中,可以用javax.servlet.ServletRequest接口中的以下方法:

public ServletInputStream getInputStream() throws IOException;

來得到一個(gè)ServletInputStream。這個(gè)ServletInputStream中,可以讀取到一個(gè)原始請(qǐng)求報(bào)文的所有內(nèi)容。同樣的,在javax.servlet.ServletResponse接口中,可以用以下方法:

public ServletOutputStream getOutputStream() throws IOException;

來得到一個(gè)ServletOutputStream,這個(gè)ServletOutputSteam,繼承自java中的OutputStream,可以讓你輸出Http的響應(yīng)報(bào)文內(nèi)容。

讓我們嘗試著像SpringMVC的設(shè)計(jì)者一樣來思考一下。我們知道,Http請(qǐng)求和響應(yīng)報(bào)文本質(zhì)上都是一串字符串,當(dāng)請(qǐng)求報(bào)文來到j(luò)ava世界,它會(huì)被封裝成為一個(gè)ServletInputStream的輸入流,供我們讀取報(bào)文。響應(yīng)報(bào)文則是通過一個(gè)ServletOutputStream的輸出流,來輸出響應(yīng)報(bào)文。

我們從流中,只能讀取到原始的字符串報(bào)文,同樣,我們往輸出流中,也只能寫原始的字符。而在java世界中,處理業(yè)務(wù)邏輯,都是以一個(gè)個(gè)有業(yè)務(wù)意義的對(duì)象為處理維度的,那么在報(bào)文到達(dá)SpringMVC和從SpringMVC出去,都存在一個(gè)字符串到j(luò)ava對(duì)象的阻抗問題。這一過程,不可能由開發(fā)者手工轉(zhuǎn)換。我們知道,在Struts2中,采用了OGNL來應(yīng)對(duì)這個(gè)問題,而在SpringMVC中,它是HttpMessageConverter機(jī)制。我們先來看兩個(gè)接口。

#HttpInputMessage 這個(gè)類是SpringMVC內(nèi)部對(duì)一次Http請(qǐng)求報(bào)文的抽象,在HttpMessageConverter的read()方法中,有一個(gè)HttpInputMessage的形參,它正是SpringMVC的消息轉(zhuǎn)換器所作用的受體“請(qǐng)求消息”的內(nèi)部抽象,消息轉(zhuǎn)換器從“請(qǐng)求消息”中按照規(guī)則提取消息,轉(zhuǎn)換為方法形參中聲明的對(duì)象。

package org.springframework.http;
import java.io.IOException;
import java.io.InputStream;
public interface HttpInputMessage extends HttpMessage {
	InputStream getBody() throws IOException;
}

#HttpOutputMessage 這個(gè)類是SpringMVC內(nèi)部對(duì)一次Http響應(yīng)報(bào)文的抽象,在HttpMessageConverter的write()方法中,有一個(gè)HttpOutputMessage的形參,它正是SpringMVC的消息轉(zhuǎn)換器所作用的受體“響應(yīng)消息”的內(nèi)部抽象,消息轉(zhuǎn)換器將“響應(yīng)消息”按照一定的規(guī)則寫到響應(yīng)報(bào)文中。

package org.springframework.http;
import java.io.IOException;
import java.io.OutputStream;
public interface HttpOutputMessage extends HttpMessage {
	OutputStream getBody() throws IOException;
}

#HttpMessageConverter 對(duì)消息轉(zhuǎn)換器最高層次的接口抽象,描述了一個(gè)消息轉(zhuǎn)換器的一般特征,我們可以從這個(gè)接口中定義的方法,來領(lǐng)悟Spring3.x的設(shè)計(jì)者對(duì)這一機(jī)制的思考過程。

package org.springframework.http.converter;
import java.io.IOException;
import java.util.List;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
public interface HttpMessageConverter<T> {
	boolean canRead(Class<?> clazz, MediaType mediaType);
	boolean canWrite(Class<?> clazz, MediaType mediaType);
	List<MediaType> getSupportedMediaTypes();
	T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
			throws IOException, HttpMessageNotReadableException;
	void write(T t, MediaType contentType, HttpOutputMessage outputMessage)
			throws IOException, HttpMessageNotWritableException;
}

HttpMessageConverter接口的定義出現(xiàn)了成對(duì)的canRead(),read()和canWrite(),write()方法,MediaType是對(duì)請(qǐng)求的Media Type屬性的封裝。舉個(gè)例子,當(dāng)我們聲明了下面這個(gè)處理方法。

@RequestMapping(value="/string", method=RequestMethod.POST)
public @ResponseBody String readString(@RequestBody String string) {
    return "Read string '" + string + "'";
}

在SpringMVC進(jìn)入readString方法前,會(huì)根據(jù)@RequestBody注解選擇適當(dāng)?shù)腍ttpMessageConverter實(shí)現(xiàn)類來將請(qǐng)求參數(shù)解析到string變量中,具體來說是使用了StringHttpMessageConverter類,它的canRead()方法返回true,然后它的read()方法會(huì)從請(qǐng)求中讀出請(qǐng)求參數(shù),綁定到readString()方法的string變量中。

當(dāng)SpringMVC執(zhí)行readString方法后,由于返回值標(biāo)識(shí)了@ResponseBody,SpringMVC將使用StringHttpMessageConverter的write()方法,將結(jié)果作為String值寫入響應(yīng)報(bào)文,當(dāng)然,此時(shí)canWrite()方法返回true。

我們可以用下面的圖,簡(jiǎn)單描述一下這個(gè)過程。

SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解

#RequestResponseBodyMethodProcessor 將上述過程集中描述的一個(gè)類是org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor,這個(gè)類同時(shí)實(shí)現(xiàn)了HandlerMethodArgumentResolver和HandlerMethodReturnValueHandler兩個(gè)接口。前者是將請(qǐng)求報(bào)文綁定到處理方法形參的策略接口,后者則是對(duì)處理方法返回值進(jìn)行處理的策略接口。兩個(gè)接口的源碼如下:

package org.springframework.web.method.support;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
public interface HandlerMethodArgumentResolver {
	boolean supportsParameter(MethodParameter parameter);
	Object resolveArgument(MethodParameter parameter,
						   ModelAndViewContainer mavContainer,
						   NativeWebRequest webRequest,
						   WebDataBinderFactory binderFactory) throws Exception;
}
package org.springframework.web.method.support;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
public interface HandlerMethodReturnValueHandler {
	boolean supportsReturnType(MethodParameter returnType);
	void handleReturnValue(Object returnValue,
						   MethodParameter returnType,
						   ModelAndViewContainer mavContainer,
						   NativeWebRequest webRequest) throws Exception;
}

RequestResponseBodyMethodProcessor這個(gè)類,同時(shí)充當(dāng)了方法參數(shù)解析和返回值處理兩種角色。我們從它的源碼中,可以找到上面兩個(gè)接口的方法實(shí)現(xiàn)。

對(duì)HandlerMethodArgumentResolver接口的實(shí)現(xiàn):

public boolean supportsParameter(MethodParameter parameter) {
	return parameter.hasParameterAnnotation(RequestBody.class);
}
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
		NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
	Object argument = readWithMessageConverters(webRequest, parameter, parameter.getGenericParameterType());
	String name = Conventions.getVariableNameForParameter(parameter);
	WebDataBinder binder = binderFactory.createBinder(webRequest, argument, name);
	if (argument != null) {
		validate(binder, parameter);
	}
	mavContainer.addAttribute(BindingResult.MODEL_KEY_PREFIX + name, binder.getBindingResult());
	return argument;
}

對(duì)HandlerMethodReturnValueHandler接口的實(shí)現(xiàn)

public boolean supportsReturnType(MethodParameter returnType) {
	return returnType.getMethodAnnotation(ResponseBody.class) != null;
}
	public void handleReturnValue(Object returnValue, MethodParameter returnType,
		ModelAndViewContainer mavContainer, NativeWebRequest webRequest)
		throws IOException, HttpMediaTypeNotAcceptableException {
	mavContainer.setRequestHandled(true);
	if (returnValue != null) {
		writeWithMessageConverters(returnValue, returnType, webRequest);
	}
}

看完上面的代碼,整個(gè)HttpMessageConverter消息轉(zhuǎn)換的脈絡(luò)已經(jīng)非常清晰。因?yàn)閮蓚€(gè)接口的實(shí)現(xiàn),分別是以是否有@RequestBody和@ResponseBody為條件,然后分別調(diào)用HttpMessageConverter來進(jìn)行消息的讀寫。

如果你想問,怎么樣跟蹤到RequestResponseBodyMethodProcessor中,請(qǐng)你按照前面幾篇博文的思路,然后到這里 spring-mvc-showcase下載源碼回來,對(duì)其中HttpMessageConverter相關(guān)的例子進(jìn)行debug,只要你肯下功夫,相信你一定會(huì)有屬于自己的收獲的。

#思考 張小龍?jiān)谡勎⑿诺谋举|(zhì)時(shí)候說:“微信只是個(gè)平臺(tái),消息在其中流轉(zhuǎn)”。在我們對(duì)SpringMVC源碼分析的過程中,我們可以從HttpMessageConverter機(jī)制中領(lǐng)悟到類似的道理。在SpringMVC的設(shè)計(jì)者眼中,一次請(qǐng)求報(bào)文和一次響應(yīng)報(bào)文,分別被抽象為一個(gè)請(qǐng)求消息HttpInputMessage和一個(gè)響應(yīng)消息HttpOutputMessage。

處理請(qǐng)求時(shí),由合適的消息轉(zhuǎn)換器將請(qǐng)求報(bào)文綁定為方法中的形參對(duì)象,在這里,同一個(gè)對(duì)象就有可能出現(xiàn)多種不同的消息形式,比如json和xml。同樣,當(dāng)響應(yīng)請(qǐng)求時(shí),方法的返回值也同樣可能被返回為不同的消息形式,比如json和xml。

在SpringMVC中,針對(duì)不同的消息形式,我們有不同的HttpMessageConverter實(shí)現(xiàn)類來處理各種消息形式。但是,只要這些消息所蘊(yùn)含的“有效信息”是一致的,那么各種不同的消息轉(zhuǎn)換器,都會(huì)生成同樣的轉(zhuǎn)換結(jié)果。至于各種消息間解析細(xì)節(jié)的不同,就被屏蔽在不同的HttpMessageConverter實(shí)現(xiàn)類中了。

以上是“SpringMVC中如何使用消息轉(zhuǎn)換器HttpMessageConverter與@ResponseBody注解”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI