java – Servlet过滤器“代理”,仅作用于远程端点的响应

前端之家收集整理的这篇文章主要介绍了java – Servlet过滤器“代理”,仅作用于远程端点的响应前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要某些HTTP请求必须重定向Spring Boot Web应用程序/服务,但是在请求方,Spring应用程序什么都不做,也可以作为HTTP客户端(另一个服务)和请求的真实的传递目的地.但是当响应回到Spring应用程序(从目的地)时,我需要Spring应用程序才能检查响应,如果需要的话可以采取措施.所以:

> HTTP客户端提出要求,比如说http://someapi.example.com
>网络魔术将请求传递给我的Spring应用程序,比如http://myproxy.example.com
>根据请求,此应用程序/代理不执行任何操作,因此请求将在http://someapi.example.com转发
> http://someapi.example.com处的服务端点将HTTP响应返回给代理
> http://myproxy.example.com处的代理检查此响应,并可能在将响应返回原始客户端之前发送警报

所以本质上,一个过滤器作为请求上的传递,只有远程服务执行后才能做任何事情并返回响应.

我最好的尝试是设置一个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)
    }
}

这可以做吗如果是这样,我在哪里将代码检查并作出响应?以我的代码为例,当尝试从浏览器中点击控制器时,我会收到异常:

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

有任何想法吗?

解决方法

根据Servlet API文档,您获取IllegalStateException的原因是因为您在ServletResponse.getOutputStream已被调用后尝试调用ServletResponse.getWriter.所以看来你需要调用方法是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,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();
                }
            };
        }
    }
}

猜你在找的Java相关文章