1.无脑的实现了一种自己写一个过滤器,修改返回体 此方法需注意fluxBody.buffer().map(dataBuffers -> {})中的buffer方法调用,不然有些返回体会分段传输的。
package com.wukala.gatewayserver.filter;
import cn.wukala.common.commonbase.result.WrapMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import org.reactivestreams.Publisher;
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.DataBufferUtils;
import org.springframework.http.HttpStatus;
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.io.IOException;
import java.util.List;
/**
* 结果封装成固定200格式
*
* @author: zym
*/
@Component
public class WrapperResponseGlobalFilter implements GlobalFilter, Ordered {
@Autowired
ObjectMapper objectMapper;
private static Joiner joiner = Joiner.on("");
@Override
public int getOrder() {
return -2;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpResponseDecorator decoratedResponse = new ServerHttpResponseDecorator(exchange.getResponse()) {
@Override
public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
if (getStatusCode().equals(HttpStatus.OK) && body instanceof Flux) {
Flux<? extends DataBuffer> fluxBody = Flux.from(body);
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
List<String> list = Lists.newArrayList();
dataBuffers.forEach(dataBuffer -> {
byte[] content = new byte[dataBuffer.readableByteCount()];
dataBuffer.read(content);
DataBufferUtils.release(dataBuffer);
try {
list.add(new String(content, "utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
});
String s = joiner.join(list);
try {
if (!WrapMapper.isWrap(s)) {
s = objectMapper.writeValueAsString(WrapMapper.ok(objectMapper.readValue(s, Object.class)));
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(s);
return bufferFactory().wrap(s.getBytes());
}));
}
return super.writeWith(body);
}
};
return chain.filter(exchange.mutate().response(decoratedResponse).build());
}
}
2.官方文档提供的 modifyResponseBody过滤器。比较简洁 (推荐)此方法需要注意过滤器顺序问题 当然取决于你的匹配,modifyResponseBody(...)以及其重载方法我没找到可以自定义的order顺序的方法。
package com.wukala.gatewayserver.config;
import cn.wukala.common.commonbase.result.WrapMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;
import java.io.IOException;
/**
* @Author: zym
* @Description:
* @Date: Created in 2018-12-26
* @Modified By:
*/
@Configuration
public class RotesConfiguration {
@Bean
public RouteLocator routes(RouteLocatorBuilder routeLocatorBuilder, ObjectMapper objectMapper) {
return routeLocatorBuilder.routes()
.route("rewrite_response_upper", r -> r.path("/oauth-server/oauth/token")
.filters(f -> f.rewritePath("/oauth-server", "")
.modifyResponseBody(String.class, String.class,
(exchange, s) -> {
try {
return Mono.just(objectMapper.writeValueAsString(WrapMapper.ok(objectMapper.readValue(s, Object.class))));
} catch (IOException e) {
e.printStackTrace();
}
return Mono.just(s);
})).uri("lb://oauth-server"))
.build();
}
}
用之前还是过一遍官方文档,少走很多弯路。。。
效果如下