Spring MVC 4:“application / 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

   Spring MVC Web Application  dispatcher org.springframework.web.servlet.DispatcherServlet 1    default *.js   default *.css   dispatcher /   contextConfigLocation /WEB-INF/dispatcher-servlet.xml   org.springframework.web.context.ContextLoaderListener   

我的dispatcher-servlet.xml

          

使用WildFly 8.1作为我的应用服务器。

首先要理解的是RequestMapping#produces()元素

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

仅用于限制请求处理程序的映射。 它没有别的。

然后,假设您的方法的返回类型为String并使用@ResponseBody批注,则返回值将由StringHttpMessageConverter处理,后者将Content-type标头设置为text/plain 。 如果您想自己返回一个JSON字符串并将标头设置为application/json ,请使用返回类型的ResponseEntity (摆脱@ResponseBody )并@ResponseBody添加适当的标头。

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

请注意,你应该有

  

在您的servlet上下文配置中,使用最合适的默认值设置MVC配置。

在控制器的返回类型上使用jackson库和@ResponseBody注释。

如果您希望返回表示为JSon的POJO,则此方法有效。 如果你喜欢返回String而不是POJO作为JSon请参考Sotirious的回答。

正如其他人评论的那样,因为你的方法的返回类型是String Spring不会觉得需要对结果做任何事情。

如果您更改签名以使返回类型需要编组,则应该有所帮助:

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

不完全适用于此OP,但对于那些遇到404并且无法将响应content-type设置为"application/json" (任何content-type )的人。 一种可能性是服务器实际响应406但是资源管理器(例如,chrome)将其打印为404。

如果您不自定义消息转换器,spring将使用AbstractMessageConverterMethodProcessor.java 。 它将运行:

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

如果它们没有任何重叠(相同的项),它将抛出HttpMediaTypeNotAcceptableException ,最终导致406.无论是ajax,还是GET / POST或表单操作,如果请求uri以.html结尾或者任何后缀, requestedMediaTypes将是“text / [that suffix]”,这与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" 

当我升级到Spring 4时,我需要更新jackson依赖项,如下所示:

   com.fasterxml.jackson.core jackson-core 2.5.1   com.fasterxml.jackson.core jackson-databind 2.5.1   com.fasterxml.jackson.core jackson-annotations 2.5.1  

我有@Greg post指定的依赖项。 我仍然面临这个问题,并且可以通过添加以下额外的jackson依赖来解决它:

  com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.7.4