Spring MVC's @ResponseBody returns JSON string

Xml代码
<bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" > 
    <property name="messageConverters"> 
  <list> 
   <ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 --> 
  </list> 
</property> 
</bean>     
<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" /> 

<bean class ="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
    <property name="messageConverters">
  <list>
   <ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 -->
  </list>
</property>
</bean>  
<bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />

需要以下两个jar包:

Xml代码
<dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.5.5" conf="runtime->default" /> 
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.5.5" conf="runtime->default" /> 

<dependency org="org.codehaus.jackson" name="jackson-core-asl" rev="1.5.5" conf="runtime->default" />
<dependency org="org.codehaus.jackson" name="jackson-mapper-asl" rev="1.5.5"conf="runtime->default" />



Java代码
@RequestMapping(value="/nogood", method=RequestMethod.GET)  
public @ResponseBody CmUser execute(String userid) {  
  CmUser u = new CmUser();  
  u.setAge(16);  
  u.setName("Test User");  
  return u;  




Through the above code, the java object can be directly converted to the json object, the following is the configuration in the project

    < bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="webBindingInitializer">
            <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
                <property name=" conversionService" ref="conversionService"/>
            </bean>
        </property>
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
                <bean class="org.springframework.http.converter.StringHttpMessageConverter" >
                    <property name = "supportedMediaTypes">
                           <list>
                                   <value>text/plain;charset=UTF-8</value>
                          </list>
                     </property>
                </bean>
                <bean class="org.springframework.http.converter.ResourceHttpMessageConverter" />
                <!-- 注:开启此类需相关jar包持:javax.xml.bind.JAXBException
                <bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
                <bean class="org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter" />
                <bean class="org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter" />
                 -->
                <bean class="org.springframework. http.converter.json.MappingJacksonHttpMessageConverter" />
            </list>
        </property>
    </bean>

The @ResponseBody annotation can be analyzed below.

In SpringMVC, a @ResponseBody annotation can be added to a method of the Controller, indicating that the return result of the method is directly Write to the HTTP response body.

However, in actual use, it is found that the value of "Content-Type" in the last generated response is incorrect.

Spring uses AnnotationMethodHandlerAdapter to handle @ResponseBody, and this class uses some HttpMessageConverters to process information specifically.

The AnnotationMethodHandlerAdapter uses the value of "Accept" in the request header to match the MediaType supported by the messageConverter, and then writes the first value of "Accept" to the "Content-Type" of the response.

General requests are made through the browser, and the value of "Accept" in the request header is generated by the browser.

The value generated by Chrome is application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

The value generated by IE8 is application/x -ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword , */*

So the value of "Content-Type" in the final response is "application/xml" or "application/x-ms-application".

But we usually return a result of type String or byte[] on the method annotated @ResponseBody, and the expected value of "Content-Type" should be "text/plain" or "application/octet-stream" .

This results in the browser not properly handling the returned content.

In fact, in the process of processing with HttpMessageConverter, Spring will first determine whether "Content-Type" is written in the response header. If it is not written, it will use the first value of "Accept" in the request header.

But because Spring encapsulates HttpServletResponse, it actually uses ServletServerHttpResponse, which has a reference to the real HttpServletResponse.

The getHeaders() method of ServletServerHttpResponse is used in the process of judging the response header, but this method does not return the header in the real HttpServletResponse. (This should be a problem?)

So although we can add a reference to HttpServletResponse in the Controller method, and then set the value of "Content-Type", it will not work.

Through the above analysis, @ResponseBody seems to be unavailable.

You can also refer to the following articles: http://www.iteye.com/topic/1124054
http://www.360doc.com/content/12/0809/11/9600761_229177035.shtml

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326780678&siteId=291194637