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

时间:2010-12-17 14:47:10

标签: java json spring spring-mvc controller

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

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

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

7 个答案:

答案 0 :(得分:114)

使用ResponseEntity代替ResponseBody。这样您就可以访问响应标头,并可以设置适当的内容类型。根据{{​​3}}:

  

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);
}

答案 1 :(得分: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();
}

评论:

首先,<mvc:annotation-driven />@EnableWebMvc必须是added到你的应用程序配置。

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

最后,必须添加Jackson,以便Spring和Spring自动处理Java和JSON之间的任何序列化和反序列化(Spring将检测到Jackson依赖关系,而MappingJacksonHttpMessageConverter将在引擎盖下)。< / p>

答案 2 :(得分: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();
  }
}

答案 3 :(得分:4)

我不认为这是可能的。似乎有一个开放的Jira:

SPR-6702: Explicitly set response Content-Type in @ResponseBody

答案 4 :(得分:3)

org.springframework.http.converter.json.MappingJacksonHttpMessageConverter注册为消息转换器,并直接从方法返回对象。

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="webBindingInitializer">
    <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"/>
  </property>
  <property name="messageConverters">
    <list>
      <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </list>
  </property>
</bean>

和控制器:

@RequestMapping(method=RequestMethod.GET, value="foo/bar")
public @ResponseBody Object fooBar(){
    return myService.getActualObject();
}

这需要依赖org.springframework:spring-webmvc

答案 5 :(得分:1)

除了response.setContentType(..)

之外,我认为你不能

答案 6 :(得分:-2)

我的现实版本。加载HTML文件并流式传输到浏览器。

@Controller
@RequestMapping("/")
public class UIController {

    @RequestMapping(value="index", method=RequestMethod.GET, produces = "text/html")
    public @ResponseBody String GetBootupFile() throws IOException  {
        Resource resource = new ClassPathResource("MainPage.html");
        String fileContents = FileUtils.readFileToString(resource.getFile());
        return fileContents;
    }
}