当我尝试从响应对象中获取 ServletOutputStream 对象时,出现了 java.lang.IllegalStateException。下面是我的代码:
<%@ page import="java.util.*,java.io.*"%>
<%
try {
System.out.print("request came");
File f = new File ("E:/dd.txt");
String name = f.getName().substring(f.getName().lastIndexOf("/") + 1,f.getName().length());
InputStream in = new FileInputStream(f);
ServletOutputStream outs = response.getOutputStream();
response.setContentType ("application/txt");
response.setHeader ("Content-Disposition", "attachment; filename="+f.getName()+"");
int bit = 256;
int i = 0;
try {
while ((bit) >= 0) {
bit = in.read();
outs.write(bit);
}
} catch (IOException ioe) {
ioe.printStackTrace(System.out);
}
outs.flush();
outs.close();
in.close();
} catch (Exception ioe) {
ioe.printStackTrace(System.out);
}
%>
以下是堆栈跟踪:
java.lang.IllegalStateException
at org.apache.jasper.runtime.ServletResponseWrapperInclude.getOutputStream(ServletResponseWrapperInclude.java:63)
at org.apache.jsp.html.portlet.vitage.custom.QUADWAVE.Procfiledownloadess1_005f36901_005f48.filedownload.downloadscreen_jsp._jspService(downloadscreen_jsp.java:5
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:98)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:331)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
最佳答案
您正在尝试通过 JSP 文件中的某些代码下载文件。 JSP 作为一种 View 技术实际上是错误的工具。外面的一切<% %>
(通常是基于文本的内容,如 HTML、XML、JSON 等)也被写入 HTTP 响应,包括空格。这只会破坏由 Java 代码编写的下载内容的完整性,如果您提供二进制文件(例如文档/音频/视频文件)则更是如此。
您的具体问题是因为 JSP 内部使用了 response.getWriter()
。打印所有模板内容(<% %>
之外的所有内容),然后您尝试使用 getOutputStream()
.这是一个非法的状态。您不能在单个响应中同时使用它们。除了使用 getWriter()
相反,您可以通过删除 <% %>
之外的 any 空格来解决它,包括换行符。
所以,替换
<%@ page import="java.util.*,java.io.*"%>
<%
// Your Java code.
%>
通过
<%@ page import="java.util.*,java.io.*"%><%
// Your Java code.
%>
(并绝对确保在最后一个 %>
之后也没有尾随空格/换行符)
但是,您实际上不应该使用 JSP 来完成这项工作。据说这是错误的工作工具。您应该使用正常的 HTTP servlet class为了工作。只需创建一个扩展类 HttpServlet
并将 JSP 中的所有 Java 代码移动到 doGet()
中方法。最后将该 servlet 映射到 URL 并改为调用该 URL。
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Your Java code.
}
}
您可以在 this article 中找到更具体的示例.
另见:
关于jsp - 如何在 JSP 文件中编写文件下载以响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14109922/