使用httpClient上传文件,文件名是中文,需要设置http为兼容模式,否则会使用mime默认的编码(US-ASCII),中文文件名就乱码了,源码分析如下。
HttpBrowserCompatibleMultipart
浏览器兼容模式 (设置的charset)(UTF-8),文件名正常
编码过程如下:
private static void writeBytes(
final String s, final Charset charset, final OutputStream out) throws IOException {
final ByteArrayBuffer b = encode(charset, s);
writeBytes(b, out);
}
protected static void writeField(
final MinimalField field, final Charset charset, final OutputStream out) throws IOException {
writeBytes(field.getName(), charset, out);
writeBytes(FIELD_SEP, out);
writeBytes(field.getBody(), charset, out);
writeBytes(CR_LF, out);
}
结果:
--mFDXEYYXySUoUuFmPQ2yjojbK0_qgR8Z4V
Content-Disposition: form-data; name="uploadFile2"; filename="中文.mp4"
Content-Type: video/mp4
HttpStrictMultipart
浏览器严格模式 MIME.DEFAULT_CHARSET (US-ASCII),文件名乱码了
编码过程如下:
private static void writeBytes(
final String s, final OutputStream out) throws IOException {
final ByteArrayBuffer b = encode(MIME.DEFAULT_CHARSET, s); // US-ASCII
writeBytes(b, out);
}
protected static void writeField(
final MinimalField field, final OutputStream out) throws IOException {
writeBytes(field.getName(), out);
writeBytes(FIELD_SEP, out);
writeBytes(field.getBody(), out);
writeBytes(CR_LF, out);
}
结果
--k8ni5k102LlgW3Ez5ktsImNa3lMr5tB8FPe_e
Content-Disposition: form-data; name="uploadFile2"; filename="??.mp4"
Content-Type: video/mp4
Content-Transfer-Encoding: binary
设置方法:
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setCharset(Charset.forName("UTF-8"));
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);