项目需要处理网络请求异常 404 等异常,可以通过自定义全局过滤器来处理响应结果。还可以对相应结果进行二次封装,修改内容响应最新修改过的内容。
自定义全局过滤器:
- 实现 GlobalFilter 接口
- 实现 Ordered 接口,可以自定义过滤器顺序
添加自定义全局过滤器类
import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import com.tigerkin.util.ApiResult;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.nio.charset.Charset;
import java.util.List;
/**
* @ClassName CustomGlobalFilter
* @Description 自定义全局过滤器
* @Author tigerkin
* @Date 2022/3/14 17:03
*/
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
private final Logger log = LoggerFactory.getLogger(this.getClass());
private static Joiner joiner = Joiner.on("");
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("========> 请求进入全局过滤器");
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator response = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (!(body instanceof Flux)) {
return super.writeWith(body);
}
HttpStatus statusCode = getStatusCode();
if (statusCode.equals(HttpStatus.OK)) {
// return readAndWrite(body); // 读取响应结果,可以对响应结果做二次处理再返回
return super.writeWith(body); // 直接返回响应结果
} else { // 对非正常状态码的请求,封装统一响应信息,不弹出错误页面
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
ApiResult result;
if (statusCode.equals(HttpStatus.NOT_FOUND)) {
result = ApiResult.error(HttpStatus.NOT_FOUND, "访问服务资源不存在");
} else {
result = ApiResult.error(statusCode, statusCode.name());
}
String resultJson = JSON.toJSONString(result);
byte[] uppedContent = new String(resultJson.getBytes(), Charset.forName("UTF-8")).getBytes();
originalResponse.setStatusCode(HttpStatus.OK); // 设置状态码
originalResponse.getHeaders().setContentLength(uppedContent.length); // 设置内容长度
originalResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON); // 设置内容类型
return bufferFactory.wrap(uppedContent);
}));
}
}
/**
* 读取和写入Response响应内容
* @param body
* @return
*/
private Mono<Void> readAndWrite(Publisher<? extends DataBuffer> body) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
List<String> list = Lists.newArrayList();
dataBuffers.forEach(dataBuffer -> {
try {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
list.add(new String(content, "UTF-8"));
} catch (Exception e) {
log.info("加载Response字节流异常,失败原因:{}", Throwables.getStackTraceAsString(e));
}
});
String responseData = joiner.join(list);
System.out.println("responseData:" + responseData);
byte[] uppedContent = new String(responseData.getBytes(), Charset.forName("UTF-8")).getBytes();
originalResponse.getHeaders().setContentLength(uppedContent.length);
originalResponse.getHeaders().setContentType(MediaType.APPLICATION_JSON);
return bufferFactory.wrap(uppedContent);
}));
}
@Override
public Mono<Void> writeAndFlushWith(Publisher<? extends Publisher<? extends DataBuffer>> body) {
return writeWith(Flux.from(body).flatMapSequential(p -> p));
}
};
return chain.filter(exchange.mutate().response(response).build());
}
/**
* 定义全局过滤器顺序
*
* @return
*/
@Override
public int getOrder() {
return -1;
}
}