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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4471584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 17:52:47  来源:igfitidea点击:

In Spring MVC, how can I set the mime type header when using @ResponseBody

javajsonspringspring-mvccontroller

提问by Sean Patrick Floyd

I have a Spring MVC Controller that returns a JSON String and I would like to set the mimetype to application/json. How can I do that?

我有一个返回 JSON 字符串的 Spring MVC 控制器,我想将 mimetype 设置为 application/json。我怎样才能做到这一点?

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

The business objects are already available as JSON strings, so using MappingHymansonJsonViewis not the solution for me. @ResponseBodyis perfect, but how can I set the mimetype?

业务对象已经可以作为 JSON 字符串使用,所以使用MappingHymansonJsonView不是我的解决方案。@ResponseBody是完美的,但我该如何设置 mimetype?

采纳答案by matsev

I would consider to refactor the service to return your domain object rather than JSON strings and let Spring handle the serialization (via the MappingHymansonHttpMessageConverteras you write). As of Spring 3.1, the implementation looks quite neat:

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

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

Comments:

注释:

First, the <mvc:annotation-driven />or the @EnableWebMvcmust be addedto your application config.

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

Next, the producesattribute of the @RequestMappingannotation is used to specify the content type of the response. Consequently, it should be set to MediaType.APPLICATION_JSON_VALUE(or "application/json").

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

Lastly, Hymanson must be added so that any serialization and de-serialization between Java and JSON will be handled automatically by Spring (the Hymanson dependency is detected by Spring and the MappingHymansonHttpMessageConverterwill be under the hood).

最后,必须添加 Hymanson,以便 Java 和 JSON 之间的任何序列化和反序列化都将由 Spring 自动处理(Hymanson 依赖项由 Spring 检测到,MappingHymansonHttpMessageConverter并将在幕后)。

回答by dogbane

I don't think this is possible. There appears to be an open Jira for it:

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

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

SPR-6702:在@ResponseBody 中显式设置响应内容类型

回答by Bozho

I don't think you can, apart from response.setContentType(..)

我不认为你可以,除了 response.setContentType(..)

回答by GriffeyDog

You may not be able to do it with @ResponseBody, but something like this should work:

您可能无法使用 @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();
  }
}

回答by OrangeDog

Register org.springframework.http.converter.json.MappingHymansonHttpMessageConverteras the message converter and return the object directly from the method.

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

<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.MappingHymansonHttpMessageConverter"/>
    </list>
  </property>
</bean>

and the controller:

和控制器:

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

This requires the dependency org.springframework:spring-webmvc.

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

回答by Javier Ferrero

Use ResponseEntityinstead of ResponseBody. This way you have access to the response headers and you can set the appropiate content type. According to the Spring docs:

使用ResponseEntity代替ResponseBody。这样您就可以访问响应标头,并且可以设置适当的内容类型。根据Spring 文档

The HttpEntityis similar to @RequestBodyand @ResponseBody. Besides getting access to the request and response body, HttpEntity(and the response-specific subclass ResponseEntity) also allows access to the request and response headers

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

The code will look like:

代码将如下所示:

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

回答by R Keene

My version of reality. Loading a HTML file and streaming to the browser.

我的现实版本。加载 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;
    }
}