请求调度程序在包含之前读取响应

Request Dispatcher read Response before includes

在我的用例中,我必须使用 RequestDispatcher 才能将请求重定向到部署在同一服务器上的另一个 servlet。

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain arg2) throws IOException, ServletException {
   String generateRedirectUrl=FormURL((HttpServletRequest)req);
   ServletContext context = ((HttpServletRequest)req).getSession().getServletContext();
   ServletContext newContext = context.getContext("/myNewContext");
   RequestDispatcher dispatcher = newContext.getRequestDispatcher(generateRedirectUrl);  
   dispatcher.forward(req, resp);          
}

但我必须在发送转发之前读取响应并对其进行一些操作。

可以吗?

如果您创建一个 servletContextListener,您可以使用它来添加一个作为转发请求的一部分运行的新过滤器。然后你可以实现一个 HttpServletResponseWrapper 覆盖 getPrintWriter() 和 getOutputStream() 方法到 return 你自己的对象,它基本上缓冲写入的内容,然后在你调用 doChain() 之前用你的包装器替换响应对象新过滤器。然后在 doChain 的 return 上,您从缓冲区中提取响应数据,按您喜欢的方式处理它,然后使用 PrintWriter 或 OutputStream(其余请求使用的那个)将其写出。我怀疑其余服务将使用 PrintWriter 进行输出,因此这将是您采用的路线。

这里有一个很好的例子说明如何做到这一点(减去 ServletContextListener):

http://www.java2s.com/Tutorial/Java/0400__Servlet/Filterthatusesaresponsewrappertoconvertalloutputtouppercase.htm

此示例将响应转换为大写的地方是您查找需要更改的 json 名称、值对,然后根据需要对其进行修改的地方。

这里是一个合适的 ServletContextListener 的例子。请注意,需要添加侦听器,以便为所有应用程序调用它,不同的服务器实现提供不同的方法来执行此操作:

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

    @WebListener
    public class ServletContextListenerFilter implements ServletContextListener {

        public ServletContextListenerFilter() {}

        @Override
        public void contextDestroyed(ServletContextEvent arg0) {}

        @Override
        public void contextInitialized(ServletContextEvent sce) {
            ServletContext sc = sce.getServletContext();

            if (sc.getServletContextName().equals("Third party rest serice context name")) {
                sc.addFilter("FilterName", filterClass);
            }

        }
    }