sme*_*eeb 10 java proxy spring servlet-filters
我需要将某些HTTP请求重定向到Spring Boot Web应用程序/服务,但是在请求端,Spring应用程序什么都不做,并且充当HTTP客户端(另一个服务)和请求的真实之间的直通目的地.但是当响应回到Spring应用程序(来自该目的地)时,我需要Spring应用程序能够检查响应,并在需要时可能对其采取措施.所以:
基本上,一个过滤器充当请求的传递,并且在远程服务执行并返回响应之后才真正做任何事情.
到目前为止,我最好的尝试是设置一个servlet过滤器:
@Override
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response)
// How and where do I put my code?
if(responseContainsFizz(response)) {
// Send an alert (don't worry about this code)
}
}
Run Code Online (Sandbox Code Playgroud)
这可能吗?如果是这样,我在哪里放置检查和响应的代码?使用我的代码时,我尝试从浏览器访问控制器时会抛出异常:
java.lang.IllegalStateException: STREAM
at org.eclipse.jetty.server.Response.getWriter(Response.java:910) ~[jetty-server-9.2.16.v20160414.jar:9.2.16.v20160414]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_92]
rest of stack trace omitted for brevity
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
小智 5
根据Servlet API文档,您获得该文档的原因IllegalStateException是因为您尝试调用ServletResponse.getWriter之后ServletResponse.getOutputStream已经响应了响应.所以看来你需要调用的方法是ServletResponse.getOutputStream().
但是,如果您尝试访问响应的主体,最佳解决方案是将响应包装在一个ServletResponseWrapper以便您可以捕获数据:
public class MyFilter implements Filter
{
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
}
@Override
public void destroy()
{
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{
MyServletResponseWrapper responseWrapper = new MyServletResponseWrapper((HttpServletResponse) response);
chain.doFilter(request, responseWrapper);
if (evaluateResponse(responseWrapper)) {
// Send an alert
}
}
private boolean evaluateResponse(MyServletResponseWrapper responseWrapper) throws IOException
{
String body = responseWrapper.getResponseBodyAsText();
// Perform business logic on the body text
return true;
}
private static class MyServletResponseWrapper extends HttpServletResponseWrapper
{
private ByteArrayOutputStream copyOutputStream;
private ServletOutputStream wrappedOutputStream;
public MyServletResponseWrapper(HttpServletResponse response)
{
super(response);
}
public String getResponseBodyAsText() throws IOException
{
String encoding = getResponse().getCharacterEncoding();
return copyOutputStream.toString(encoding);
}
@Override
public ServletOutputStream getOutputStream() throws IOException
{
if (wrappedOutputStream == null) {
wrappedOutputStream = getResponse().getOutputStream();
copyOutputStream = new ByteArrayOutputStream();
}
return new ServletOutputStream()
{
@Override
public boolean isReady()
{
return wrappedOutputStream.isReady();
}
@Override
public void setWriteListener(WriteListener listener)
{
wrappedOutputStream.setWriteListener(listener);
}
@Override
public void write(int b) throws IOException
{
wrappedOutputStream.write(b);
copyOutputStream.write(b);
}
@Override
public void close() throws IOException
{
wrappedOutputStream.close();
copyOutputStream.close();
}
};
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1050 次 |
| 最近记录: |