使用 Zuul 处理 GET Body
Processing GET Body with Zuul
我正在使用 Zuul 代理一个奇怪的客户端,该客户端发送 body 作为 GET 请求的一部分。不幸的是,我无法更改客户端。
使用 curl 这样的请求可以发送为:
curl -XGET 'localhost:8765/kibana/index.html' -d' {"key": "value"}'
而数据真正在body发送。然而,在 zuul 方面,当我尝试读取 body 时,它是空的。这是我的原型 zuul 代码:
@Configuration
@ComponentScan
@EnableAutoConfiguration
@Controller
@EnableZuulProxy
public class ZuulServerApplication {
@Bean
public ZuulFilter myFilter() {
return new ZuulFilter(){
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request=(HttpServletRequest)ctx.getRequest();
try {
InputStream is=request.getInputStream();
String content=IOUtils.toString(is);
System.out.println("Request content:"+content);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 10;
}
@Override
public String filterType() {
return "pre";
}};
}
public static void main(String[] args) {
new SpringApplicationBuilder(ZuulServerApplication.class).web(true).run(args);
}
}
如果我发送 POST 请求,此代码会毫无问题地打印请求 body。但是,如果我发送上述 GET 请求,则不会打印 body。我可以做些什么来实际将 body 作为 GET 请求的一部分发送?
似乎有一些底层机制[0],例如一些具有较小过滤器顺序的内置 Zuul 过滤器,将默认 "raw" HttpServletRequest
替换为 HttpServletRequestWrapper
,在标准情况下(即不是 GET
方法与主体),能够处理输入流的多次获取。但是在 GET
方法的情况下,主体 HttpServletRequestWrapper
似乎根本 不是 代理输入流。
因此解决方案可能是更改 filterOrder
例如至 -10
.
然后它适用于过滤器,因为使用了 HttpServletRequest
- 提到的机器没有轮到它,因此还没有用 HttpServletRequestWrapper
替换 HttpServletRequest
。但是这个解决方案的潜在问题是过滤器可能会耗尽输入流用于其他东西,例如具有更高过滤器阶数的过滤器。但是由于 GET
with body 无论如何都不是一个好的做法,毕竟它可能是一个足够好的解决方案:)
[0] 我很久以前就对此进行过调试,但没有达到确切的程度 - 因此 "the machinery".
的定义很模糊
我正在使用 Zuul 代理一个奇怪的客户端,该客户端发送 body 作为 GET 请求的一部分。不幸的是,我无法更改客户端。
使用 curl 这样的请求可以发送为:
curl -XGET 'localhost:8765/kibana/index.html' -d' {"key": "value"}'
而数据真正在body发送。然而,在 zuul 方面,当我尝试读取 body 时,它是空的。这是我的原型 zuul 代码:
@Configuration
@ComponentScan
@EnableAutoConfiguration
@Controller
@EnableZuulProxy
public class ZuulServerApplication {
@Bean
public ZuulFilter myFilter() {
return new ZuulFilter(){
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request=(HttpServletRequest)ctx.getRequest();
try {
InputStream is=request.getInputStream();
String content=IOUtils.toString(is);
System.out.println("Request content:"+content);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 10;
}
@Override
public String filterType() {
return "pre";
}};
}
public static void main(String[] args) {
new SpringApplicationBuilder(ZuulServerApplication.class).web(true).run(args);
}
}
如果我发送 POST 请求,此代码会毫无问题地打印请求 body。但是,如果我发送上述 GET 请求,则不会打印 body。我可以做些什么来实际将 body 作为 GET 请求的一部分发送?
似乎有一些底层机制[0],例如一些具有较小过滤器顺序的内置 Zuul 过滤器,将默认 "raw" HttpServletRequest
替换为 HttpServletRequestWrapper
,在标准情况下(即不是 GET
方法与主体),能够处理输入流的多次获取。但是在 GET
方法的情况下,主体 HttpServletRequestWrapper
似乎根本 不是 代理输入流。
因此解决方案可能是更改 filterOrder
例如至 -10
.
然后它适用于过滤器,因为使用了 HttpServletRequest
- 提到的机器没有轮到它,因此还没有用 HttpServletRequestWrapper
替换 HttpServletRequest
。但是这个解决方案的潜在问题是过滤器可能会耗尽输入流用于其他东西,例如具有更高过滤器阶数的过滤器。但是由于 GET
with body 无论如何都不是一个好的做法,毕竟它可能是一个足够好的解决方案:)
[0] 我很久以前就对此进行过调试,但没有达到确切的程度 - 因此 "the machinery".
的定义很模糊