主要实现,当通过接口请求数据时,先从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)); } }