[英]Spring Boot Rest Controller: Return default Error JSON
Within my API I like to protect the user details endpoints, so that normal logged in users can only access their user profile. 在我的API中,我喜欢保护用户详细信息端点,以便普通登录用户只能访问其用户配置文件。 Therefor I am writing the controller: 因此我正在编写控制器:
@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();
}
In stead of raiseing an Exception which leads to InternalServerExcetption
, I like to return the default spring boot error json, like the following: 而不是引发导致InternalServerExcetption
的异常,我喜欢返回默认的spring引导错误json,如下所示:
{
"timestamp": "2019-05-08T11:42:23.064+0000",
"status": 403,
"error": "Forbidden",
"message": "Access Denied",
"path": "/user/2"
}
I would prefere a solution, which works as well for other Erros like 404. What would be the easiest way to achieve that goal? 我会优先考虑一个解决方案,对于像404这样的其他Erros也是如此。实现这一目标的最简单方法是什么?
You can use below methods for the same 您可以使用以下方法
public class FooController{
//...
@ExceptionHandler({ CustomException1.class, CustomException2.class })
public String handleException() {
return "the intended body";
}
}
Alternatively you can put this logic in as a Global Exceptions Handler using @ControllerAdvice
或者,您可以使用@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);
}
}
After some research I found a solution which looks quite elegant: 经过一番研究后,我找到了一个看起来非常优雅的解
RestController Method looks like that: 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");
}
Addionally I have implemented the class ForbiddenRequestException
: 另外我已经实现了类ForbiddenRequestException
:
@ResponseStatus(value = HttpStatus.FORBIDDEN)
public class ForbiddenRequestException extends RuntimeException {
public ForbiddenRequestException(String message) {
super(message);
}
}
And at least to remove the trace
from the JSON by setting server.error.include-stacktrace=never
in the properties, this might not be ideal, but I think in production you should do this anyway. 至少要通过在属性中设置server.error.include-stacktrace=never
来从JSON中删除trace
,这可能不太理想,但我认为在生产中你应该这样做。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.