В Spring MVC, как я могу установить заголовок MIME-типа при использовании @ResponseBody - PullRequest
74 голосов
/ 17 декабря 2010

У меня есть Spring MVC Controller, который возвращает строку JSON, и я хотел бы установить mimetype для application / json. Как я могу это сделать?

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

Бизнес-объекты уже доступны в виде строк JSON, поэтому использование MappingJacksonJsonView не является для меня решением. @ResponseBody идеально, но как я могу установить mimetype?

Ответы [ 7 ]

118 голосов
/ 19 декабря 2010

Используйте 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);
}
39 голосов
/ 24 ноября 2012

Я хотел бы реорганизовать службу, чтобы она возвращала ваш объект домена, а не строки 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 должны быть добавлены в конфигурацию вашего приложения.

Далее атрибут создает аннотации @RequestMapping, которая используется для указания типа содержимого ответа. Следовательно, он должен быть установлен на MediaType.APPLICATION_JSON_VALUE (или "application/json").

Наконец, Джексон должен быть добавлен, так что любая сериализация и десериализация между Java и JSON будут автоматически обрабатываться Spring (зависимость Джексона обнаружена Spring, и MappingJacksonHttpMessageConverter будет скрыт).

7 голосов
/ 17 декабря 2010

Возможно, вы не сможете сделать это с @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();
  }
}
4 голосов
/ 17 декабря 2010

Я не думаю, что это возможно.Похоже, для этого существует открытая Jira:

SPR-6702: явно заданный тип содержимого ответа в @ ResponseBody

3 голосов
/ 17 декабря 2010

Зарегистрируйте 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.

1 голос
/ 17 декабря 2010

Не думаю, что вы можете, кроме response.setContentType(..)

0 голосов
/ 30 сентября 2016

Моя версия реальности.Загрузка файла 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;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...