Java 最佳实践 response.getOutputStream

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4300513/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:34:52  来源:igfitidea点击:

best practice response.getOutputStream

javaservlets

提问by cometta

any comments on my code on allowing user to download file.

对我的允许用户下载文件的代码的任何评论。

if(fileObject !=null)
response.setHeader("Content-disposition", "attachment; filename=\""+fileObject.getFilename()+"\"");
response.setContentType(fileObject.getFiletype());
response.setContentLength((int)fileObject.getFilesize().intValue());
try {
 if(response !=null && response.getOutputStream() !=null &&fileObject!=null && fileObject.getBinData() !=null ){
    OutputStream out = response.getOutputStream();
    out.write(fileObject.getBinData());
 }


} catch (IOException e) {
    throw new ApplicationRuntimeException(e);
}

most of the time, i dont get below error. but once and a while, i get error

大多数时候,我不会遇到以下错误。但有时,我会出错

29 Nov 2010 10:50:41,925 WARN [http-2020-2] - Unable to present exception page: getOutputStream() has already been called for this response
java.lang.IllegalStateException: getOutputStream() has already been called for this response
 at org.apache.catalina.connector.Response.getWriter(Response.java:610)

采纳答案by BalusC

The exception message is clear:

异常消息很明确:

Unable to present exception page: getOutputStream() has already been called for this response
java.lang.IllegalStateException: getOutputStream() has already been called for this response
at org.apache.catalina.connector.Response.getWriter(Response.java:610)

无法显示异常页面:已经为此响应调用了
getOutputStream() java.lang.IllegalStateException:已经
在 org.apache.catalina.connector.Response 中为此响应调用了 getOutputStream() 。getWriter(Response.java:610)

An IOExceptionwas been thrown and you're rethrowing it as a custom exception which forced the servletcontainer to show the exception page which will use getWriter()for this. You should in fact let any IOExceptiongo because that's usually a point of no return.

一个IOException被抛出,你将它作为自定义异常重新抛出,这迫使 servletcontainer 显示将getWriter()用于此的异常页面。事实上,你应该IOException放手,因为这通常是一个不归路。

An IOExceptioncan for example be thrown during the job when the client aborted the request. The best practice is to notcatch IOExceptionon the Servlet API yourself. It's already declared in throwsclause of the servlet methods.

一个IOException例如在作业过程中,当客户端中止该请求被抛出。最好的做法是不是IOException在Servlet API的自己。它已经在throwsservlet 方法的子句中声明。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    FileObject fileObject = getItSomehow();
    if (fileObject != null && fileObject.getBinData() != null) {
        response.setHeader("Content-disposition", "attachment; filename=\"" + fileObject.getFilename() + "\"");
        response.setContentType(fileObject.getFiletype());
        response.setContentLength((int)fileObject.getFilesize().intValue());
        response.getOutputStream().write(fileObject.getBinData());
    } else {
        // ???
    }
}

回答by highlycaffeinated

You are calling response.getOutputStream()twice. Instead, call it once and assign it to a local variable, then use that variable for your null check and your writeoperation.

你打了response.getOutputStream()两次电话。相反,调用它一次并将其分配给一个局部变量,然后使用该变量进行空检查和write操作。

try {
 OutputStream out = response.getOutputStream();
 if(response !=null && out !=null &&fileObject!=null && fileObject.getBinData() !=null ){
    out.write(fileObject.getBinData());
 }
} catch (IOException e) {
  throw new ApplicationRuntimeException(e);
}

回答by user207421

How can response be null? Especially after you've already used it? Or response.getOutputStream()? Or fileObject, after you've already tested it for being non-null? And used it? These tests may be doing more harm than good.

响应如何为空?尤其是在你已经使用它之后?还是 response.getOutputStream()?或 fileObject,在您已经测试它为非空之后?并且用过?这些测试可能弊大于利。