SmartUpload 的乱码处理

最近用到SmartUpload 来上传文件。SmartUpload对文件的上传和下载虽然很方便,但其对中文支持不足。所以经常会出现乱码的问题,瞬间崩溃的感觉。

本人现在用 SmartUpload 的上传部分,姑且只解决上传出现的乱码问题,下载部分可自行研究。

大家都知道,Java读取文件的方式总体可以分为两类:按字节读取和按字符读取。其实字符流可以看做是一种包装流,它的底层还是采用字节流来读取字节。那么Java按字节读取文件主要用InputStream.read() 方法来读取。这个方法并不能设置读取的编码方式,因为从输入流里读取的字节编码取决于被读取的文件自身的编码。

既然读文件要使用和文件编码一致的编码,那Eclipse是怎么读取Java文件的呢?

经过baidu后发现:

① javac在控制台编译java类文件时默认采用了操作系统默认的GBK编码解码文件,当然使用javacencoding参数来制定我们的解码编码,如下::javac -encoding UTF-8 Demo.java

② Eclipse中编译java文件时,Eclipse会自动识别了我们java源文件的文件编码,然后采取了正确的encoding参数来编译我们的java源文件。

 

言归正传,SmartUpload 在什么情况下会出现乱码,为什么会出现乱码。以下分几种情况细说:

为解决 SmartUpload的各种乱码,我利用反编译工具查看 SmartUpload.jar 包里的二进制文件,以方便修改SmartUpload 的源代码。假设我的项目,jsp.....都是UTF-8的编码方式。

1. 当使用 SmartUpload 上传文件时且文件名含有中文时会出现乱码,但是这并不影响我们上传文件,因为我们上传到服务器之后的文件名一般都是我们自己取的,和客户端的文件名没有半毛钱关系,所以这个乱码问题我也是到最后才发现,当我们在 SmartUpload 类的getDataHeader() 方法中将返回结果打印出来,上传专卖店.png的图片时,会输出“Content-Disposition: form-data;name="image"; filename="涓撳崠搴?png"可以看出文件文发生了乱码。发生乱码的原因是 jsp文件采用的是 UTF-8的编码方式,为SmartUpload 的 m_response CharacterEncodingISO-8859-1。当我们在生成返回值字符串是为其指定编码方式为 UTF-8 时就不会出现乱码,即str = new String(this.m_binArray, i, j - i + 1,"UTF-8")。这时打印的是:“Content-Disposition: form-data; name="image";filename="专卖店.png"”。

2. 当使用 SmartUpload上传文件时,在form 表单里有一个text input时,text的值含有中文字符,在后台利用smartUpload.getRequest().getParameter("name")时也会出现乱码。这个问题比上个问题更纠结,因为查看源码之后发现jspSmartUpload RequestCharacterEncoding编码方式都是UTF-8,这样就无从下手了。当然也想过其他办法,最容易相到的就是处理乱码字符串,使其变得不是乱码,所以本人写了一个静态方法(StringUtils. toUTF8ByGBK)将乱码的字符串转换成UTF-8编码的字符串,发现暂时能解决问题。后来才发现没有问题只是巧合。例如:

<span style="white-space:pre">	</span>String test = "oppo专卖";

	System.out.println(test);

	System.out.println(test.length());

	Strings = new String(test.getBytes(), "GBK");

	Stringstr = toUTF8ByGBK(s);

	System.out.println(str);

	System.out.println(str.length());

结果:

oppo专卖

6

oppo专卖

6

--------------------------------------------------

But

<span style="white-space:pre">	</span>String test = "oppo专卖店";
<span style="white-space:pre">	</span>System.out.println(test);
<span style="white-space:pre">	</span>System.out.println(test.length());
<span style="white-space:pre">	</span>Strings = new String(test.getBytes(), "GBK");
<span style="white-space:pre">	</span>Stringstr = toUTF8ByGBK(s);
<span style="white-space:pre">	</span>System.out.println(str);
<span style="white-space:pre">	</span>System.out.println(str.length());

结果:

    oppo专卖店

7

oppo专卖?

8

第二种情况连个编码不一样的字符串的长度都不一样,查资料发现是因为:GBK编码是一个中文2个字节,而UTF-8编码是一个中文3个字节。这个问题在刚开始的时候也说过。

这个简单粗暴的方法还是不能解决问题,那么就要另辟蹊径了。最容易想到的就是放弃SmartUpload,改用commons-fileupload 。本人用过一次commons-fileupload 。后台处理相当麻烦,代码一大推。虽然可以解决这个乱码问题,但是秉着少写代码的原则(在后期会多次需要上传文件),所以继续修改SmartUpload 的源代码。经过多次debug 后知道问题出现在SmartUpload load() 里。在 load()方法中当表单遍历到不是文件的时候会 执行this.m_formRequest.putParameter(str2,(String)localObject)。这行代码就是把表单里面text 的参数通过键值对的方式放到SmartUploadRequestHashtable里面。在这里就出现了乱码。追究上面代码,即localObject 是怎么来的,localObject = new String(this.m_binArray, this.m_startData, this.m_endData- this.m_startData + 1);纠结到这里大家应该知道问题出现在哪了。 在new localObject的时候采用的默认编码方式和我们jsp Servlet的编码方式不一样,这里只需要改某一个使其一样就OK了。

3. 当使用 SmartUpload下载文件时,当文件名含有中文时也会出现乱码。同样修改源代码可以很方便的解决问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值