我已经使用@ExceptionHandler了解了基于控制器的异常。
我已经阅读了使用@ControllerAdvice处理全局异常的信息。
我还阅读了有关扩展HandlerExceptionResolver以便更深入地处理异常的信息。
但是,我理想地希望做的是能够在应用程序的任何层上抛出一个全局异常,该异常具有指示返回给客户端的JSON响应的参数。
例如:
throw new CustomGlobalException(HttpStatus.UNAUTHORISED, "This JWT Token is not Authorised.")
throw new CustomGlobalException(HttpStatus.FORBIDDEN, "This JWT Token is not valid.")
然后这将基于我创建的模型以及状态(例如:
)返回JSON响应。{
"success" : "false",
"message" : "This JWT Token is not Authorised."
}
,并将其作为我的控制器的REST响应返回。 这样的事情可能吗?还是我必须按照文档中所述对所有内容进行自定义错误异常处理。
为澄清起见,我需要异常来中断正在进行的进程,也许是从数据库中获取数据,然后立即将给定的异常返回给客户端。我有一个Web MVC设置。
更多详细信息:
@ControllerAdvice
@RequestMapping(produces = "application/json")
public class GlobalExceptionHandler {
@ExceptionHandler(CustomException.class)
public ResponseEntity<Object> handleCustomException(CustomException ex,
WebRequest request) {
Map<String, Object> response = new HashMap<>();
response.put("message", ex.getMessage());
return new ResponseEntity<>(response, ex.getCode());
}
}
在这里引发异常:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain
filterChain) throws ServletException, IOException {
logger.debug("Filtering request for JWT header verification");
try {
String jwt = getJwtFromRequest(request);
logger.debug("JWT Value: {}", jwt);
if (StringUtils.hasText(jwt) && tokenProvider.validateToken(jwt)) {
String username = tokenProvider.getUserIdFromJWT(jwt);
UserDetails userDetails = customUserDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken
(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
} else {
logger.error("No Valid JWT Token Provided");
throw new CustomException(HttpStatus.UNAUTHORIZED, "No Valid JWT Token Provided");
}
} catch (Exception ex) {
logger.error("Could not set user authentication in security context", ex);
}
filterChain.doFilter(request, response);
}
答案 0 :(得分:2)
这并不能完全满足您的期望,但是要做几乎您想要的事情(更干净的IMO)的最简单方法是简单地定义一个异常,如下所示:
$scope.my_array=[];
$scope.my_array.push({"element":1});
var data= [{"element":2},{"element":3}];
$scope.my_array = $scope.my_array.concat(data);
console.log($scope.my_array);
现在,每次从控制器方法(直接或间接)引发此类异常(不返回)时,您都会收到诸如
的响应@ResponseStatus(HttpStatus.UNAUTHORIZED)
public class UnauthorizedException extends RuntimeException {
public UnauthorisedException(String message) {
super(message);
}
}
当然,HTTP响应的实际状态代码也将是401。
您还可以抛出一个{
"timestamp": "2018-06-24T09:38:51.453+0000",
"status": 401,
"error": "Unauthorized",
"message": "This JWT Token is not Authorised.",
"path": "/api/blabla"
}
,它更通用,允许您使用相同的异常类型并将状态作为参数传递。但是我发现它不太干净。
答案 1 :(得分:1)
在我关于如何处理异常here的文章之后,您可以编写自己的处理程序,像这样,
class CustomGlobalException {
String message;
HttpStatus status;
}
@ExceptionHandler(CustomGlobalException.class)
public ResponseEntity<Object> handleCustomException(CustomGlobalException ex,
WebRequest request) {
Map<String, Object> response = new HashMap<>();
response.put("success", "false");
response.put("message", ex.getMessage());
return new ResponseEntity<>(response, ex.getStatus());
}
上面提到的上面的代码将处理发生在任何代码层的 CustomGlobalException 。
答案 2 :(得分:0)
从Spring 5及更高版本开始,ResponseStatusException(提供了spring框架)会更好。 请参阅spring-response-status-exception