在servlet重定向之前使用过滤器修改响应URL(Java / Tomcat)

时间:2016-08-25 19:32:03

标签: tomcat servlets httpresponse servlet-filters

我正在尝试使用servlet修改servlet filter的响应网址,之前 servlet本身会发布response.sendRedirect。但我无处可去。我首先使用servlet进行测试,然后设置一些虚拟JSP页面来复制servlet的相同基本行为。 servlet来自第三方供应商,无法修改。

我会坚持使用这个问题的JSP页面并假装它们无法修改。如果我可以修改servlet,则无需发布此问题。

我还引用了以下两个主题来帮助我构建过滤器。

Redirecting a request using servlets and the "setHeader" method not working

Looking for an example for inserting content into the response using a servlet filter

servlet / JSP中发生的事情是它加载https然后根据当前网址URL构建一个新的http,附加一个querystring parameter ,cacheid和重新加载页面,即

  1. https://example.com/test/testfilter.jsp
  2. http://example.com/test/testfilter.jsp?cacheid=123456
  3. 我希望它看起来像这样:

    1. https://example.com/test/testfilter.jsp
    2. https://example.com/test/testfilter.jsp?cacheid=123456
    3. 所以我的想法是构建一个截取响应的过滤器,之前 servlet / JSP发出response.sendRedirect,修改位置和状态标题,它应该有效。但它不是很有效。

      testfilter.jsp

      <%
      
      if (request.getParameter("cacheid") == null) {
          response.sendRedirect("http:/example.com/test/testfilter.jsp?cacheid=123456");
      }
      
      %>
      <html>
      <head></head>
      <body>Test</body>
      </html>
      

      过滤

      这是我的doFilter方法:

      public void doFilter(ServletRequest request, ServletResponse response,
              FilterChain chain) throws IOException, ServletException {
          // TODO Auto-generated method stub
          System.out.println("BEFORE filter");
      
          PrintWriter out = response.getWriter();
      
          CharResponseWrapper responseWrapper = new CharResponseWrapper((HttpServletResponse) response);
      
          if ( ((HttpServletRequest)request).getParameter("cacheid") == null ) {
              // Not sure how to append querystring parameter
              responseWrapper.setHeader("location", "https://example.com/test/testfilter.jsp?cacheid=123456");
              responseWrapper.setStatus(HttpServletResponse.SC_FOUND);
          }       
      
          chain.doFilter(request, responseWrapper);
      
          String servletResponse = new String(responseWrapper.toString());
      
          out.write(servletResponse + " filtered"); // Here you can change the response
      
          System.out.println("AFTER filter, original response: " + servletResponse);
      
          if ( ((HttpServletRequest)request).getParameter("cacheid") == null ) {
              // Not sure how to append querystring parameter
              responseWrapper.setHeader("location", "https://example.com/test/testfilter.jsp?cacheid=123456");
              responseWrapper.setStatus(HttpServletResponse.SC_FOUND);
          }  
      }
      

      小问题是我不确定如何在此修改后的响应中附加查询字符串参数,cacheid及其值。

      主要问题是过滤器似乎只在第二次调用testfilter.jsp时调用(使用querystring参数,cacheid)。这是原始响应:

      https://example.com/test/testfilter.jsp

      HTTP/1.1 302 Moved Temporarily
      Content-Length: 0
      Content-Type: text/html;charset=ISO-8859-1
      Location: http://example.com/test/testfilter.jsp?cacheid=123456
      Server: Microsoft-IIS/7.5
      Set-Cookie: JSESSIONID=66ACCD1EFF485CE820BB9E705311C31D; Path=/test; Secure
      Date: Thu, 25 Aug 2016 19:18:54 GMT
      

      http://example.com/test/testfilter.jsp?cacheid=123456

      HTTP/1.1 200 OK
      Content-Length: 60
      Content-Type: text/html;charset=ISO-8859-1
      Server: Microsoft-IIS/7.5
      Set-Cookie: JSESSIONID=1342FB2D65F5568AC7EA1EF21E6FB8E4; Path=/test
      Date: Thu, 25 Aug 2016 19:18:54 GMT
      
      <html>
      <head></head>
      <body>Test</body>
      </html> filtered
      

      如果我可以让第一次过滤器拦截它,在它发送自己的重定向之前,我会被设置。但事情似乎并不那么简单。

      我希望我解释得很清楚,问题是什么。任何帮助将不胜感激。

      谢谢。

1 个答案:

答案 0 :(得分:0)

设置一个Nginx并将这种逻辑移入Nginx指令proxy_redirect是一种解决方法。

相关问题