我想使用Zuul来验证,转换和转发从客户端到内部服务的请求。目标是从客户端隐藏遗留API。
我的想法是:客户端将一个带有对象A的JSON表示的POST请求发送到嵌入了Zuul的API网关。 API网关将正文从A转换为LegacyA并将其发送到内部服务。
例如,我搜索一种转换以下JSON的方法:
["hello","world"]
在这个JSON中:
{hashCode("hello"):"hello", hashCode("world"):"world")}
我想使用预过滤器。但我有问题重写有效的请求。
你知道我怎么能这样做吗?
我写过这个过滤器:
public class RestZuulFilter extends ZuulFilter {
private final ObjectMapper objectMapper;
@Autowired
public RestZuulFilter(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 100;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequestWrapper wrapper = new MyWrapper(ctx.getRequest());
ctx.setRequest(wrapper);
return null;
}
class MyWrapper extends HttpServletRequestWrapper {
/**
* Constructs a request object wrapping the given request.
*
* @param request The request to wrap
* @throws IllegalArgumentException if the request is null
*/
public MyWrapper(HttpServletRequest request) {
super(request);
}
@Override
public ServletInputStream getInputStream() throws IOException {
ServletInputStream inputStream = this.getRequest().getInputStream();
List<String> test = objectMapper.readValue(inputStream, new TypeReference<List<String>>() {
});
Map<Integer, String> result = test.stream()
.collect(Collectors.toMap(String::hashCode, str -> str));
byte[] json = objectMapper.writeValueAsBytes(result);
ServletInputStream response = new ServletInputStreamWrapper(json);
return response;
}
}
}
我遇到的问题是Content-Length没有相应更新。
看一下正在转换的请求体的以下示例。我认为这对你有用。
InputStream in = (InputStream) context.get("requestEntity");
if (in == null) {
in = context.getRequest().getInputStream();
}
String body = StreamUtils.copyToString(in, Charset.forName("UTF-8"));
body = body.toUpperCase();
context.set("requestEntity", new ByteArrayInputStream(body.getBytes("UTF-8")));
对于完整的课程: