2015-05-30 66 views
15

我有以下標註映射控制器:Spring MVC的4:「應用/ JSON的」內容類型沒有被正確設置

@RequestMapping(value = "/json", method = RequestMethod.GET, produces = "application/json") 
@ResponseBody 
public String bar() { 
    return "{\"test\": \"jsonResponseExample\"}"; 
} 

然而,我返回一個有效的JSON字符串,內容類型時,我在瀏覽器中查看Chrome Dev Tools的響應不是application/json,而只是簡單的text/html。爲什麼沒有設置內容類型?

web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app metadata-complete="true" version="3.0" 
    xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 

    <display-name>Spring MVC Web Application</display-name> 

    <servlet> 
     <servlet-name>dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <!-- static assets --> 
    <servlet-mapping> 
     <servlet-name>default</servlet-name> 
     <url-pattern>*.js</url-pattern> 
    </servlet-mapping> 
    <servlet-mapping> 
     <servlet-name>default</servlet-name> 
     <url-pattern>*.css</url-pattern> 
    </servlet-mapping> 

    <servlet-mapping> 
     <servlet-name>dispatcher</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> 
    </context-param> 

    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
</web-app> 

dispatcher-servlet.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 
    xsi:schemaLocation=" 
    http://www.springframework.org/schema/beans  
    http://www.springframework.org/schema/beans/spring-beans-4.1.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-4.1.xsd"> 


    <context:annotation-config /> 

    <context:component-scan base-package="com.mydomain.controllers" /> 

    <bean id="viewResolver" 
     class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/WEB-INF/jsp/" /> 
     <property name="suffix" value=".jsp" /> 
    </bean> 
</beans> 

使用WildFly 8.1作爲我的應用程序服務器。

+0

@ResponseBody做和acctualy有一些Json映射器? – John

+1

讓我們看看您的方法的其餘部分,請求標題和完整響應。 –

+0

@SotiriosDelimanolis新增全部。 – user1757703

回答

40

要了解的第一件事是,在

@RequestMapping(value = "/json", method = RequestMethod.GET, produces = "application/json") 

RequestMapping#produces()元素只會限制你的請求處理程序映射。 它沒有別的。

然後,因爲你的方法具有String返回類型和注有@ResponseBody,則返回值將通過StringHttpMessageConverter其中Content-type頭設置爲text/plain處理。如果您想自己返回一個JSON字符串並將標頭設置爲application/json,請使用返回類型ResponseEntity(擺脫@ResponseBody)併爲其添加適當的標頭。

@RequestMapping(value = "/json", method = RequestMethod.GET, produces = "application/json") 
public ResponseEntity<String> bar() { 
    final HttpHeaders httpHeaders= new HttpHeaders(); 
    httpHeaders.setContentType(MediaType.APPLICATION_JSON); 
    return new ResponseEntity<String>("{\"test\": \"jsonResponseExample\"}", httpHeaders, HttpStatus.OK); 
} 

請注意,你應該有

<mvc:annotation-driven /> 

在servlet上下文配置來設置你的MVC配置最合適的默認值。

+1

傑克遜庫完美工作用@ResponseBody – John

+2

@ user3360241用'@ ResponseBody'完成的Jackson用'MappingJackson2HttpMessageConverter'實現。它在'StringHttpMessageConverter'之後註冊,因此在處理這個請求時不起作用。 –

+0

Hm:http://www.mkyong.com/spring-mvc/spring-3-mvc-and-json-example/,這也是一個例子。我會說,操作系統也想將自定義對象作爲Json返回。 – John

3

在Controller的返回類型上使用jackson庫和@ResponseBody註釋。

如果您希望返回表示爲JSon的POJO,則此方法有效。如果你想要返回字符串而不是作爲JSon的POJO請參考Sotirious的答案。

+1

我做到了,但它仍然無法正常工作。這可能與我的配置XML文件有關嗎?使用Gson而不是Jackson但同樣的事情。 – user1757703

+0

請添加更多詳情,請告訴我們您的依賴性和控制器的完整代碼。 – John

+0

我不能說這個Gson,我向你保證傑克遜確實能工作。 – John

1

正如其他人所評論的,因爲你的方法的返回類型是String Spring不會覺得需要對結果做任何事情。

如果你改變你的簽名,以便返回類型是什麼,需要編組,應該幫助:

@RequestMapping(value = "/json", method = RequestMethod.GET, produces = "application/json") 
@ResponseBody 
public Map<String, Object> bar() { 
    HashMap<String, Object> map = new HashMap<String, Object>(); 
    map.put("test", "jsonRestExample"); 
    return map; 
} 
-1

當我升級到Spring 4我需要更新傑克遜的依賴關係如下:

<dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-core</artifactId> 
     <version>2.5.1</version> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-databind</artifactId> 
     <version>2.5.1</version> 
    </dependency> 
    <dependency> 
     <groupId>com.fasterxml.jackson.core</groupId> 
     <artifactId>jackson-annotations</artifactId> 
     <version>2.5.1</version> 
    </dependency>   
-1

我有指定@Greg文章的依賴關係。我仍然面臨的問題,可能是能夠通過添加以下附加傑克遜的依賴來解決它:

<dependency> 
    <groupId>com.fasterxml.jackson.dataformat</groupId> 
    <artifactId>jackson-dataformat-xml</artifactId> 
    <version>2.7.4</version> 
</dependency> 
0

不完全是這個OP,但對於那些誰遇到404,並且不能設置響應content-type"application/json"(任何content-type)。一種可能性是服務器實際響應406,但資源管理器(例如,chrome)將其打印爲404.

如果您未自定義消息轉換器,spring將使用AbstractMessageConverterMethodProcessor.java。它可以運行:

List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(request); 
List<MediaType> producibleMediaTypes = getProducibleMediaTypes(request, valueType, declaredType); 

,如果他們沒有任何重疊(同一項目),這會讓HttpMediaTypeNotAcceptableException,這最終導致406號,如果它是一個Ajax,或GET/POST,或形式事動作,如果請求URI與.html或任何後綴結束時,requestedMediaTypes將是「文/ [即後綴]」,而這種衝突與producibleMediaTypes,通常是:你用

"application/json" 
"application/xml" 
"text/xml"   
"application/*+xml" 
"application/json" 
"application/*+json" 
"application/json" 
"application/*+json" 
"application/xml" 
"text/xml"   
"application/*+xml" 
"application/xml" 
"text/xml"   
"application/*+xml" 
相關問題