Java 用JSP上传Word文档

Java 用JSP上传Word文档,java,jsp,Java,Jsp,我目前正在使用的程序允许用户浏览服务器上的文件,然后下载它们。对于下载,我编写了一个JSP将内容上传到客户端。它被传递文件名,然后发回其内容。我下面的代码目前对文本文件非常有效,但是当我尝试下载并打开一个word文档(据我所知是一个二进制文件)时,我从MS word获得一些文本、一些奇怪的方块和一条错误消息。我不确定它为什么错误地读取二进制数据。任何帮助都将不胜感激 <%@ page import="java.io.*" %> <% final File AP

我目前正在使用的程序允许用户浏览服务器上的文件,然后下载它们。对于下载,我编写了一个JSP将内容上传到客户端。它被传递文件名,然后发回其内容。我下面的代码目前对文本文件非常有效,但是当我尝试下载并打开一个word文档(据我所知是一个二进制文件)时,我从MS word获得一些文本、一些奇怪的方块和一条错误消息。我不确定它为什么错误地读取二进制数据。任何帮助都将不胜感激

    <%@ page import="java.io.*" %>

<%
    final File APP_ROOT = new File(com.mdi.core.config.ProcessConfiguration.getInstance().getStringValue("APP_ROOT"));
    File f = new File(request.getParameter("path"));

    File parent = f;
    boolean valid = false;
    while(!valid && (parent = parent.getParentFile()) != null)
    {
        valid = parent.equals(APP_ROOT);
    }
    if(!valid)
    {
        response.sendError(403, "You can not download this file!");
        return;
    }

    response.addHeader("Content-Disposition","attachment; filename="+f.getName());

    response.setContentLength((int)f.length());
    OutputStream os = response.getOutputStream();
    response.setContentType(java.net.URLConnection.guessContentTypeFromName(f.getName()));
    InputStream fin = null;
    try
    {
        fin = new FileInputStream(f);
        byte[] buff = new byte[512];
        int read;
        while((read = fin.read(buff)) != -1)
            os.write(buff, 0, read);
    }
    catch(Exception ex)
    {
        ex.printStackTrace();
    }
    finally
    {
        if(fin != null) fin.close();
    }       
%>

我在标准输出中也得到了这个错误

java.net.ProtocolException: Exceeded stated content-length of: '40220' bytes
    at weblogic.servlet.internal.ServletOutputStreamImpl.checkCL(ServletOutputStreamImpl.java:200)
    at weblogic.servlet.internal.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:146)
    at jsp_servlet._mdi._html._file_upload.__default_file_upload._jspService(__default_file_upload.java:101)
    at weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
    at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
    at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
    at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
    at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at com.mdi.core.utils.http.SecurityFilter.doFilter(SecurityFilter.java:154)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at com.mdi.core.utils.http.ResponseHeaderFilter.doFilter(ResponseHeaderFilter.java:69)
    at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.wrapRun(WebAppServletContext.java:3715)
    at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3681)
    at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
    at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
    at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
    at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:178)
<Jun 27, 2014 10:46:07 AM EDT> <Error> <HTTP> <BEA-101083> <Connection failure.
java.net.ProtocolException: Didn't meet stated Content-Length, wrote: '39942' bytes instead of stated: '40220' bytes.
    at weblogic.servlet.internal.ServletOutputStreamImpl.ensureContentLength(ServletOutputStreamImpl.java:446)
    at weblogic.servlet.internal.ServletResponseImpl.ensureContentLength(ServletResponseImpl.java:1432)
    at weblogic.servlet.internal.ServletResponseImpl.send(ServletResponseImpl.java:1511)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1462)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
    Truncated. see log file for complete stacktrace
> 
<Jun 27, 2014 10:46:07 AM EDT> <Error> <HTTP> <BEA-101104> <Servlet execution in servlet context "ServletContext@1188950474[app:Trade module:TA15 path:/TA15 spec-version:null]" failed, java.net.ProtocolException: Didn't meet stated Content-Length, wrote: '39942' bytes instead of stated: '40220' bytes..
java.net.ProtocolException: Didn't meet stated Content-Length, wrote: '39942' bytes instead of stated: '40220' bytes.
    at weblogic.servlet.internal.ServletOutputStreamImpl.ensureContentLength(ServletOutputStreamImpl.java:446)
    at weblogic.servlet.internal.ServletResponseImpl.ensureContentLength(ServletResponseImpl.java:1432)
    at weblogic.servlet.internal.ServletResponseImpl.send(ServletResponseImpl.java:1511)
    at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1462)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
    Truncated. see log file for complete stacktrace
java.net.ProtocolException:超出了声明的内容长度:“40220”字节
位于weblogic.servlet.internal.ServletOutputStreamImpl.checkCL(ServletOutputStreamImpl.java:200)
位于weblogic.servlet.internal.ServletOutputStreamImpl.write(ServletOutputStreamImpl.java:146)
在jsp\u servlet.\u mdi.\u html.\u file\u upload.\u default\u file\u upload.\u jsp服务(\u default\u file\u upload.java:101)
位于weblogic.servlet.jsp.JspBase.service(JspBase.java:34)
位于weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
位于weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
位于weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:300)
位于weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
位于weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
位于com.mdi.core.utils.http.SecurityFilter.doFilter(SecurityFilter.java:154)
位于weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
位于com.mdi.core.utils.http.ResponseHeaderFilter.doFilter(ResponseHeaderFilter.java:69)
位于weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:56)
位于weblogic.servlet.internal.WebAppServletContext$servleinvocationAction.wrapRun(WebAppServletContext.java:3715)
在weblogic.servlet.internal.WebAppServletContext$servleinvocationAction.run(WebAppServletContext.java:3681)
位于weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
位于weblogic.security.service.SecurityManager.runAs(SecurityManager.java:120)
位于weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2277)
位于weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:2183)
位于weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1454)
在weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
在weblogic.work.ExecuteThread.run(ExecuteThread.java:178)

非常重要的是删除JSP自己的空白输出:

<%@ page contentType="application/octet" import="java.io.*" %><%
%>

最后一行没有空格,也没有换行符。 提示:使用servlet

不知何故,仍然需要执行
os.flush()


在@BoristheSpide的评论之后:忘记法拉盛吧。我认为这些空格造成了一些问题,将内容类型添加为二进制数据。

没有什么比JSP中的大量代码块更让人眼花缭乱的了。JSP用于模板化。Java文件用于业务逻辑。您的问题100%是由于字符编码,因为我在整个块中没有看到一个显式编码。但是,如果我只是尝试上载二进制数据,为什么字符编码很重要?那么我应该如何解决这个问题?我应该使用什么类型的字符编码?您的根本问题是您使用的是JSP。JSP将直接写入HTTP响应流,它被设计为服务于HTML。当然,您可以对JSP进行黑客攻击,并在JSP发送任何内容之前尝试通过流获取输出,但这种方法从根本上是有缺陷的。JSP中的任何空白或其他内容都会破坏正在发送的任何数据。是的,很奇怪,我第一次甚至编写了
os.close()
。问题被写入:
'39942'字节,而不是声明的'40220'字节。
-缺少字节!