在使用全局filter的异常不能通过全局的异常捕获抛出到页面
全局过滤器:
@Component
@Order(-1)
public class AdminFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
RequestPath path = request.getPath();
System.out.println("路径:"+path);
List<String> authorization = request.getHeaders().get("authorization");
if(!CollectionUtils.isEmpty(authorization)){
for (int i = 0; i <authorization.size() ; i++) {
System.out.println("权限:"+authorization.get(i));
if(authorization.get(i).equals("admin")){
return chain.filter(exchange);
}
}
}
throw new BusinessSilentException("没有相对应的权限,请联系相关人员赋权");
}
}
全局异常捕获:
@Slf4j
@RestControllerAdvice
public class GlobalHandler extends BaseHandler {
@ExceptionHandler(value = InvalidFormatException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ApiResult<String> handleJacksonFormatException(InvalidFormatException exception){
log.error(HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase(), exception);
return ApiResult.fail(CommonExceptions.SERVER_ERROR);
}
}
返回结果:
{
"timestamp": "2022-07-29T08:00:39.756+00:00",
"path": "/test/hello",
"status": 500,
"error": "Internal Server Error",
"message": "",
"requestId": "db392e5"
}
我们期望的是将正确的异常信息抛出到页面,但是并未将原因抛出…
原因:全局异常是在经过Controller后捕捉到异常才会抛出 而过滤器在经过controller前发现异常后没有在经过Controller 所以并未捕捉到异常并未通过全局异常捕获往外抛出异常所以需要做的是过滤失败后转向指定的异常Controller 让全局异常捕获
修改后的全局过滤器–增加过滤失败后的路径切换
@Component
@Order(-1)
public class AdminFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
RequestPath path = request.getPath();
System.out.println("路径:"+path);
List<String> authorization = request.getHeaders().get("authorization");
if(!CollectionUtils.isEmpty(authorization)){
for (int i = 0; i <authorization.size() ; i++) {
System.out.println("权限:"+authorization.get(i));
if(authorization.get(i).equals("admin")){
return chain.filter(exchange);
}
}
}
//重新设置转向Controller 将异常抛出
// 全局异常在经过Controller后抛出异常 不经过Controller不会抛出异常
// 所以将路径转向专门的异常抛出Controller
// 通过request/uri会保留原来的path在原来的path后面添加不合理 使用newInstance不是http请求
URI newUri=UriComponentsBuilder.fromHttpUrl("http://192.168.80.24:8888/")
.host("localhost")
.port(8888)
.path("/error")
.queryParam("msg","没有相对应的权限,请联系相关人员赋权").build().toUri();
ServerHttpRequest newRequest = request.mutate().uri(newUri).build();
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, newUri);
return chain.filter(exchange.mutate().request(newRequest).build());
}
}
异常Controller的异常
抛出方法:
@RequestMapping(value = "error")
public ApiResult<String> throwException(String msg){
throw new BusinessSilentException(msg);
}
返回结果:
{
"result": "fail",
"code": 500,
"message": "没有相对应的权限,请联系相关人员赋权",
"data": null
}
通过对判断失败后的路径的切换成功转到异常Controller中成功捕获到异常抛到页面