在Spring MVC中,如何在使用@ResponseBody时设置mime类型头

Sea*_*oyd 75 java spring json controller spring-mvc

我有一个Spring MVC Controller,它返回一个JSON String,我想将mimetype设置为application/json.我怎样才能做到这一点?

@RequestMapping(method=RequestMethod.GET, value="foo/bar")
@ResponseBody
public String fooBar(){
    return myService.getJson();
}
Run Code Online (Sandbox Code Playgroud)

业务对象已经可以作为JSON字符串使用,因此使用MappingJacksonJsonView对我来说不是解决方案.@ResponseBody是完美的,但我怎样才能设置mimetype?

Jav*_*ero 120

ResponseEntity而不是ResponseBody.这样您就可以访问响应标头,并可以设置适当的内容类型.根据Spring文档:

HttpEntity类似于 @RequestBody@ResponseBody.除了访问请求和响应主体之外,HttpEntity(以及特定于响应的子类 ResponseEntity)还允许访问请求和响应头

代码如下所示:

@RequestMapping(method=RequestMethod.GET, value="/fooBar")
public ResponseEntity<String> fooBar2() {
    String json = "jsonResponse";
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentType(MediaType.APPLICATION_JSON);
    return new ResponseEntity<String>(json, responseHeaders, HttpStatus.CREATED);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我可以多次投票,我会的! (5认同)
  • 使用这种方法,您可以使用相同的方法返回不同的内容类型,这是Spring无法生成的"产品".此外,这是最不具侵入性的,即您不必创建/实例化您自己的MessageConverters. (2认同)

mat*_*sev 40

我会考虑重构服务以返回您的域对象而不是JSON字符串,并让Spring处理序列化(通过MappingJacksonHttpMessageConverter您编写时).从Spring 3.1开始,实现看起来非常简洁:

@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE, 
    method = RequestMethod.GET
    value = "/foo/bar")
@ResponseBody
public Bar fooBar(){
    return myService.getBar();
}
Run Code Online (Sandbox Code Playgroud)

评论:

首先,必须将<mvc:annotation-driven />或者@EnableWebMvc必须添加到您的应用程序配置中.

接下来,注释的produce属性@RequestMapping用于指定响应的内容类型.因此,它应设置为MediaType.APPLICATION_JSON_VALUE(或"application/json").

最后,必须添加Jackson,以便Java和JSON之间的任何序列化和反序列化将由Spring自动处理(Jackson依赖项由Spring检测,并且MappingJacksonHttpMessageConverter将在引擎盖下).

  • 根据javadoc,property*produce*的目的是匹配请求的*Accept*头.这解释了为什么*produce*的值是一个值列表.因此,*produce*不是添加任何响应头的可靠手段.根据javadoc,它与响应头没有任何关系. (6认同)

Gri*_*Dog 7

您可能无法使用@ResponseBody执行此操作,但这样的操作应该有效:

package xxx;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class FooBar {
  @RequestMapping(value="foo/bar", method = RequestMethod.GET)
  public void fooBar(HttpServletResponse response) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    out.write(myService.getJson().getBytes());
    response.setContentType("application/json");
    response.setContentLength(out.size());
    response.getOutputStream().write(out.toByteArray());
    response.getOutputStream().flush();
  }
}
Run Code Online (Sandbox Code Playgroud)