如何通过在多部分帖子中上传文件内容来utf-8编码文件名

时间:2015-04-14 00:13:10

标签: file-upload encoding utf-8 httpurlconnection multipartform-data

上传文件正常工作,除非文件名是双字节。

下面的代码片段显示了进行文件名编码的可能位置,但不确定它是否正确,或者在哪里适用“charset = utf-8”。任何帮助表示赞赏。

    HttpURLConnection connection = null;
    DataOutputStream outputStream = null;
    DataInputStream inputStream = null;

    String urlString = WebApiConstants.getInstance().getBaseURL();
    String lineEnd = "\r\n";
    String twoHyphens = "--";
    String boundary = "--BoundaryStringUsingCurrentTime”+currentTimeMillis();

    int bytesRead, bytesAvailable, bufferSize;
    byte[] buffer;
    try {
      URL url = new URL(urlString);
      connection = (HttpURLConnection) url.openConnection();

      connection.setDoInput(true);
      connection.setDoOutput(true);
      connection.setUseCaches(false);

      connection.setRequestMethod("POST");
      connection.setRequestProperty("Connection", "Keep-Alive");

      List<BasicNameValuePair> headers = getHeaderNameValuePairs();

      for (BasicNameValuePair hdr : headers) {
          connection.setRequestProperty(hdr.getName(), hdr.getValue());
      }

      connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
      outputStream = new DataOutputStream(connection.getOutputStream());
      outputStream.writeBytes(twoHyphens + boundary + lineEnd);

      outputStream.writeBytes("Content-Disposition: form-data; name=\"requests\"" + lineEnd);
      outputStream.writeBytes("Content-Type: application/json" + lineEnd + lineEnd);                       
                outputStream.writeBytes(getJsonDataString(attachment.getMessageId()));
                outputStream.writeBytes(lineEnd + twoHyphens + boundary + lineEnd);

      /* ???
      // could encode the fail name and put in, not sure if it is right? 
      String fileNameUtf8 = URLEncoder.encode(fileName, "UTF-8");
      outputStream.writeBytes("Content-Disposition: form-data; name=\"file0\";filename=\""
                   + fileNameUtf8 + "\"" + lineEnd);

      */

      outputStream.writeBytes("Content-Disposition: form-data; name=\"file0\";filename=\""
                   + fileName + "\"" + lineEnd);

      outputStream.writeBytes("Content-Type: " + mimeType + lineEnd + lineEnd);
      FileInputStream fileInputStream = new FileInputStream(new File(pathToFile));
      bytesAvailable = fileInputStream.available();
      bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
      buffer = new byte[bufferSize];

      bytesRead = fileInputStream.read(buffer, 0, bufferSize);
      while (bytesRead > 0) {
        outputStream.write(buffer, 0, bufferSize);
        bytesAvailable = fileInputStream.available();
        bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
      }

      outputStream.writeBytes(lineEnd);
      outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                … … …
                … … …

1 个答案:

答案 0 :(得分:0)

您可以对文件名进行编码,如下所示:

final private static String hexStr = "0123456789ABCDEF";

private static String MimeEncodeQP(String s)
{
    byte[] bytes = s.getBytes("UTF-8");

    StringBuilder output = new StringBuilder(12 + (bytes.length * 3));
    output.append("=?UTF-8?Q?");

    for ( final byte b : bytes )
    {
        if( b == 32 )
        {
            output.append('_');
        }
        else if( ((b >= 33) && (b <= 60)) ||
                 ((b >= 62) && (b <= 126)) )
        {
            output.append((char) b);
        }
        else
        {
            output.append('=')
                  .append(hexStr.charAt((b & 0xF0) >> 4)
                  .append(hexStr.charAt(b & 0x0F));
        }
    }

    output.append("?=");

    return output.toString();
}

outputStream.writeBytes("Content-Disposition: form-data; name=\"file0\";filename=\"" + MimeEncodeQP(fileName) + "\"" + lineEnd);

阅读以下规范以获取更多详细信息:

RFC 2045 "Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies", Section 67 "Quoted-Printable Content-Transfer-Encoding"

RFC 2047 "MIME (Multipurpose Internet Mail Extensions) Part Three: Message Header Extensions for Non-ASCII Text"

RFC 2388 "Returning Values from Forms: multipart/form-data",第5.4和34条;非ASCII字段名称&#34;。

HTML4, Section 17.13.4.2 "multipart/form-data"

HTML5, Section 4.10.22.7 "Multipart form data"