httpclient调用三方文件上传接口中文乱码

commons-httpclient-3.0.1.jar
类:org.apache.commons.httpclient.methods.multipart.FilePart

获取文件名方法:
protected void sendDispositionHeader(OutputStream out)
throws IOException {
LOG.trace("enter sendDispositionHeader(OutputStream out)");
super.sendDispositionHeader(out);
String filename = this.source.getFileName();
if (filename != null) {
out.write(FILE_NAME_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtil.getAsciiBytes(filename));//这里中文肯定乱码
out.write(QUOTE_BYTES);
}
}

类:org.apache.commons.httpclient.methods.multipart.Part
...
protected void sendDispositionHeader(OutputStream out) throws IOException {
LOG.trace("enter sendDispositionHeader(OutputStream out)");
out.write(CONTENT_DISPOSITION_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtil.getAsciiBytes(getName()));//同上
out.write(QUOTE_BYTES);
}

如上所示,文件名不进行特殊处理,则官方默认使用Ascii编码,对英文以外的编码是个挑战,
所以需重写sendDispositionHeader方法,且不继承父类实现,方可实现中文文件名的正常上传,如下:

@Override
protected void sendDispositionHeader(OutputStream out) throws IOException {
// 实现基类Part方法
out.write(CONTENT_DISPOSITION_BYTES);
out.write(QUOTE_BYTES);
out.write(EncodingUtil.getBytes(getName(), "gbk"));//OK,通过
out.write(QUOTE_BYTES);
// 实现父类FilePart方法
String fileName = getSource().getFileName();
if (fileName != null) {
out.write(EncodingUtil.getAsciiBytes(FILE_NAME));
out.write(QUOTE_BYTES);
out.write(EncodingUtil.getBytes(fileName, "gbk"));//OK,通过
out.write(QUOTE_BYTES);
}

以上为3.0.1版本的操作,故寻至新版4.3.1,该头部实现已经修改,且无编码区别,官方实现如下:
protected void generateContentDisp(ContentBody body) {
StringBuilder buffer = new StringBuilder();
buffer.append("form-data; name=\"");
buffer.append(getName());
buffer.append("\"");
if (body.getFilename() != null) {
buffer.append("; filename=\"");
buffer.append(body.getFilename());
buffer.append("\"");
}
addField("Content-Disposition", buffer.toString());
}
故建议旧版切换即可

转自:https://blog.csdn.net/dongfengpo25/article/details/84517217

你可能感兴趣的:(Spring,Boot)