假设我有一个控制器,该控制器为GET请求提供服务并返回要序列化为JSON的bean,并且还提供了IllegalArgumentException可以在服务中引发的异常处理程序:
GET
IllegalArgumentException
@RequestMapping(value = "/meta/{itemId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public MetaInformation getMetaInformation(@PathVariable int itemId) { return myService.getMetaInformation(itemId); } @ExceptionHandler(IllegalArgumentException.class) @ResponseStatus(value = HttpStatus.BAD_REQUEST) @ResponseBody public String handleIllegalArgumentException(IllegalArgumentException ex) { return ExceptionUtils.getStackTrace(ex); }
消息转换器是:
<mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> </mvc:message-converters> </mvc:annotation-driven>
现在,当我在浏览器中请求给定的URL时,我会看到正确的JSON答复。但是,如果引发异常,则将字符串化的异常也转换为JSON,但我希望将其处理为StringHttpMessageConverter(导致text/plainmime类型)。我该怎么办?
StringHttpMessageConverter
text/plain
为了使图片更完整(更复杂),假设我还具有以下处理程序:
@RequestMapping(value = "/version", method = RequestMethod.GET) @ResponseBody public String getApplicationVersion() { return "1.0.12"; }
这个处理器允许返回串,都被序列化MappingJackson2HttpMessageConverter,并StringHttpMessageConverter根据传入Accept- type客户端。返回类型和值应如下所示:
MappingJackson2HttpMessageConverter
Accept- type
+----+---------------------+-----------------------+------------------+-------------------------------------+ | NN | URL | Accept-type | Content-type | Message converter | | | | request header | response header | | +----+---------------------+-----------------------+------------------+-------------------------------------+ | 1. | /version | text/html; */* | text/plain | StringHttpMessageConverter | | 2. | /version | application/json; */* | application/json | MappingJackson2HttpMessageConverter | | 3. | /meta/1 | text/html; */* | application/json | MappingJackson2HttpMessageConverter | | 4. | /meta/1 | application/json; */* | application/json | MappingJackson2HttpMessageConverter | | 5. | /meta/0 (exception) | text/html; */* | text/plain | StringHttpMessageConverter | | 6. | /meta/0 (exception) | application/json; */* | text/plain | StringHttpMessageConverter | +----+---------------------+-----------------------+------------------+-------------------------------------+
我想移除produces = MediaType.APPLICATION_JSON_VALUE从@RequestMapping的getMetaInformation会给你想要的结果。
produces = MediaType.APPLICATION_JSON_VALUE
@RequestMapping
getMetaInformation
响应类型将根据Accept标头中的内容类型值进行协商。
编辑
由于这不涉及场景3,4,因此以下是ResponseEntity.class直接使用的解决方案:
ResponseEntity.class
@ExceptionHandler(Exception.class) public ResponseEntity<String> handleIllegalArgumentException(Exception ex) { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.TEXT_PLAIN); return new ResponseEntity<String>(ex.getMessage(), headers, HttpStatus.BAD_REQUEST); }