主要实现,当通过接口请求数据时,先从redis里面查询数据,如果redis里面有数据则直接返回,果如没有数据则请求接口获取数据(我这里redis的key是url,主要是测试用)
参考地址:
https://blog.csdn.net/qq_35387940/article/details/119753044
package com.gateway.filter;
import com.alibaba.fastjson.JSONObject;
import com.gateway.config.BaseConfig;
import com.gateway.utils.RedisUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Throwables;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.server.reactive.ServerHttpRequest;
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.StandardCharsets;
import java.util.List;
import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR;
/**
* 网关跳转过滤类
*
* @Author: hans
* @Date: 2020/05/23
*/
@Component
public class SkipFilter implements GlobalFilter, Ordered {
private static Logger log = LoggerFactory.getLogger(SkipFilter.class);
private static Joiner joiner = Joiner.on("");
@Autowired
private BaseConfig baseConfig;
@Autowired
private RedisUtil redisUtil;
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse originalResponse = exchange.getResponse();
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
String url = request.getURI().getPath();
String data = getDataFromRedis(url);
if(data != null){
ServerHttpResponse resp = exchange.getResponse();
resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
System.out.println("data: " + data);
DataBuffer buffer = resp.bufferFactory().wrap(data.getBytes(StandardCharsets.UTF_8));
return resp.writeWith(Flux.just(buffer));
}
System.out.println("url: " + url);
ServerHttpResponseDecorator response = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
// 获取ContentType,判断是否返回JSON格式数据
String originalResponseContentType = exchange.getAttribute(ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);
if (StringUtils.isNotBlank(originalResponseContentType) && originalResponseContentType.contains("application/json")) {
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);
setDataToRedis(url, responseData);
byte[] uppedContent = new String(responseData.getBytes(), StandardCharsets.UTF_8).getBytes();
originalResponse.getHeaders().setContentLength(uppedContent.length);
return bufferFactory.wrap(uppedContent);
}));
}
}
return super.writeWith(body);
}
@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());
}
private String getDataFromRedis(String key){
Object o = redisUtil.get(key);
if(o== null){
return null;
}
return o.toString();
}
private void setDataToRedis(String key, String data){
redisUtil.set(key, data, baseConfig.getRedisTimeOut());
}
@Override
public int getOrder() {
return -999;
}
/**
* 认证错误输出
*
* @param resp 响应对象
* @param mess 错误信息
* @return
*/
private Mono<Void> authError(ServerHttpResponse resp, String mess) {
resp.setStatusCode(HttpStatus.UNAUTHORIZED);
resp.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", mess);
String returnStr = jsonObject.toJSONString();
DataBuffer buffer = resp.bufferFactory().wrap(returnStr.getBytes(StandardCharsets.UTF_8));
return resp.writeWith(Flux.just(buffer));
}
}
浙公网安备 33010602011771号