smartupload 使用 form表单 enctype=“mutipart/form-data“ 上传文件时,中文乱码的问题处理

在jsp页面中,form表单提交既包含表单项,又包含文件的情况下,采用了 enctype=“mutipart/form-data” 的提交类型。servlet中用smartupload进行文件接收,当上传的文件名称是中文的情况下名称会乱码,写此文章记录我自己的处理过程。方便后期查询复用。
首先先大概梳理一下文件上传的基本原理和流程:
1.因为此类的form表单提交的既有文字又有文件,所以采用的是字节流的方式进行的整体的from表单传输。
具体的传参流程参考:
https://blog.csdn.net/yuemei_1991/article/details/77604603
2.后台z在servlet的request中得到了字节流,就是大量的byte数组
SmartUpload核心的解析代码如下:

SmartUpload smartUpload=new SmartUpload();
int initialSize=1024*1024*10;
smartUpload.setMaxFileSize(initialSize);
try{
	smartUpload.initialize(config,request,response);
	smartupload.upload();
}

smartupload.upload();是真正实现上传文件的操作;
通过读流文件,获取到了前台包括文件和表单其他数据的byte数组
m_binArray;
其中有一个方法:
String s1=getDataHeader();
通过截取byte数组,截取出来了消息头对应的byte子数组。
我的环境是windows,当前查看字符的编码是gb2312
举例:我上传的excel文件名称是:我是中文报表。
得到的消息头数组是这样的:

[67,111,110,116,101,110,116,45,68,105,
115,112,111,115,105,116,105,111,110,58,
32,102,111,114,109,45,100,97,116,97,
59,32,110,97,109,101,61,34,102,105,
108,101,110,97,109,101,34,59,32,102,
105,108,101,110,97,109,101,61,34,-50,
-46,-54,-57,-42,-48,-50,-60,-79,-88,-79,-19,46]

(我获取的消息头数据没获取全,但是已经包含了我需要的中文信息了)
对应的字符串是这样的:

Content-Disposition: form-data; name="filename"; filename="我是中文报表.xls"
Content-Type: application/vnd.ms-excel

我上面的byte数组实际显示的只有:
Content-Disposition: form-data; name=“filename”; filename="我是中文报表. 这些。
前面的非中文的字符,直接查看ascii码表就能对上那些字符,其中的中文字符对应的是:

[-50,-46,-54,-57,-42,-48,-50,-60,-79,-88,-79,-19]

发现一共12个byte值,因为gb2312每一个汉字,包含两个字节。所以6个汉字一个是12个字符数

这些字节数组是怎么来的,我简单介绍一下:
1.查询编码表的汉字编码值
2.编码值拆分成两个16进制数
3.转换为二进制
4.最高位是符号位 1代表是负数 0代表是整数
5.去掉补码,求反码
6.结果转换为十进制
比如第一个汉字:
查gb2312编码表,他的编码是0XCED2
0X表示这是16进制数包含两个字节数据
CE D2
十进制 206 210
二进制 11001110 11010010(高位都是1所以两个都是负数)
去掉补码(-1)
11001101 11010001
求反码
00110010 00101110
转换为十进制
2+16+32 2+4+8+32
-50 -46

其他的汉字思路相同。

在getDataHeader()方法中,将byte数组生成字符串,代码里面是这样写的:

String s=new String(m_binArray,i,(j-i)+1);
i 和 (j-i)+1就是在截取消息头对应的字节数组。
这个newString方法并没有指定字符集,说实话,到现在我也没查到,在没有指定字符集的情况下,直接这么写,默认的字符集是什么。反正肯定不是gb2312,这个后期需要深挖一下。
把这句话修改为:
String s=new String(m_binArray,i,(j-i)+1,“gb2312”);

就可以正确的将消息头的中文字符解析出来。

我推测,默认编码应该是英文类的编码,比如iso-8859-1,而字符集的byte数组,是不可能有负值的,这就导致了,乱码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值