【问题标题】:Multipart post of xlsx get corrupted via HTTPUrlConnectionxlsx 的多部分帖子通过 HTTPUrlConnection 损坏
【发布时间】:2017-05-04 06:29:53
【问题描述】:

我正在尝试通过 HTTPUrlconnection 发布 xlsx 文件,在接收端我得到了该文件,但是在 MS Excel 中打开它时,它说文件已损坏并需要修复。我的多部分帖子的代码 sn-p

class MultipartUtility {
        private  final Logger log = getLogger(MultipartUtility.class.getName());
        private static final String CRLF = "\r\n";
        private static final String CHARSET = "UTF-8";
        private static final int CONNECT_TIMEOUT = 1500000;
        private static final int READ_TIMEOUT = 1000000;
        private final HttpURLConnection connection;
        private final OutputStream outputStream;
        private final PrintWriter writer;
        private final String boundary;
        // for log formatting only
        private final URL url;
        private final long start;

        public MultipartUtility(final String strUrl) throws IOException {
            start = currentTimeMillis();
            URL url  = new URL(strUrl);
            this.url = url;
            boundary = "---------------------------" + currentTimeMillis();
            connection = (HttpURLConnection) url.openConnection();
            connection.setConnectTimeout(CONNECT_TIMEOUT);
            connection.setReadTimeout(READ_TIMEOUT);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept-Charset", CHARSET);
            connection.setRequestProperty("Content-Type","multipart/form-data; boundary=" + boundary);
            connection.setUseCaches(false);
            connection.setDoInput(true);
            connection.setDoOutput(true);
            outputStream = connection.getOutputStream();
            writer = new PrintWriter(new OutputStreamWriter(outputStream, CHARSET),true);
        }
        public void addFilePart(final String  filePath)throws IOException {
            String fieldName = "content";
            File uploadFile = new File(filePath);
            final String fileName = uploadFile.getName();
            writer.append("--").append(boundary).append(CRLF)
                    .append("Content-Disposition: form-data; name=\"")
                    .append(fieldName).append("\"; filename=\"").append(fileName)
                    .append("\"").append(CRLF).append("Content-Type: ")
                    .append(guessContentTypeFromName(fileName)).append(CRLF)
                    .append("Content-Transfer-Encoding: binary").append(CRLF)
                    .append(CRLF);

            writer.flush();
            outputStream.flush();
            try (final FileInputStream inputStream = new FileInputStream(uploadFile);) {
                final byte[] buffer = new byte[4096];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                outputStream.flush();
            }
            writer.append(CRLF);
        }


        public HashMap<Object, Object> finish() throws IOException {
            writer.append(CRLF).append("--").append(boundary).append("--").append(CRLF);
            writer.close();

            final int status = connection.getResponseCode();
            if (status != HTTP_OK) {
                throw new IOException(format("{0} failed with HTTP status: {1}",url, status));
            }
            try (final InputStream is = connection.getInputStream()) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                String sResponse;
                StringBuilder responseBuilder = new StringBuilder();
                while ((sResponse = reader.readLine()) != null) {
                    responseBuilder = responseBuilder.append(sResponse);
                }
                HashMap respMap = new HashMap();
                respMap.put("RESP_MSG", responseBuilder.toString());
                respMap.put("RESP_CODE", status);
                respMap.put("RESP_SIZE", responseBuilder.toString().length());
                log.log(INFO,format("{0} took {4} ms", url,(currentTimeMillis() - start)));
                log.log(INFO,"status::::::"+status);
                return respMap;
            } finally {
                connection.disconnect();
            }
        }
    }

【问题讨论】:

    标签: java httpurlconnection multipartform-data xlsx


    【解决方案1】:

    问题在于您的 addFilePart 方法,最后,您附加了“writer.append(CRLF)” 当文件数为 1 时,您不应该在最后添加它,因为它会为您通过网络发送的文件大小增加额外的 2 位,这会导致您的 xlxs 文件损坏。

    如果你想添加一个文件或多个文件,下面是代码。 在此,我们将 CRLF(用于分隔文件)附加到除最后一个文件之外的所有文件的写入器。

    public void addFilePart(List<String> files) {
        if (nonNull(files) && !files.isEmpty()) {
            AtomicInteger counter = new AtomicInteger(0);
            files.forEach(file -> {
                try {
                    int i = counter.incrementAndGet();
                    this.addFilePart(file); // your add file part method
                    if (files.size() != i) {
                        writer.append(CRLF);
                    }
                    writer.flush();
                } catch (IOException e) {
    
                }
            });
        }
    }
    

    【讨论】:

    • 感谢@divyansh....您的建议帮助我的项目运行良好....不要在文件写入过程结束时添加过多的 CRLF .....
    【解决方案2】:

    我尝试执行您的代码,并且能够成功地从 java 程序上传文件。 您报告的问题是我猜是由于文件的内容类型。如果您尝试上传 .xlsx (MS Excel 2007),它会使数据变形,需要在我们读取上传的文件之前进行恢复。

    如果您尝试上传 .xls 文件,它会正确上传而不会出现任何变形,MS excel 打开此文件时不会出现任何警告/错误。

    所以我建议玩 作家.追加( “内容类型: ” + "应用程序/x-excel")

    要找到正确的内容类型,请参阅: https://www.codeproject.com/Questions/481262/contentplustypeplusforplusxlsxplusfile

    祝你好运

    【讨论】:

    • 您给定的解决方法工作正常。非常感谢。
    猜你喜欢
    • 2019-09-26
    • 2015-10-06
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多