Eri*_*fer 4 java spring spring-mvc
我将 Spring MVC 与 Spring Boot 和 Thymeleaf 结合使用。我有返回 Thymeleaf 模板名称的普通控制器和用@RepsonseBody.
假设我有一个EntityNotFoundException由控制器调用的某些代码引发的错误。如果抛出它,我想分别返回 404 状态代码和 REST 控制器的错误页面或错误消息。
我当前对普通控制器的设置:
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String message) {
super(message);
}
}
@Controller
public class FooController {
@RequestMapping("/foo") public String foo() {
try {
...
} catch (EntityNotFoundException enfe) {
throw new ResourceNotFoundException(enfe.getMessage());
}
return "foo";
}
}
Run Code Online (Sandbox Code Playgroud)
对于 REST 控制器,我不会捕获异常并让全局异常处理程序拾取它:
@Controller
public class BarController {
@RequestMapping("/bar")
@ResponseBody
public SomeDto bar() throws EntityNotFoundException {
...
return someDto;
}
}
@ControllerAdvice
public class ExceptionHandlerAdvice {
@ExceptionHandler(EntityNotFoundException.class)
public final ResponseEntity<Object> handleEntityNotFoundExceptionEntityNotFoundException enfe) {
return new ResponseEntity<>(enfe.getMessage, HttpStatus.NOT_FOUND);
}
}
Run Code Online (Sandbox Code Playgroud)
我也不想在我的普通控制器中捕获并重新抛出。全局处理程序应该同时处理:
@ExceptionHandler(EntityNotFoundException.class)
public final Object handleEntityNotFoundException(EntityNotFoundException enfe) {
if (/* is REST controller? */) {
return new ResponseEntity<>(enfe.getMessage(), HttpStatus.NOT_FOUND);
} else {
Map<String, Object> model = ImmutableMap.of("message", enfe.getMessage());
return new ModelAndView("error", model, HttpStatus.NOT_FOUND);
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法确定异常来自哪里,即控制器是否用@ResponseBody类似的东西进行注释?
我找到了解决方案。您可以将当前控制器方法作为HandlerMethod参数注入。
@ExceptionHandler(EntityNotFoundException.class)
public final Object handleEntityNotFoundException(EntityNotFoundException enfe, HandlerMethod handlerMethod) {
boolean isRestController = handlerMethod.hasMethodAnnotation(ResponseBody.class)
|| handlerMethod.getBeanType().isAnnotationPresent(ResponseBody.class)
|| handlerMethod.getBeanType().isAnnotationPresent(RestController.class);
if (isRestController) {
return new ResponseEntity<>(enfe.getMessage(), HttpStatus.NOT_FOUND);
} else {
Map<String, Object> model = ImmutableMap.of("message", enfe.getMessage());
return new ModelAndView("error", model, HttpStatus.NOT_FOUND);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2800 次 |
| 最近记录: |