我尝试为休息控制器配置一个spring异常处理程序,该处理程序能够根据传入的accept标头将映射呈现给xml和json。它现在抛出500个servlet异常。
这很有效,它拿起了home.jsp:
@ExceptionHandler(IllegalArgumentException.class)
public String handleException(final Exception e, final HttpServletRequest request, Writer writer)
{
return "home";
}
这不起作用:
@ExceptionHandler(IllegalArgumentException.class)
public @ResponseBody Map<String, Object> handleException(final Exception e, final HttpServletRequest request, Writer writer)
{
final Map<String, Object> map = new HashMap<String, Object>();
map.put("errorCode", 1234);
map.put("errorMessage", "Some error message");
return map;
}
在同一控制器中,通过相应的转换器将响应映射到xml或json:
@RequestMapping(method = RequestMethod.GET, value = "/book/{id}", headers = "Accept=application/json,application/xml")
public @ResponseBody
Book getBook(@PathVariable final String id)
{
logger.warn("id=" + id);
return new Book("12345", new Date(), "Sven Haiges");
}
任何?
答案 0 :(得分:20)
你的方法
@ExceptionHandler(IllegalArgumentException.class)
public @ResponseBody Map<String, Object> handleException(final Exception e, final HttpServletRequest request, Writer writer)
不起作用,因为它的返回类型错误。 @ExceptionHandler方法只有两种有效的返回类型:
有关详细信息,请参阅http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html。以下是链接中的具体文字:
返回类型可以是String,其中 被解释为视图名称或 ModelAndView对象。
回应评论
Thanx,我似乎已经过度了。那是 坏...任何想法如何提供 xml / json中自动出现异常 格式? - Sven Haiges 7小时前
这就是我所做的(我实际上是在Scala中完成的,所以我不确定语法是否完全正确,但你应该得到要点)。
@ExceptionHandler(Throwable.class)
@ResponseBody
public void handleException(final Exception e, final HttpServletRequest request,
Writer writer)
{
writer.write(String.format(
"{\"error\":{\"java.class\":\"%s\", \"message\":\"%s\"}}",
e.getClass(), e.getMessage()));
}
答案 1 :(得分:13)
Thanx,我似乎已经过度了。这很糟糕......任何想法如何提供 xml / json格式自动出现异常?
Spring 3.0中的新功能可以利用MappingJacksonJsonView来实现:
private MappingJacksonJsonView jsonView = new MappingJacksonJsonView();
@ExceptionHandler(Exception.class)
public ModelAndView handleAnyException( Exception ex )
{
return new ModelAndView( jsonView, "error", new ErrorMessage( ex ) );
}
答案 2 :(得分:10)
这似乎是一个确认的Bug(SPR-6902 @ResponseBody不适用于@ExceptionHandler)
https://jira.springsource.org/browse/SPR-6902
已在3.1 M1中修复了......
答案 3 :(得分:6)
如果您使用邮件转换器将错误对象编组为响应内容,则可能是以下解决方法
@ExceptionHandler(IllegalArgumentException.class)
public String handleException(final Exception e, final HttpServletRequest request)
{
final Map<String, Object> map = new HashMap<String, Object>();
map.put("errorCode", 1234);
map.put("errorMessage", "Some error message");
request.setAttribute("error", map);
return "forward:/book/errors"; //forward to url for generic errors
}
//set the response status and return the error object to be marshalled
@SuppressWarnings("unchecked")
@RequestMapping(value = {"/book/errors"}, method = {RequestMethod.POST, RequestMethod.GET})
public @ResponseBody Map<String, Object> showError(HttpServletRequest request, HttpServletResponse response){
Map<String, Object> map = new HashMap<String, Object>();
if(request.getAttribute("error") != null)
map = (Map<String, Object>) request.getAttribute("error");
response.setStatus(Integer.parseInt(map.get("errorCode").toString()));
return map;
}
答案 4 :(得分:6)
我正在使用Spring 3.2.4。我解决这个问题的方法是确保我从异常处理程序返回的对象有getter。
没有getter,Jackson无法将对象序列化为JSON。
在我的代码中,对于以下ExceptionHandler:
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public List<ErrorInfo> exceptionHandler(Exception exception){
return ((ConversionException) exception).getErrorInfos();
}
我需要确保我的ErrorInfo对象有getter:
package com.pelletier.valuelist.exception;
public class ErrorInfo {
private int code;
private String field;
private RuntimeException exception;
public ErrorInfo(){}
public ErrorInfo(int code, String field, RuntimeException exception){
this.code = code;
this.field = field;
this.exception = exception;
}
public int getCode() {
return code;
}
public String getField() {
return field;
}
public String getException() {
return exception.getMessage();
}
}
答案 5 :(得分:3)
AnnotationMethodHandlerExceptionResolver还需要MappingJacksonHttpMessageConverter
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver">
<property name="messageConverters">
<list>
<bean
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper" ref="jacksonObjectMapper" />
</bean>
</list>
</property>
</bean>
<bean id="jacksonObjectMapper"
class="iacm.cemetery.framework.web.servlet.rest.JacksonObjectMapper" />
答案 6 :(得分:1)
我遇到了类似的问题,当您的Controller方法返回类型和ExceptionHandler返回类型不是相同时会出现此问题。确保您具有完全相同的返回类型。
控制器方法:
@RequestMapping(value = "/{id}", produces = "application/json", method = RequestMethod.POST)
public ResponseEntity<?> getUserById(@PathVariable String id) throws NotFoundException {
String response = userService.getUser(id);
return new ResponseEntity(response, HttpStatus.OK);
}
建议方法:
@ExceptionHandler(NotFoundException.class)
public ResponseEntity<?> notFoundException(HttpServletRequest request, NotFoundException e) {
ExceptionResponse response = new ExceptionResponse();
response.setSuccess(false);
response.setMessage(e.getMessage());
return new ResponseEntity(response, HttpStatus.NOT_FOUND);
}
正如您所看到的,两个类中的返回类型相同ResponseEntity<?>
。