首先,网关为什么要定义全局异常处理类,因为网关默认抛出异常后,返回给前端是html页面的错误提示,现在我们的系统都是前后端分离,要求响应的数据都是json格式的,所以我们要将网关中的异常,响应给前端是以json类型返回。
我们可以自定义异常类,然后在这个全局异常处理中,捕获处理响应httpstatus状态码。
package com.atlml.configs;
import com.atlml.exceptions.IllegalTokenException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.reactive.error.ErrorWebExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class GlobalExceptionConfiguration implements ErrorWebExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionConfiguration.class);
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
Map<String, String> result = new HashMap<>();
ServerHttpResponse response = exchange.getResponse();
if (response.isCommitted()) {
return Mono.error(ex);
}
response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
if (ex instanceof IllegalTokenException) {
response.setStatusCode(HttpStatus.FORBIDDEN);
} else {
response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
}
return response
.writeWith(Mono.fromSupplier(() -> {
DataBufferFactory bufferFactory = response.bufferFactory();
result.put("msg", ex.getMessage());
ObjectMapper objectMapper = new ObjectMapper();
try {
return bufferFactory.wrap(objectMapper.writeValueAsBytes(result));
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
}));
}
}