Spirng|Spirng gateway 拦截 response并修改然后返回给客户端
BodyHandlerFunction.java
import org.reactivestreams.Publisher;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import reactor.core.publisher.Mono;
import java.util.function.BiFunction;
public interface BodyHandlerFunction extends
BiFunction, Mono> {
}
BodyHandlerServerHttpResponseDecorator.java
import org.reactivestreams.Publisher;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class BodyHandlerServerHttpResponseDecorator
extends ServerHttpResponseDecorator {/**
* body 处理拦截器
*/
private BodyHandlerFunction bodyHandler = initDefaultBodyHandler();
/**
* 构造函数
*
* @param bodyHandler
* @param delegate
*/
public BodyHandlerServerHttpResponseDecorator(
BodyHandlerFunction bodyHandler, ServerHttpResponse delegate) {
super(delegate);
if (bodyHandler != null) {
this.bodyHandler = bodyHandler;
}
}@Override
public Mono writeWith(Publisher extends DataBuffer> body) {
//body 拦截处理器处理响应
return bodyHandler.apply(getDelegate(), body);
}@Override
public Mono writeAndFlushWith(
Publisher extends Publisher extends DataBuffer>> body) {
return writeWith(Flux.from(body).flatMapSequential(p -> p));
}/**
* 默认body拦截处理器
*
* @return
*/
private BodyHandlerFunction initDefaultBodyHandler() {
return (resp, body) -> resp.writeWith(body);
}
}
ResponseGlobalFilter.java
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.web.server.ServerWebExchange;
import org.synchronoss.cloud.nio.multipart.util.IOUtils;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.io.IOException;
@Configuration
public class ResponseGlobalFilter implements GlobalFilter, Ordered {@Override
public Mono filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
//如果是获取验证码的请求,则跳出
if(exchange.getRequest().getPath().value().contains("captcha")){
return chain.filter(exchange);
}
//构建响应拦截处理器
BodyHandlerFunction bodyHandler = (resp, body) -> Flux.from(body)
.map(dataBuffer -> {
//响应信息转换为字符串
String reqBody = null;
try {
//dataBuffer 转换为String
reqBody = IOUtils
.inputStreamAsString(dataBuffer.asInputStream(), "UTF-8")
.replaceAll(">\\s{1,}<", "><");
System.out.println(reqBody);
} catch (IOException e) {
e.printStackTrace();
}
return reqBody;
})
.flatMap(orgBody -> {
//根据原有的响应信息构建新响应信息并写入到resp中
//此处可以根据业务进行组装新的响应信息,
// 例如:登录后创建会话
//- 拿到登录请求的响应信息,判断登录是否成功
//- 登录成功调用创建会话接口,根据创建会话接口返回组装登录的真实响应
String rbody = orgBody + "";
HttpHeaders headers = resp.getHeaders();
if(headers.get("Access-Control-Allow-Origin")!=null && headers.get("Access-Control-Allow-Origin").size()>1){
String value=https://www.it610.com/article/headers.get("Access-Control-Allow-Origin").get(0);
headers.remove("Access-Control-Allow-Origin");
headers.setAccessControlAllowOrigin(value);
}
if(headers.get("Access-Control-Allow-Credentials")!=null && headers.get("Access-Control-Allow-Credentials").size()>1){
String value=https://www.it610.com/article/headers.get("Access-Control-Allow-Credentials").get(0);
headers.remove("Access-Control-Allow-Credentials");
headers.setAccessControlAllowCredentials(valuehttps://www.it610.com/article/=="true");
}
return resp.writeWith(Flux.just(rbody)
.map(bx -> resp.bufferFactory()
.wrap(bx.getBytes())));
}).then();
//构建响应包装类
BodyHandlerServerHttpResponseDecorator responseDecorator = new BodyHandlerServerHttpResponseDecorator(
bodyHandler, exchange.getResponse());
return chain
.filter(exchange.mutate().response(responseDecorator).build());
}@Override
public int getOrder() {
//WRITE_RESPONSE_FILTER 之前执行
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;
}}
【Spirng|Spirng gateway 拦截 response并修改然后返回给客户端】
推荐阅读
- 微信域名防封|微信域名防封 微信域名拦截检测技术
- Spring|Spring Cloud Gateway真的有那么差吗()
- (三十)java版spring|(三十)java版spring cloud+spring boot+redis多租户社交电子商务平台- gateway限流
- 小说域名怎么才能在微信中正常访问而不被微信拦截(366tool免费提供小说防封方案)
- 解决mybatis拦截器无法注入spring|解决mybatis拦截器无法注入spring bean的问题
- SSM项目使用拦截器实现登录验证功能
- nuxt 路由拦截
- Android|Android 拦截TextView中超链接点击事件
- Layout拦截点击事件
- 系统数据隔离|根据mybatis 拦截器实现项目业务数据隔离