jsp - 如何在 JSP 文件中编写文件下载以响应

标签 jsp download

当我尝试从响应对象中获取 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/

相关文章:

java - 使用java登录并下载网页并存储cookie

php - YouTube-dl服务器直接文件下载

c# - 下载直接文件

c# - 在 Sharepoint 中下载文件后不再回发

ios - 从 Amazon CDN 到 iOS 设备的频繁下载损坏/不完整的原因是什么?

javascript - 如何在jsp中创建json对象?

java - .NET 使用的 Apache Tomcat JSP 平台最具互操作性的 Web 服务平台

java - Tomcat 和我的 JSP/Servlet 应用程序之间的区别?

java - JSP生成Excel电子表格(XLS)下载

javascript - 将 jsp 列表的第一个元素传递给 javascript