文件上传文件名乱码的解决方法及形成乱码原因

来源:互联网 发布:大数据的存储与处理 编辑:程序博客网 时间:2024/04/30 16:48

              采用Struts2提供的文件下载机制时,如果要下载的文件的的名字是中文的话,就会出现乱码问题。解决办法如下(只截取部分代码):
             UserFavoritesAttachment u = (UserFavoritesAttachment) getSession().get(UserFavoritesAttachment.class,Long.parseLong(fpid));
             String fileName =  u.getFilename();//要提供fileName 的get,set方法,因为我的文件路径及文件名是从数据库中获得,故通过这种方式获得文件名(中文)
              如果直接使用这个fileName的话,就会出现中文乱码,即使你现在把它的值打出来是正确的。因此这里要转码一次,
                              try {
                                             fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
                               } catch (UnsupportedEncodingException e) {
                                           e.printStackTrace();
                               }
            网上有好多地方提到这种转码方式,
                            try {
                                          fileName = new String(fileName.getBytes(),"utf-8");
                            } catch (UnsupportedEncodingException e) {
                                         e.printStackTrace();
                             }
         本人试过这种方式,还是会出现乱码,故建议采用第一种方法,实在不行,两种都试一下,程序重在调试嘛!
         如果用jsp提供的方式下载(原始的,没有封装的),也只需把fileName砖码一次,即
                            try {
                                        fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
                            } catch (UnsupportedEncodingException e) {
                                         e.printStackTrace();
                            }
                            response.setHeader("content-disposition", "attachment;filename=" + fileName);
        如果文件名是从前台视图页面(jsp页面)通过url参数传到action中去的话,jsp页面中就要编码两次,action中解码一次。代码如下:
      jsp页面:
                   function fun(){
                             var name1 = encodeURI("张三");
                             alert(name1);
                             var name2 = encodeURI(name1);
                            alert(name2);
                             window.location.href="encode.action?name="+name2;
                 }
                <a href="javascript:fun()">点击下载</a>

               action代码:
                           private  String  name;
                          public void setName(String name) {
                                            try {
                                                      name=java.net.URLDecoder.decode(name, "utf-8");
                                            } catch (UnsupportedEncodingException e) {

                                                     e.printStackTrace();
                                             }
                                             this.name = name;
                           }
 
 
                          public String getName() {
                                             return name;
                            }
         读者可以debug跟踪一下name,或者输出name,就会发现set方法中的name是正常的。
        为什么要前台页面编码两次,后台代码要解码一次了?因为汉字是不能在url中直接传参过去的,必须要经过编码,js中encodeURI()方法会对汉字进行utf-8编码;首先会找到汉字在utf-8编码在内存中的十六进制格式的表示,并在每个十六进制字节前加上%,“张三”用encodeURI()方法编码一次之后是%D5%C5%C8%FD,用encodeURI()编码第二次以后是%25D5%25C5%25C8%25FD,action获取这个参数的时候已经把传过来的值用iso-8859-1的形式解码了一次,因为tomcat默认的编码方式是iso-8859-1,但服务器的这次解码对于像%25D5%25C5%25C8%25FD这样的数据来说,与手动用utf-8方式解码的效果一样,结果都是%D5%C5%C8%FD(把%25换成了%),然后在手动解码一次,即action代码中的name=java.net.URLDecoder.decode(name, "utf-8"),就变成汉字了。

原创粉丝点击