博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
<a>标签文件下载文件名乱码问题
阅读量:4928 次
发布时间:2019-06-11

本文共 2945 字,大约阅读时间需要 9 分钟。

近期项目中用到了extjs的上传控件上传文件,然后页面使用a标签直接调用后台action获取流进行下载。在本地tomcat下是没有什么问题的,但是当放到测试环境jboss下的时候却遇到了文件名乱码的问题。以下为关键代码:

application/octet-stream
fileStream
attachment;filename="${fileUpdateFileName}"
public InputStream getInputStream(String id){        if ("".equals(id) || id == null) {            log.warn("id is null");            throw new FileStorageException(FileStorageException.COMMON_FILE_IDISBLANK);        }        FileEntity res = fileStorageDao.get(id);        if(res == null) {            log.warn("get file is null");            throw new FileStorageException(FileStorageException.COMMON_FILE_GETFILEISBLANK);        }        byte[] sfile = res.getSerializedFile();        //根据ID获取文件        InputStream fis = new ByteArrayInputStream(sfile);        return fis;    }
/*页面中用标签进行下载*/var url = "../kminfo/downloadFile.action?kmInfoVO.fileUpdateId=" + annex + "&&kmInfoVO.fileUpdateFileName=" + annexName;var uploadAttachmentForm = infoEditWindow.down('form').down('form').getForm().findField('fileUpdateNameDisp').setValue(""+annexName+"");

当点击a标签之后,文件名称和文件id会被传到后台,后台根据文件id去查找文件,然后放入流中,struts2中的配置了下载的文件名,它会去调用getFileUpdateFileName()方法去取的文件名,然后再返回到前台。

因为是通过a标签传的中文,在到达后台的时候已经被解码成了不知道什么编码,试着在后台get方法中对文件进行转换:

new String(fileUpdateFileName.getBytes("UTF-8"),"ISO-8859-1");

本地可行,但是jboss下还是乱码。试了很多的方法都没办法解决这个问题,最后决定在前台就对中文名进行转码,然后到后台去解码。

/*页面中用标签进行下载*/var url = "../kminfo/downloadFile.action?kmInfoVO.fileUpdateId=" + annex + "&&kmInfoVO.fileUpdateFileName=" + encodeURI(encodeURI(annexName));var uploadAttachmentForm = infoEditWindow.down('form').down('form').getForm().findField('fileUpdateNameDisp').setValue(""+annexName+"");

这里必须要encodeURI两次,如果是一次的话浏览器还是会把他解析为中文,那么也就无效了。

public String downloadFile(){        try {            getKmInfoVO().setFileUpdateFileName(new String(URLDecoder.decode(getKmInfoVO().getFileUpdateFileName(),"UTF-8").getBytes("UTF-8"),                    "ISO-8859-1"));        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }        InputStream fileStream = fileStorageService.getInputStream(getKmInfoVO().getFileUpdateId());        kmInfoVO.setFileStream(fileStream);        return SUCCESS;    }

后台只需要URLDecoder一次就可以成功解码了,最后经过在本地和测试环境上都可行。最后再说一下,很多情况下,我们在写程序的时候都会把代码设置为UTF-8的编码,可以在下载文件设置filename的时候却要设置编码格式为ISO-8859-1(如是英文的话就不需要这样处理了)。

先说为什么使用 ISO-8859-1 编码,这个主要是由于http协议,http header头要求其内容必须为iso-8859-1编码,所以我们最终要把其编码为 ISO-8859-1 编码的字符串;
但是前面为什么不直接使用 "中文文件名".getBytes("ISO-8859-1"); 这样的代码呢?因为ISO-8859-1编码的编码表中,根本就没有包含汉字字符,当然也就无法通过"中文文件名".getBytes("ISO-8859-1");来得到正确的“中文文件名”在ISO-8859-1中的编码值了,所以再通过new String()来还原就无从谈起了。 所以先通过 "中文文件名".getBytes("utf-8") 获取其 byte[] 字节,让其按照字节来编码,即在使用 new String("中文文件名".getBytes("utf-8"), "ISO-8859-1") 将其重新组成一个字符串,传送给浏览器。

转载于:https://www.cnblogs.com/luoxiao-wang/p/4030163.html

你可能感兴趣的文章
mysql 查询死锁语句
查看>>
pl_sql操作--激活提升权限scott用户
查看>>
UDP网络编程
查看>>
[Nuxt] Display Vuex Data Differently in Each Page of Nuxt and Vue.js
查看>>
[Ramda] Curry and Uncurry Functions with Ramda
查看>>
[TypeScript] Function Overloads in Typescript
查看>>
[React] React Fundamentals: Mixins
查看>>
关于SQL数据库 数据库名 表名的一些操作
查看>>
1013. 识别三角形
查看>>
IE8+兼容经验小结
查看>>
Android studio下使用SharedSDK
查看>>
会话与请求
查看>>
hibernate one2many (单向关联)
查看>>
自制反汇编逆向分析工具
查看>>
MS SQLserver数据库安装
查看>>
第2章 数字之魅——斐波那契(Fibonacci)数列
查看>>
Spark集群基于Zookeeper的HA搭建部署笔记(转)
查看>>
Codeforces Round #106
查看>>
vue循环时设置多选框禁用状态,v-for
查看>>
CSS3 2D 转换
查看>>