关于TomCat上传文件中文名乱码的问题
最近在学习TomCat文件上传这一部分,由于文件上传必须要三个条件:
1.表单提交方式必须为Post
2.表单中需要有<input type=”file”>元素,还需要有name属性和值(name的值)。
3.表单enctype=”multipart/form-data”
而且,这种方式提交后对浏览器进行抓包分析如下:
POST /web06/jsp/upload.jsp HTTP/1.1
Accept: text/html, application/xhtml+xml, */*
X-HttpWatch-RID: 22006-10026
Referer: http://localhost:8080/web06/jsp/upload.jsp
Accept-Language: zh-CN
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
Content-Type: multipart/form-data; boundary=-------------------------7e139d10110a64(分割线,将请求体的内容分成几块,后面带两个横杠表示内容结束)
Accept-Encoding: gzip, deflate
Host: localhost:8080
Content-Length: 322
DNT: 1
Connection: Keep-Alive
Cache-Control: no-cache
Cookie: JSESSIONID=D51DCB996556C94861B2C72C4D978010 -----------------------------7e139d10110a64
Content-Disposition: form-data; name="info" aaa
-----------------------------7e139d10110a64
Content-Disposition: form-data; name="upload"; filename="C:\Users\jt\Desktop\aa.txt"
Content-Type: text/plain hello world!!!
-----------------------------7e139d10110a64—-(有两个横杠表示结束)
要想获得普通项的参数,不能像以前那样通过request.getParameter()来得到了.因此,借住第三方工具包,本文采用的是Apache公司的FileUpload工具包.代码如下:
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
6 request.setCharacterEncoding("utf-8");
List<FileItem> fileitems = servletFileUpload.parseRequest(request);
8 //System.setProperty("sun.jnu.encoding","utf-8");//设置系统对文件名编码的字符集
for (FileItem itme : fileitems) {
if (itme.isFormField()) {//是普通项
String name = itme.getFieldName();
String value = itme.getString("utf-8");
13 //String value = itme.getString();
14 //value = new String(value.getBytes("iso-8859-1"),"utf-8");
System.out.println(name+"---"+value);
} else {//文件上传项
String realPath = this.getServletContext().getRealPath("/upload");
File file = new File(realPath);
if (!file.exists()) {
file.mkdirs();//不存在就创建文件夹
}
//获得文件输入流
InputStream is = itme.getInputStream();
//获得输出流
String filename =itme.getName();
System.out.println(filename);
27 //System.out.println(System.getProperty("file.encoding"));
28 //System.out.println(System.getProperty("sun.jnu.encoding"));
int index = filename.lastIndexOf("\\");//兼容IE浏览器,如果是IE浏览器,则获得filename为全路径
if (index != -1) {
filename = filename.substring(index + 1);
}
System.out.println(filename);
String newFilename = Utils.getName(filename);//工具类,防止文件名重名,调用UUID
String path = Utils.getFilename(newFilename);//工具类,将文件进行分类存放
File newFile = new File(realPath +"/"+ path);
if (!newFile.exists()) {
newFile.mkdirs();
}
FileOutputStream os = new FileOutputStream(realPath +"/"+ path+ newFilename);
IOUtils.copy(is,os);
is.close();
os.close();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
上面代码中标红部分是比较关键的地方.下面对普通项和文件项乱码问题分别进行解释:
1.普通项
获得普通项的值得代码为:
String value = itme.getString("utf-8");
和这个方法有个重载的如下:
String value = itme.getString();
很显然大家也知道结果,上面那个采用字符集"utf-8"进行编码,如果value含有中文,那么结果不会乱码,而采用下面一种则会乱码.我当时就在想,我在程序开始已经设置了请求缓冲流的字符集如下:
request.setCharacterEncoding("utf-8");
为什么我调用下面getString()还会出现乱码呢?去查看源码才发现自己对这几个方法根本没有理解,只是套模板用而已.下面先看一下setCharacterEncoding()方法的作用,API中的解释如下:
public void setCharacterEncoding(String env) throws java.io.UnsupportedEncodingException
重写此请求正文中使用的字符编码的名称。必须在使用 getReader() 读取请求参数或读取输入之前调用此方法。否则,此方法没有任何效果。
当你提交不含文件的表单,调用getParameter方法从请求缓冲流获得数据时,设置该方法可以解决乱码问题,(只限Post请求和Tomcat8.0的get请求).查看getParameter源码如下:
6 private void mergeParameters(){
7 if ((queryParamString == null) || (queryParamString.length() < 1))
8 return;
9 HashMap queryParameters = new HashMap();
10 String encoding = getCharacterEncoding();
11 if (encoding == null)
12 encoding = "ISO-8859-1";
13 try{
14 RequestUtil.parseParameters(queryParameters, queryParamString, encoding);
15 }catch (Exception e){
16 ;
17 }
18 Iterator keys = parameters.keySet().iterator();
19 while (keys.hasNext()){
20 String key = (String) keys.next();
21 Object value = queryParameters.get(key);
22 if (value == null){
23 queryParameters.put(key, parameters.get(key));
24 continue;
25 }
26 queryParameters.put(key, mergeValues(value, parameters.get(key)));
27 }
28 parameters = queryParameters;
29 }
主要在10 11 12三行代码,10行调用了getCharacterEncoding()方法获得字符集,如果没设置的话就默认设置字符集为iso-8859-1.
而在提交含有文件(即设置了enctype属性)的请求中就不一样了,下面看一下getString()方法的源码:
1 public String getString() {
2 byte[] rawdata = get();//通过缓冲流获得字节数组
3 String charset = getCharSet();//获得字符集,并没有看到setCharSet方法,因此,调用该方法,只能得到charset=null
4 if (charset == null) {//如果字符集是空
5 charset = DEFAULT_CHARSET;//这是个自定义常量为ISO-8859-1
6 }
7 try {
8 return new String(rawdata, charset);//通过iso-8859-1进行编码得到了结果,肯定会乱码
9 } catch (UnsupportedEncodingException e) {
10 return new String(rawdata);
11 }
12 }
public String getString(final String charset) throws UnsupportedEncodingException { return new String(get(), charset); }
这是重载的getString(String )方法,可以看到get()获得字符数组之后,直接调用new String方法得到参数.
那么如果用 String value = itme.getString();则可以先用iso-8859-1解码,然后再用utf-8编码,也能获得正确的结果.
String value = new String((value.getbytes("iso-8859-1"),"utf-8");
2.文件项上传(文件名乱码和文件内容乱码)
请参考:
https://blog.csdn.net/QQ578473688/article/details/77265815?locationNum=7&fps=1
关于TomCat上传文件中文名乱码的问题的更多相关文章
- 关于commons-fileupload组件上传文件中文名乱码问题
java web开发,常用到的文件上传功能,常用的commons-fileupload和commons-io两个jar包.关于如何使用这两个jar来完成文件上传的功能,这里不做详解.使用commons ...
- C# 使用 fckeditor 上传文件中文名乱码的问题---转
提到中文乱码,首先肯定是由于编码问题引起的所以就从编码转换入手,尝试了将UTF-8转换为GB2312,但发现无论如何没有办法转成功 看到很多文章说修改配置文件 <globalization re ...
- Tomcat上传文件报错:returned a response status of 403 Forbidden
出现这样的错误是没有权限对服务器进行写操作.需要在这个项目所在的tomcat中配置可写操作即可: 在tomcat的web.xml添加下面代码: <init-param><param- ...
- drupal7 上传文件中文乱码
drupal7自带有file模块,可以上传文件. 但是存在问题:如果上传的文件名称是中文,存储在文件下面的文件名称是乱码的,解决办法如下:参考出处 includes/file.inc中,修改两处代码, ...
- restTemplate.postForObject上传文件中文乱码(???.xls)
一.问题描述 项目中, 使用restTemplate上传文件时, 文件名中文乱码, 一串问号, 源文件名为: 测试中文乱码哦哦哦.zip, 通过restTemplate.postForObject调用 ...
- Linux学习23-Xftp上传文件显示乱码问题
前言 当我们在windows新建一个文件,里面有中文时,使用Xftp上传到linux服务器上,会出现乱码问题. Windows的默认编码为GBK Linux的默认编码为UTF-8 Xftp上传文件乱码 ...
- tomcat 上传文件权限不足
参考:https://www.cnblogs.com/houchaoying/p/8652040.html tomcat-bin-catalina.sh UMASK="0027" ...
- php 上传文件名出现乱码
想必很多朋友在进行utf8编码的php开发上传功能的时候,都会遇到这样的一个问题,就是上传中文文件名的文件时,文件名会变成乱码,其实我们可以用iconv函数对文件名进行重新编码就解决问题了 可能会有不 ...
- SpringMVC使用FileUpload上传文件
进口FileUpload和common-io的Jar包 注意:1.Struts2其它方法需要使用的:struts2过滤,将改变reqeust类型,由HttpServletRequest成为MultiP ...
随机推荐
- js中url跳转问题
问题描述:列表中有不同的企业名字,每个企业名字都有一个不同的链接,用id做为参数区分.点击不同的名字,根据id的不同跳转到对应的详情页,设置连接如下: 1. url = http://localhos ...
- C++ RCSP智能指针简单实现与应用
智能指针的实现代码来源博客:<http://blog.csdn.net/to_be_better/article/details/53570910> 修改:添加 get()函数,用以获得原 ...
- 转: web 页面加载速度优化实战-100% 的飞跃提升
前言 一个网站的加载速度有多重要? 反正我相信之前来 博主网站 的人至少有 50% 在加载完成前关闭了本站. 为啥捏? 看图 首页完整加载时间 8.18s,看来能进来看博主网站的人都是真爱呀,哈哈. ...
- Navicat Premium 11破解补丁下载及安装方法
Navicat Premium 11.x Patch破解补丁
- Redis的持久化机制包括RBD和AOF两种,对于这两种持久化方式各有优势
RDB机制的策略 RDB持久化是指在指定的时间间隔内将内存中的数据和操作通过快照的方式保存到redis bin目录下的一个默认名为 dump.rdb的文件,可以通过配置设置自动的快照持久化的方式,我们 ...
- IPFS:世界正在悄然发生变化
世界正在悄然发生变化(IPFS) 2015-05-05 Juan Benet 在自己的终端里面敲入了下面的文字: > echo "hello worlds" | ipfs a ...
- 自定义TabBar之理解hittest
需求的TabBar是这样的:5个 tabItem, 中间的那个 item 部分超出系统默认TabBar的上边界. 那么实现的关键点就是如何在点击它突出的部分的时候,也可以正常获得响应.我来把问题简化, ...
- 关于html文档的规范
1. <!DOCTYPE html> 告诉浏览器该文档使用哪种html或xhtml的规范 2. 元数据中的X-UA-Compatible <meta http-equiv=" ...
- git分支的创建与合并
在git中提倡使用分支,这就涉及到了分支的创建和合并.在git中我们的每次提交类似于一个链表,按照时间顺序向下排列,大约画了一个图,每个小圆圈代表一次提交,在git中有有一个主分支master,我们新 ...
- 很全的atom问题解决方案
atom插件 http://blog.csdn.net/qq_30100043/article/details/53558381 atom社区 https://atom-china.org/