import lombok.extern.slf4j.Slf4j;
import org.reactivestreams.Publisher;
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.HttpMethod;
import org.springframework.http.MediaType;
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.Charset;
@Component
@Slf4j
public class HttpResponseGlobalFilter implements GlobalFilter, Ordered {
@Override
public int getOrder() {
return -2;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest serverHttpRequest = exchange.getRequest();
ServerHttpResponse originalResponse = exchange.getResponse();
String contentType = originalResponse.getHeaders().getFirst("Content-Type");
if(contentType==null||!contentType.equals(MediaType.APPLICATION_JSON_VALUE)){
return chain.filter(exchange);
}
//如果是post请求,将请求体取出来,再写入
HttpMethod method = serverHttpRequest.getMethod();
long contentLength = originalResponse.getHeaders().getContentLength();
//当返回体里面没有任何数据的话不用后面的获取数据步骤
if(contentLength<1){
return chain.filter(exchange);
}
DataBufferFactory bufferFactory = originalResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(originalResponse) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {//解决返回体分段传输
StringBuffer stringBuffer = new StringBuffer();
dataBuffers.forEach(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
try {
stringBuffer.append(new String(content, "utf-8"));
} catch (Exception e) {
log.error("--list.add--error", e);
}
});
String result = stringBuffer.toString();
//TODO,result就是response的值,想修改、查看就随意而为了
String url = serverHttpRequest.getPath().toString();
String urlParams = serverHttpRequest.getQueryParams().toSingleValueMap().toString();
String accessId = "";
if( serverHttpRequest.getHeaders()!=null){
accessId= serverHttpRequest.getHeaders().getFirst("accessId");
}
//log.info("请求长度:" + StringUtils.length(requestBodyStr) + ",返回data长度:" + StringUtils.length(jsonObject.getString("data")));
//log.info("请求地址:【{}】请求参数:GET【{}】|POST:【\n{}\n】,响应数据:【\n{}\n】", url, urlParams, result);
log.info("\n" + "-------------------------------------------------------------------------------->>\n" +
"locationtype: response\n" +
"Url : {}\n" +
"HttpMethod : {}\n" +
"accessId: {}\n" +
"Param : {}\n" +
"\"<<--------------------------------------------------------------------------------"
,url, method, accessId,result);
byte[] uppedContent = new String(result.getBytes(), Charset.forName("UTF-8")).getBytes();
originalResponse.getHeaders().setContentLength(uppedContent.length);
return bufferFactory.wrap(uppedContent);
}));
}
// if body is not a flux. never got there.
return super.writeWith(body);
}
};
// replace response with decorator
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
}