В Spring MVC, как я могу установить заголовок типа mime при использовании @ResponseBody
У меня есть контроллер Spring MVC, который возвращает строку JSON, и я хотел бы установить тип mimetype в application/json. Как я могу это сделать?
@RequestMapping(method=RequestMethod.GET, value="foo/bar")
@ResponseBody
public String fooBar(){
return myService.getJson();
}
бизнес-объекты уже доступны в виде строк JSON, поэтому с помощью MappingJacksonJsonView
это не решение для меня. @ResponseBody
- это замечательно, но как я могу установить этот фильтр?
7 ответов:
Я бы рассмотрел рефакторинг службы, чтобы вернуть ваш объект домена, а не строки JSON, и пусть Spring обрабатывает сериализацию (через
MappingJacksonHttpMessageConverter
Как вы пишите). По состоянию на весну 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
будет под капотом).
использовать
ResponseEntity
вместоResponseBody
. Таким образом, у вас есть доступ к заголовкам ответов, и вы можете установить соответствующий тип контента. Согласно Spring docs:The
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); }
возможно, вы не сможете сделать это с помощью @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(); } }
Я не думаю, что это возможно. Кажется, для этого есть открытая Джира:
SPR-6702: явно установите содержимое ответа-введите в @ResponseBody
зарегистрироваться
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
.
моя версия реальности. Загрузка 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; } }