sme*_*eeb 5 exception spring-mvc httpresponse
Spring 3.2.15,这里基于 MVC 的 REST API(不是Spring Boot,遗憾的是!)。我正在尝试实现一个满足以下条件的异常映射器/处理程序:
MyAppResponse(见下文);和BlahException)必须映射到 HTTP 422FizzBuzzException有自己的状态映射方案:
FizzBuzzException-> HTTP 401FooBarException-> HTTP 403OmgException-> HTTP 404对象所在位置MyAppResponse:
// Groovy pseudo-code
@Canonical
class MyAppResponse {
String detail
String randomNumber
}
Run Code Online (Sandbox Code Playgroud)
看起来也许能ResponseEntityExceptionHandler为我做到这一点,但我并没有透过树木看到森林,因为它是如何传递参数的。我希望我能做这样的事情:
// Groovy-pseudo code
@ControllerAdvice
class MyAppExceptionMapper extends ResponseEntityExceptionHandler {
ResponseEntity<Object> handleFizzBuzzException(FizzBuzzException fbEx, HttpHeaders headers, HttpStatus status) {
// TODO: How to reset status to 401?
status = ???
new ResponseEntity(fbEx.message, headers, status)
}
ResponseEntity<Object> handleFooBarException(FooBarException fbEx, HttpHeaders headers, HttpStatus status) {
// TODO: How to reset status to 403?
status = ???
new ResponseEntity(fbEx.message, headers, status)
}
ResponseEntity<Object> handleOmgException(OmgException omgEx, HttpHeaders headers, HttpStatus status) {
// TODO: How to reset status to 404?
status = ???
new ResponseEntity(omgEx.message, headers, status)
}
// Now map all Spring-generated exceptions to 422
ResponseEntity<Object> handleAllSpringExceptions(SpringException springEx, HttpHeaders headers, HttpStatus status) {
// TODO: How to reset status to 422?
status = ???
new ResponseEntity(springEx.message, headers, status)
}
// Everything else is a 500...
ResponseEntity<Object> handleAllOtherExceptions(Exception ex, HttpHeaders headers, HttpStatus status) {
// TODO: How to reset status to 500?
status = ???
new ResponseEntity("Whoops, something happened. Lol.", headers, status)
}
}
Run Code Online (Sandbox Code Playgroud)
知道如何完全实现此映射逻辑以及实体是实例MyAppResponse而不仅仅是字符串的要求吗?
那么,我只需要对类进行注释@ControllerAdvice来配置 Spring 使用它吗?
要减少 @bond-java-bond 答案,您不需要ResponseEntity自己构建:
@ResponseStatus每种handleSomeException方法(例如@ResponseStatus(HttpStatus.UNAUTHORIZED))MyAppResponse从这些方法返回自定义但如果每种异常都以相同的方式处理(仅根据 HTTP 状态进行区分),我建议MyAppExceptionMapper像这样减少:
@ControllerAdvice
public class MyAppExceptionMapper {
private final Map<Class<?>, HttpStatus> map;
{
map = new HashMap<>();
map.put(FizzBuzzException.class, HttpStatus.UNAUTHORIZED);
map.put(FooBarException.class, HttpStatus.FORBIDDEN);
map.put(NoSuchRequestHandlingMethodException.class, HttpStatus.UNPROCESSABLE_ENTITY);
/* List Spring specific exceptions here as @bond-java-bond suggested */
map.put(Exception.class, HttpStatus.INTERNAL_SERVER_ERROR);
}
// Handle all exceptions
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseEntity<MyAppResponse> handleException(Exception exception) {
MyAppResponse response = new MyAppResponse();
// Fill response with details
HttpStatus status = map.get(exception.getClass());
if (status == null) {
status = map.get(Exception.class);// By default
}
return new ResponseEntity<>(response, status);
}
}
Run Code Online (Sandbox Code Playgroud)
优点:
此外,您可以将映射配置移到外部并注入它。
如何配置 MVC 调度程序 Servlet
首先,检查mvc-dispatcher-servlet.xml(或contextConfigLocation来自 的另一个web.xml)是否包含:
<context:component-scan base-package="base.package"/>
<mvc:annotation-driven/>
Run Code Online (Sandbox Code Playgroud)
其次,检查@ControllerAdvice注解的类和@Controller注解的类是否都属于base.package.
有关更多详细信息,请参阅Spring MVC 中的异常处理或Spring MVC @ExceptionHandler 示例中的完整示例。
| 归档时间: |
|
| 查看次数: |
2793 次 |
| 最近记录: |