java 需要帮助创建自定义 HttpServletResponse
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4712920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Need help with creating custom HttpServletResponse
提问by andbi
Suddenly stuck on generating custom servlet response. I want to replace servlet response with predefined one:
突然卡在生成自定义 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
//
}
and filter code snipped as follows:
和过滤器代码剪断如下:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//
//
MyCustomResponse customResponse = new MyCustomResponse("Hello world!", (HttpServletResponse) response);
chain.doFilter(request, customResponse);
}
Shame on me, but i'm really stuck on coding this simple task :(
我真丢脸,但我真的坚持编码这个简单的任务:(
Any help would be appreciated.
任何帮助,将不胜感激。
UPDATE:
更新:
All I want is to implement custom response wrapper which, once it's put into filter chain, would always respond with some predefined text. I know how to write custom data from within doFilter() method, but I want MyCustomResponse
to be responsible for that - just instantiate and put in chain. Any well-reasoned responses "You cant do that because..." are also welcome.
我想要的只是实现自定义响应包装器,一旦它被放入过滤器链,就会始终以一些预定义的文本进行响应。我知道如何从 doFilter() 方法中编写自定义数据,但我想MyCustomResponse
对此负责 - 只需实例化并放入链中即可。也欢迎任何合理的回答“你不能这样做,因为......”。
采纳答案by Nayan Wadekar
As quoted in one of your comments :
正如您的评论之一所引用的:
"I want my custom response to return a string in response to getWriter or getOutputStream method invocation"
“我希望我的自定义响应返回一个字符串以响应 getWriter 或 getOutputStream 方法调用”
For that, you have to provide your own implementation for getWriter() & getOutputStream() by overriding them.
为此,您必须通过覆盖它们来为 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;
}
//---
回答by AlexR
I am sorry, but
对不起,但是
- it is not clear what is your problem. You code is written, so? It does not work? what exactly does not work?
- Why do you want to do this? The "right" solution is to pass information as session attribute.
- I do not believe this can work. Really, you do not call directly the next filter in chain. You are kindly asking the app. server to do this. And you are not expected to replace the servlet request/response by your own. Use method explained above (#2)
- 不清楚你的问题是什么。你的代码写好了,所以?这是行不通的?究竟是什么不起作用?
- 你为什么要这样做?“正确”的解决方案是将信息作为会话属性传递。
- 我不相信这行得通。真的,您不会直接调用链中的下一个过滤器。您正在询问该应用程序。服务器来做到这一点。并且您不需要自己替换 servlet 请求/响应。上面解释的使用方法(#2)
回答by JB Nizet
Your response wrapper is useless as is, since it only stores a string in the Java object used to model the actual HTTP response.
您的响应包装器原样是无用的,因为它只在用于建模实际 HTTP 响应的 Java 对象中存储一个字符串。
The actual HTTP response that the client receives is the stream of bytes (resp. characters) sent via the output stream (resp. writer) of the HttpServletResponse object (and the headers, cookies, etc. stored in the HttpServletResponse object). If you want to send a custom output string to the client, just use response.getWriter().print("Hello worlds!").
客户端接收的实际 HTTP 响应是通过 HttpServletResponse 对象(以及存储在 HttpServletResponse 对象中的标头、cookie 等)的输出流(相应的编写器)发送的字节流(相应的字符)。如果您想向客户端发送自定义输出字符串,只需使用 response.getWriter().print("Hello worlds!")。
Passing the response to the rest of the filter chain is questionable, since the rest of the chain will probably want to add its own data to the response stream.
将响应传递给过滤器链的其余部分是有问题的,因为链的其余部分可能希望将自己的数据添加到响应流中。
If you want to hard-code the response to send to the client to your custom output, but be able to still pass the response to the chain and ignore whatever the rest of the chain puts in the response, you could try to add the following to your wrapper :
如果您想硬编码响应以发送到客户端到您的自定义输出,但仍然能够将响应传递给链并忽略链的其余部分放入响应中的任何内容,您可以尝试添加以下内容到您的包装器:
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;
}
回答by Buhake Sindi
I don't see the reason of what you want to do, but if you want to use your wrapper, my suggestion would be:
我没有看到你想要做什么的原因,但如果你想使用你的包装器,我的建议是:
Create your own servlet that uses your wrapper and register it in web.xml
, in something like this:
创建您自己的 servlet,使用您的包装器并将其注册到 中web.xml
,如下所示:
- Extend
javax.servlet.GenericServlet
and override theservice(ServletRequest, ServletResponse)
method. Then you use the Template Method patternto create aservice(ServletRequest, ServletResponseWrapper)
. OR - Extend
javax.servlet.HttpServlet
and overrideservice(HttpServletRequest, HttpServletResponse)
method. Use the Template Method pattern to create aservice(HttpServletRequest, HttpServletResponseWrapper)
. This will require that you don't use thedoGet
,doPost
,doPut
,doTrace
methods already provided byHttpServlet
but, instead create your own that uses your wrapper.
- 扩展
javax.servlet.GenericServlet
和覆盖该service(ServletRequest, ServletResponse)
方法。然后使用模板方法模式创建一个service(ServletRequest, ServletResponseWrapper)
. 或者 - 扩展
javax.servlet.HttpServlet
和覆盖service(HttpServletRequest, HttpServletResponse)
方法。使用模板方法模式创建一个service(HttpServletRequest, HttpServletResponseWrapper)
. 这将要求您不要使用已经提供的doGet
,doPost
,doPut
,doTrace
方法HttpServlet
,而是使用您的包装器创建自己的方法。
Hope this helps.
希望这可以帮助。