[英]Spring Boot Rest Controller: Return default Error JSON
在我的API中,我喜欢保护用户详细信息端点,以便普通登录用户只能访问其用户配置文件。 因此我正在编写控制器:
@RequestMapping(value = URL_USER + "/{id}", method = RequestMethod.GET)
@ResponseBody
public PersistentEntityResource get(PersistentEntityResourceAssembler persistentEntityResourceAssembler, @PathVariable Long id) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
ApplicationUser loggedInUser = applicationUserService.findByUsername(authentication.getName());
ApplicationUser applicationUser = applicationUserService.findById(id);
if (applicationUser.getId().equals(loggedInUser.getId())) {
return persistentEntityResourceAssembler.toFullResource(applicationUser);
}
throw new IllegalAccessException();
}
而不是引发导致InternalServerExcetption
的异常,我喜欢返回默认的spring引导错误json,如下所示:
{
"timestamp": "2019-05-08T11:42:23.064+0000",
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/user/2"
}
我会优先考虑一个解决方案,对于像404这样的其他Erros也是如此。实现这一目标的最简单方法是什么?
您可以使用以下方法
public class FooController{
//...
@ExceptionHandler({ CustomException1.class, CustomException2.class })
public String handleException() {
return "the intended body";
}
}
或者,您可以使用@ControllerAdvice
将此逻辑作为Global Exceptions Handler
@ControllerAdvice
public class RestResponseEntityExceptionHandler
extends ResponseEntityExceptionHandler {
@ExceptionHandler(value
= { IllegalArgumentException.class, IllegalStateException.class })
protected ResponseEntity<Object> handleConflict(
RuntimeException ex, WebRequest request) {
String bodyOfResponse = "This should be application specific";
return handleExceptionInternal(ex, bodyOfResponse,
new HttpHeaders(), HttpStatus.CONFLICT, request);
}
}
经过一番研究后,我找到了一个看起来非常优雅的解
RestController方法如下所示:
@RequestMapping(value = URL_USER + "/{id}", method = RequestMethod.GET)
@ResponseBody
public PersistentEntityResource get(PersistentEntityResourceAssembler persistentEntityResourceAssembler, @PathVariable Long id) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
ApplicationUser loggedInUser = applicationUserService.findByUsername(authentication.getName());
ApplicationUser applicationUser = applicationUserService.findById(id);
if (applicationUser.getId().equals(loggedInUser.getId())) {
return persistentEntityResourceAssembler.toFullResource(applicationUser);
}
throw new ForbiddenRequestException("Access not allowed");
}
另外我已经实现了类ForbiddenRequestException
:
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class ForbiddenRequestException extends RuntimeException {
public ForbiddenRequestException(String message) {
super(message);
}
}
至少要通过在属性中设置server.error.include-stacktrace=never
来从JSON中删除trace
,这可能不太理想,但我认为在生产中你应该这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.