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<ServerHttpResponse, Publisher<? extends DataBuffer>, Mono<Void>> {
}
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<Void> writeWith(Publisher<? extends DataBuffer> body) {
//body 拦截处理器处理响应
return bodyHandler.apply(getDelegate(), body);
}
@Override
public Mono<Void> 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<Void> 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=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=headers.get("Access-Control-Allow-Credentials").get(0);
headers.remove("Access-Control-Allow-Credentials");
headers.setAccessControlAllowCredentials(value=="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;
}
}
标签:body,Spirng,springframework,gateway,headers,org,import,bodyHandler,response 来源: https://blog.csdn.net/taobong/article/details/100010033