如前面的文章所述,controller中抛出的异常我们使用ControllerAdvice来处理:
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public AjaxResponse handler(Exception e){
AjaxResponse r = new AjaxResponse();
if (e instanceof RuntimeException){
RuntimeException selectNoFindException = (RuntimeException) e;
r.setStatus(-1);
r.setMsg(selectNoFindException.getMessage());
} else {
r.setStatus(-1);
r.setMsg("系统错误");
}
log.error(e.getMessage());
return r;
}
/**
* 捕获自定义异常
* @param e
* @return
*/
@ExceptionHandler(value = FriendlyException.class)
public Map<String,Object> errorHandle(FriendlyException e){
Map<String,Object> map = new HashMap<String,Object>();
map.put("code",e.getCode());
map.put("msg",e.getMsg());
return map;
}
}
但是filter中抛出的异常上面的方法就为无能为力了,如登录的认证,和权限的判断,我们可以使用如下的处理方法:
定义一个controller 继承BasicErrorController,并重写error方法。
@RestController
@Api(value = "handle filter throws exception", description = "处理filter抛出的异常")
public class ErrorController extends BasicErrorController {
public ErrorController() {
super(new DefaultErrorAttributes(), new ErrorProperties());
}
@Override
@RequestMapping(produces = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL));
HttpStatus status = getStatus(request);
Map<String,Object> map = new HashMap<String,Object>();
map.put("code",body.get("status"));
map.put("msg",body.get("message"));
return new ResponseEntity<Map<String, Object>>(map, status);
}
}
看下request中的信息:
看一下body中的信息:
接下来就可以filter中抛出异常,errorcontroller就可以捕获了:
以下是shiro中认证失败时方法onAccessDenied:
protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception {
HttpServletResponse httpResponse = WebUtils.toHttp(servletResponse);
httpResponse.setCharacterEncoding("UTF-8");
httpResponse.setContentType("application/json;charset=UTF-8");
httpResponse.setStatus(HttpStatus.SC_NON_AUTHORITATIVE_INFORMATION);
fillCorsHeader(WebUtils.toHttp(servletRequest), httpResponse);
throw new AuthenticationException("token认证失败");
//return false;
}
以下是权限判断时,权限不足时抛出的异常在isAccessAllowed方法中。
protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object mappedValue) throws Exception {
Subject subject = getSubject(servletRequest, servletResponse);
String[] rolesArray = (String[]) mappedValue;
//没有角色限制,有权限访问
if (rolesArray == null || rolesArray.length == 0) {
return true;
}
for (String role : rolesArray) {
//若当前用户是rolesArray中的任何一个,则有权限访问
if (subject.hasRole(role)) {
return true;
}
}
throw new AuthorizationException("没有权限访问此资源");
}
这里isAccessAllowed和onAccessDenied应该在哪个方法抛出异常呢,我没有考虑太多,都试了一下,有机会时再研究一下
|