0
点赞
收藏
分享

微信扫一扫

sprngboot2.0+shiro+jwt 过滤器中的自定义异常不能被全局异常拦截


情境:

     其他的地方自定义异常的拦截,都是好使的,但是过滤器中的不行,找了两天,才找到问题在这儿

我还想这是为啥呢,真是邪门了

     网上好多说是拦截不了的,然后我找了好久是可以拦截,但是拦截后抛出的是500,并不是自定义异常

不过也可以变相的处理,获取到抛出的自定义异常文字,再一次包装抛出,拦截的方案如下

package com.read.data.bi_statistics.cms.exception;

import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @author: tianyong
* @time: 2019/8/21 10:46
* @description:
*/
@RestControllerAdvice
public class ChainExceptionHandler extends BasicErrorController {


public ChainExceptionHandler() {
super(new DefaultErrorAttributes(), new ErrorProperties());
}


public ChainExceptionHandler(ErrorAttributes errorAttributes, ErrorProperties errorProperties) {
super(errorAttributes, errorProperties);
}


public ChainExceptionHandler(ErrorAttributes errorAttributes, ErrorProperties errorProperties, List<ErrorViewResolver> errorViewResolvers) {
super(errorAttributes, errorProperties, errorViewResolvers);
}



/**
* @author: tianyong
* @time: 2019/8/21 10:46
* @description:处理传过来的异常(解决自定义全局异常捕获不到的问题)
*/
@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);
String code=body.get("status").toString();
String message = body.get("message").toString();
Map<String,Object> map = new HashMap<String,Object>();
map.put("code",code);
map.put("msg",message);
return new ResponseEntity<Map<String, Object>>(map, status);
}

}

     由于我的代码里面有了对于错误状态码,抛出的异常会先走到错误码,之后才会走到拦截的这里,所以

没有采用上面的拦截方案

package com.read.data.bi_statistics.cms.exception;

import com.read.data.bi_statistics.cms.data.enums.CodeInfo;
import com.read.data.bi_statistics.cms.entity.ReturnBone;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import static com.read.data.bi_statistics.authority.utils.JwtUtil.checkChar;
import static com.read.data.bi_statistics.cms.common.Utils.error;

/**
* @author: tianyong
* @Time: 2019/7/15 15:54
* @description:状态码配置类
*/
@Controller
public class StatusCodeExceptionHandler implements ErrorController {


/**
* @author: tianyong
* @time: 2019/7/16 11:36
* @description:指定跳转路径/error
*/
@Override
public String getErrorPath() {
return "/error";
}

/**
* @author: tianyong
* @time: 2019/7/16 11:37
* @description:处理错误状态码
*/
@RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
Exception attribute = (Exception)request.getAttribute("javax.servlet.error.exception");
if(statusCode == 400) {
return "/400";
}else if(statusCode == 401) {
return "/401";
}else if(statusCode == 403) {
return "/403";
}else if(statusCode == 404) {
return "/404";
}else if(statusCode == 405) {
return "/405";
}else if(statusCode == 500) {
//处理全局异常无法捕获过滤器中自定义异常问题
String message = attribute.getCause().getMessage();
if(checkChar(message)){
return "/401";
}else{
return "/500";
}
}else{
return "/500";
}
}


/**
* @author: tianyong
* @time: 2019/7/15 16:14
* @description:400 请求无效
*/
@ResponseBody
@RequestMapping("/400")
public ReturnBone error400 (){
return error(CodeInfo.STATUS_CODE_400);
}


/**
* @author: tianyong
* @time: 2019/8/15 14:16
* @description:401 用户认证失败
*/
@ResponseBody
@RequestMapping("/401")
public ReturnBone error401 (){
return error(CodeInfo.STATUS_CODE_401);
}


/**
* @author: tianyong
* @time: 2019/7/15 16:14
* @description:403 禁止访问
*/
@ResponseBody
@RequestMapping("/403")
public ReturnBone error403 (){
return error(CodeInfo.STATUS_CODE_403);
}


/**
* @author: tianyong
* @time: 2019/7/15 16:14
* @description:404 请求的网页不存在
*/
@ResponseBody
@RequestMapping("/404")
public ReturnBone error404 (){
return error(CodeInfo.STATUS_CODE_404);
}


/**
* @author: tianyong
* @time: 2019/7/15 16:14
* @description:405 资源被禁止
*/
@ResponseBody
@RequestMapping("/405")
public ReturnBone error405 (){
return error(CodeInfo.STATUS_CODE_405);
}


/**
* @author: tianyong
* @time: 2019/7/15 16:14
* @description:500 内部服务器错误,请联系管理员
*/
@ResponseBody
@RequestMapping("/500")
public ReturnBone error500 (){
return error(CodeInfo.STATUS_CODE_500);
}

}

我最后采用的方案是:第一个代码块,里面的500错误里面,我又根据抛出的自定义异常中的文字,区分与普通500异常

然后只要是有文字的都跳转401,没有做具体的区分,但是你们也可以根据具体的文字信息,再进行封装抛出自定义异常

if(authorization == null){
loggers.error("获取token失败!");
throw new AuthenticationException("获取token失败!");
}

或者还有种方式,我见其他的文章有的没有在过滤器中处理,而是在拦截器里面处理的,请求->过滤器->拦截器是这个访问顺序

举报

相关推荐

0 条评论