需要有关创建自定义HttpServletResponse的帮助

时间:2011-01-17 12:02:35

标签: java servlets servlet-filters

突然停留在生成自定义servlet响应上。我想用预定义的替换servlet响应:

public class MyCustomResponse extends HttpServletResponseWrapper {
  private String customOutput;
  public MyCustomResponse(String customOutput, HttpServletResponse response) {
    super(response);
    // PrintWriter and Outputstream should stream this variable as output
    this.customOutput = customOutput;
  }

  //
  // Below I need to override something
  //
}

和过滤器代码剪切如下:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  //
  //
  MyCustomResponse customResponse = new MyCustomResponse("Hello world!", (HttpServletResponse) response);
  chain.doFilter(request, customResponse);
}

对我感到羞耻,但我真的坚持编码这个简单的任务:(

任何帮助都将不胜感激。

更新

我想要的只是实现自定义响应包装器,一旦放入过滤器链,它总是会响应一些预定义的文本。我知道如何从doFilter()方法中编写自定义数据,但我希望MyCustomResponse对此负责 - 只需实例化并放入链中。任何有充分理由的回答“你不能这样做因为......”也是受欢迎的。

4 个答案:

答案 0 :(得分:2)

正如你的一条评论所引述:

  

“我希望我的自定义响应返回a   字符串响应getWriter或   getOutputStream方法调用“

为此,您必须为getWriter()&提供自己的实现。 getOutputStream()通过覆盖它们。

//---

    private PrintWriter printWriter = null;
    private ServletOutputStream outputStream = null;

    public PrintWriter getWriter( ) throws IOException {

        if (this.outputStream != null) {
            throw new IllegalStateException(
                    "Cannot call getWriter( ) after getOutputStream( )");
        }

        if (this.printWriter == null) {
            // initialize printWriter
        }
        return this.printWriter;
    }

    public ServletOutputStream getOutputStream( ) throws IOException {

        if (this.printWriter != null) {
            throw new IllegalStateException(
                "Cannot call getOutputStream( ) after getWriter( )");
        }

        if (this.outputStream == null) {
            // initialize outputStream
        }
        return this.outputStream;
    }

//---

答案 1 :(得分:1)

对不起,但是

  1. 目前尚不清楚你的意思是什么 问题。您的代码是写的吗?它 不起作用?究竟什么不起作用?
  2. 你为什么要这样做? “正确”的解决方案是将信息作为会话属性传递。
  3. 我不相信这可行。真的,你不直接调用链中的下一个过滤器。你好心地问这个应用程序。服务器这样做。并且您不应该自己替换servlet请求/响应。使用上述方法(#2)

答案 2 :(得分:1)

您的响应包装器没有用,因为它只在用于建模实际HTTP响应的Java对象中存储一个字符串。

客户端收到的实际HTTP响应是通过HttpServletResponse对象的输出流(resp.writer)发送的字节流(resp。字符)(以及存储在HttpServletResponse对象中的头文件,cookie等) 。 如果要将自定义输出字符串发送到客户端,只需使用response.getWriter()。print(“Hello worlds!”)。

将响应传递给过滤器链的其余部分是有问题的,因为链的其余部分可能希望将自己的数据添加到响应流中。

如果您想要将响应硬编码发送到客户端到您的自定义输出,但仍然能够将响应传递给链并忽略链中其余部分放入响应,您可以尝试将以下内容添加到您的包装器中:

private ServletOutputStream fakeOutputStream = 
    new ServletOutputStream() {

        @Override
        public void write(int b) throws IOException {
            // do nothing. Everything written to this stream is ignored
        }
    }

private PrintWriter fakeWriter = new PrintWriter(fakeOutputStream);

public MyCustomResponse(String customOutput, HttpServletResponse response) {
    super(response);
    response.getWriter().print(customOutput);
}

@Override
public ServletOutputStream getOutputStream() {
    return fakeOutputStream;
}

@Override
public PrintWriter getWriter() {
    return fakeWriter;
}

答案 3 :(得分:0)

我没有看到你想做什么的原因,但如果你想使用你的包装,我的建议是:

使用您的包装器创建自己的servlet并在web.xml中注册它,如下所示:

  • 扩展javax.servlet.GenericServlet并覆盖service(ServletRequest, ServletResponse)方法。然后,您使用Template Method pattern创建service(ServletRequest, ServletResponseWrapper)。 OR
  • 扩展javax.servlet.HttpServlet并覆盖service(HttpServletRequest, HttpServletResponse)方法。使用模板方法模式创建service(HttpServletRequest, HttpServletResponseWrapper)。这将要求您不要使用doGet已经提供的doPostdoPutdoTraceHttpServlet方法,而是创建自己使用的方法你的包装。

希望这有帮助。