为什么在我的FileServlet上抛出Write Failed异常 [英] Why it throws Write Failed exceptions on my FileServlet

查看:72
本文介绍了为什么在我的FileServlet上抛出Write Failed异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Web实例,该实例使用文件servlet提供具有动态名称的下载.我当前的文件名为A.apk,我可以将下载文件命名为A_username.apk.到目前为止一切都还可以.但是,即使文件下载过程成功,它也会引发异常.

I have a web instance which gives downloads with dynamic names by using a file servlet. My current file name is A.apk, I can give the download as A_username.apk. Everything is OK up to now. However, It always throws exceptions even the file download process is successed.

我的代码:

public class FileServlet extends HttpServlet {


private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
private String filePath;


public void init() throws ServletException {
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) {
   String tag = "" + request.getParameter("tag");
    String name = "MyApp";
    try {
        String requestedFile = request.getPathInfo();
         this.filePath = "C:/WEBROOT/Test/build/web/andrapp";

        // Check if file is actually supplied to the request URI.
        if (requestedFile == null) {
            // Do your thing if the file is not supplied to the request URI.
            // Throw an exception, or send 404, or show default/warning page, or just ignore it.
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

        // Decode the file name (might contain spaces and on) and prepare file object.
        File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));

        // Check if file actually exists in filesystem.
        if (!file.exists()) {
            // Do your thing if the file appears to be non-existing.
            // Throw an exception, or send 404, or show default/warning page, or just ignore it.
            response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
            return;
        }

        // Get content type by filename.
        String contentType = getServletContext().getMimeType(file.getName());

        // If content type is unknown, then set the default value.
        // For all content types, see: http://www.w3schools.com/media/media_mimeref.asp
        // To add new content types, add new mime-mapping entry in web.xml.
        if (contentType == null) {
            contentType = "application/octet-stream";
        }

        // Init servlet response.
        response.reset();
        response.setBufferSize(DEFAULT_BUFFER_SIZE);
        response.setContentType(contentType);
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "attachment; filename=\"" + name + ".apk" + "\"");

        // Prepare streams.
        BufferedInputStream input = null;
        BufferedOutputStream output = null;

        try {
            // Open streams.
            input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
            output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

            // Write file contents to response.
            byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
            int length;
            while ((length = input.read(buffer)) > 0) {
                output.write(buffer, 0, length);
            }
            System.out.println("Download Success");
        } finally {
            // Gently close streams.
            close(output);
            close(input);
        }
    } catch (Exception ex) {
        System.out.println("Download Cancelled");
        ex.printStackTrace();

    }
}
// Helpers (can be refactored to public utility class) ----------------------------------------
private static void close(Closeable resource) {
    if (resource != null) {
        try {
            resource.close();
        } catch (IOException e) {
            // Do your thing with the exception. Print it, log it or mail it.
            e.printStackTrace();
        }
    }
}
}

如果下载正常,则输出下载成功"和下载已取消".如果我取消下载,则只会输出下载已取消".

If the download is OK, it outputs "Download Success" and "Download Cancelled" both. If I cancel the download, it outputs only "Download Cancelled".

异常日志:

    CORE3282: stdout: Download Cancelled 
    CORE3283: stderr: java.io.IOException: WEB8001: Write failed
    CORE3283: stderr: at com.iplanet.ias.web.connector.nsapi.NSAPIConnector.write(NSAPIConnector.java:789)
    CORE3283: stderr: at com.iplanet.ias.web.connector.nsapi.NSAPIResponseStream.write(NSAPIResponseStream.java:75)
    CORE3283: stderr: at org.apache.catalina.connector.ResponseBase.flushBuffer(ResponseBase.java:824)
    CORE3283: stderr: at org.apache.catalina.connector.HttpResponseBase.flushBuffer(HttpResponseBase.java:794)
    CORE3283: stderr: at com.iplanet.ias.web.connector.nsapi.NSAPIResponse.flushBuffer(NSAPIResponse.java:127)
    CORE3283: stderr: at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:788)
    CORE3283: stderr: at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:361)
    CORE3283: stderr: at java.io.BufferedOutputStream.write(BufferedOutputStream.java:122)
    CORE3283: stderr: at com.newwap.developer.tools.FileServlet.doGet(FileServlet.java:120)
    CORE3283: stderr: at javax.servlet.http.HttpServlet.service(HttpServlet.java:787)
    CORE3283: stderr: at javax.servlet.http.HttpServlet.service(HttpServlet.java:908)
    CORE3283: stderr: at org.apache.catalina.core.StandardWrapperValve.invokeServletService(StandardWrapperValve.java:771)
    CORE3283: stderr: at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:322)
    CORE3283: stderr: at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:509)
    CORE3283: stderr: at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:218)
    CORE3283: stderr: at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:509)
    CORE3283: stderr: at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:209)
    CORE3283: stderr: at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:509)
    CORE3283: stderr: at com.iplanet.ias.web.connector.nsapi.NSAPIProcessor.process(NSAPIProcessor.java:157)
    CORE3283: stderr: at com.iplanet.ias.web.WebContainer.service(WebContainer.java:579)
    CORE3282: stdout: Download Success

它表示该行:output.write(buffer,0,length);

It indicates exaclty the line : output.write(buffer, 0, length);

有什么主意吗?

推荐答案

我建议尝试另一种解决方案:).

I would suggest a different solution to try :).

编写如下所示的私有方法,该方法将文件内容返回为bytes

Write a private method like below which returns the file content as bytes

private byte[] getApkAsBytes(String apkPath)
        throws FileNotFoundException, IOException {
    File apkFile = new File(apkPath);
    byte[] binaryAPKFile = new byte[(int) apkFile.length()];

    FileInputStream fileInputStream = new FileInputStream(apkFile);
    // convert file into array of bytes
    fileInputStream.read(binaryAPKFile);
    fileInputStream.close();
    return binaryAPKFile;
}

然后像下面那样简单地调用,而不是使用BufferedOutputStream并关闭它.

then simply call like below instead of using BufferedOutputStream and closing it.

byte[] apkBytes = getApkAsBytes();
String bytesAsString = JSON.encode(apkBytes);
response.getWriter().write(bytesAsString);

import org.apache.commons.codec.binary.Base64;
public final class JSON {
private JSON() {}
public static byte[] decode(String s) {
    return Base64.decodeBase64(s);
}
public static String encode(byte[] bytes) {
    return Base64.encodeBase64String(bytes);
}
}

在这种情况下,JSON是util类,用于将byte[]编码为String以及从String编码为byte[]

In this case JSON is util class for encode byte[] to String and also from String to byte[]

这篇关于为什么在我的FileServlet上抛出Write Failed异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆