解决resteasy上传表单文件名乱码
Dubbo在2.6版本后合并了dubbox的resteasy代码后,可以支持rest风格的接口发布,但是在使用form表单上传文件的时候,获取的文件名称是乱码。
下面通过对源码分析一下原因,并提供一种可行的解决方法。
首先是一个resteasy上传的使用代码
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Override
public Object uploadfile(MultipartFormDataInput input, @Context HttpServletRequest request, @Context HttpServletResponse response) {
System.out.println("进入业务逻辑");
// MultipartFormDataReader
Map<String, Object> map = null; Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
//取得文件表单名
List<InputPart> inputParts = uploadForm.get("file"); final String DIRCTORY = "D:/temp/datainput/";
initDirectory(DIRCTORY);
InputStream inputStream = null;
OutputStream outStream = null;
for (InputPart inputPart : inputParts) {
try {
// 文件名称
String fileName = getFileName(inputPart.getHeaders());
inputStream = inputPart.getBody(InputStream.class, null);
//把文件流保存;
File file = new File(DIRCTORY + fileName);
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
outStream = new FileOutputStream(file);
outStream.write(buffer);
} catch (IOException e) {
e.printStackTrace();
}finally {
if(null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
}
}
if(null != outStream){
try {
outStream.close();
} catch (IOException e) {
}
}
} } return Response.ok().build();
}
resteasy文件上传使用的Consumes使用的mediattype类型是MULTIPART_FORM_DATE【@Consumes(MediaType.MULTIPART_FORM_DATA)】
这个mediatype使用的Provider使用的是org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataReader,其readForm的入口为
public MultipartFormDataInput readFrom(Class<MultipartFormDataInput> type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException, WebApplicationException
{ String boundary = mediaType.getParameters().get("boundary");
if (boundary == null) throw new IOException(Messages.MESSAGES.unableToGetBoundary());
MultipartFormDataInputImpl input = new MultipartFormDataInputImpl(mediaType, workers);
input.parse(entityStream);
return input;
}
在跟入上面代码的parse方法 input.parse(entityStream)中的new BinaryMessage()构造函数中,MultipartInputImpl对http的head进行了解析
private static class BinaryMessage extends Message
{
private BinaryMessage(InputStream is) throws IOException, MimeIOException
{
try {
MimeStreamParser parser = new MimeStreamParser(null); StorageProvider storageProvider;
if (System.getProperty(DefaultStorageProvider.DEFAULT_STORAGE_PROVIDER_PROPERTY) != null) {
storageProvider = DefaultStorageProvider.getInstance();
} else {
StorageProvider backend = new CustomTempFileStorageProvider();
storageProvider = new ThresholdStorageProvider(backend, 1024);
}
parser.setContentHandler(new BinaryOnlyMessageBuilder(this, storageProvider));
parser.parse(is); // 此处未解析代码,未传入指定的字符串编码方式
} catch (MimeException e) {
throw new MimeIOException(e);
} }
}
在行 parser.parse(is);中,采用的是apache-mime4j-1.6版本的流解析器,由于MultipartInputImpl在调用apache-mime4j的解析方法,没有可指定字符编码的方法,此处编码的设置传递会丢失。(PS:MultipartInputImpl中的defaultPartCharset,可以通过拦截器request.setAttribute(InputPart.DEFAULT_CHARSET_PROPERTY, ENCODING_UTF_8);进行指定)。
后续未指定字符编码的调用链中,apache-mime4j对上传内容的解析采用了默认的ASCII编码进行处理,对应RawField.parseBody()
private String parseBody() {
int offset = colonIdx + 1;
int length = raw.length() - offset;
return ContentUtil.decode(raw, offset, length);
}
该decode方法中使用的是写死的ASCII编码进行处理
public static String decode(ByteSequence byteSequence, int offset,
int length) {
return decode(CharsetUtil.US_ASCII, byteSequence, offset, length);
}
所以看到这里,就了解了为什么文件名称会是乱码的了,大概也知道其他地方通过拦截器设置编码格式解决不了文件名称乱码的问题了。
所以可行的解决方法可以是(亲测可用),将apache-mime4j-1.6的源码导入工程中,并且修改ContentUtil的decode方法,如下:

public static String decode(ByteSequence byteSequence, int offset,
int length) {
return decode(CharsetUtil.UTF_8 //修改此处默认编码
, byteSequence, offset, length);
}
这种方法不好的点就是冗余了一份开源代码到自己项目中,并且项目包路径会比较奇怪。当然也可以编译一份修改后的代码放到自己公司的nexus库中。
解决resteasy上传表单文件名乱码的更多相关文章
- 【Flask】 结合wtforms的文件上传表单
表单中的文件上传 基本的表单渲染,表单类设置等等就不多说了,参看另一个文章即可.但是那篇文章里没有提到对于FileField,也就是上传文件的表单字段是如何处理,后端又是如何实现接受上传过来的文件的. ...
- ajax上传表单的俩种方式
1.用h5对象上传表单(图片) var formData = new FormData(); formData.append("authenticity_token", '1212 ...
- 上传漏洞科普[1]-文件上传表单是Web安全主要威胁
为了让最终用户将文件上传到您的网站,就像是给危及您的服务器的恶意用户打开了另一扇门.即便如此,在今天的现代互联网的Web应用程序,它是一种 常见的要求,因为它有助于提高您的业务效率.在Facebook ...
- bootstrap上传表单的时候上传的数据默认是0 一定要小心
bootstrap上传表单的时候上传的数据默认是0 一定要小心
- php上传中文文件文件名乱码问题
php上传文件是最最基础的一个技术点,但是深入进去也有不少问题需要解决,这不,上传中文文件后,文件名变成了乱码. 下面是问题代码,很简单: 1.问题代码 html部分: <html> &l ...
- php上传文件中文文件名乱码的解决方法
文件上传是我们在处理表单提交时候最常用的功能之一,今天写了一个小小的demo,如下: 先看结构: html为表单提交的页面,php为处理表单的文件,upload为上传文件所放的位置 html: < ...
- 解决swfupload上传控件文件名中文乱码问题 三种方法 flash及最新版本11.8.800.168
目前比较流行的是使用SWFUpload控件,这个控件的详细介绍可以参见官网http://demo.swfupload.org/v220/index.htm 在使用这个控件批量上传文件时发现中文文件名都 ...
- 使用ajax上传表单(带文件)
在使用form表单的时候上传文件+表单,会使得页面跳转,而在某些时候不希望跳转,只变化页面中的局部信息 通过查找资料,可以使用FormData进行ajax操作. FormData介绍:XMLHttpR ...
- 原生js封装ajax:传json,str,excel文件上传表单提交
由于项目中需要在提交ajax前设置header信息,jquery的ajax实现不了,我们自己封装几个常用的ajax方法. jQuery的ajax普通封装 var ajaxFn = function(u ...
随机推荐
- Ubuntu Java环境变量配置
# java homeJAVA_HOME=/usr/local/jdk/jdk1.8.0_121JRE_HOME=JAVA_HOME/jreCLASSPATH=.:$JAVA_HOME/lib:$JR ...
- 搭建基于Nagios的监控系统——之监控远程Windows服务器
分享了如何监控Linux服务器,我们来看看使用Nagios如何监控Windows服务器. 第一部分:配置被监控的Windows服务器 首先,访问 http://sourceforge.net/pr ...
- lwip 移植
一.源码目录结构 api . core.netif. include core下又有IPV4 . IPV6 . SNMP 和.c文件 include下又有IPV4.IPV6.LWIP.netif ne ...
- JavaEE 企业级分布式高级架构师课程
总目录: 第一课(2018.7.10) 01 mybatis框架整体概况(2018.7.10)-
- 分类---Logistic Regression
一 概述 Logistic Regression的三个步骤 现在对为什么不使用均方误差进行分析(步骤二的) 由上图可以看出,当距离目标很远时,均方误差移动速率也很慢,不容易得到好的结果. Discri ...
- unity coroutine
http://gad.qq.com/article/detail/695 使用Unity 3D引擎的同学,对于Coroutine(协程)的使用肯定也是非常熟悉的了.然而Coroutine背后的技术以及 ...
- Python学习笔记(随机数)
random模块的作用是产生随机数. import random num = random.randint(1,100) random.randint(a, b)可以生成一个a到b间的随机整数,包括a ...
- Oracle树查询总结
最近在做公司的项目中遇到一个问题,多级级联导航菜单,虽然只有三级目录,但<li>中嵌套<ul>,数据库表结构如下: CREATE TABLE FLFL ( ID NUMBER ...
- jsp学习与提高(三)——JSP Cookie 处理
1.cookie是什么 Cookie是存储在客户机的文本文件,它们保存了大量轨迹信息.在servlet技术基础上,JSP显然能够提供对HTTP cookie的支持. 通常有三个步骤来识别回头客: 服务 ...
- 怎么解决java.lang.NoClassDefFoundError错误
http://blog.csdn.net/jamesjxin/article/details/46606307