最近在学习TomCat文件上传这一部分,由于文件上传必须要三个条件:  

  1.表单提交方式必须为Post

  2.表单中需要有<input type=”file”>元素,还需要有name属性和值(name的值)。

  3.表单enctype=”multipart/form-data”

  而且,这种方式提交后对浏览器进行抓包分析如下:

  1. POST /web06/jsp/upload.jsp HTTP/1.1
  2. Accept: text/html, application/xhtml+xml, */*
  3. X-HttpWatch-RID: 22006-10026
  4. Referer: http://localhost:8080/web06/jsp/upload.jsp
  5. Accept-Language: zh-CN
  6. User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko
  7. Content-Type: multipart/form-data; boundary=-------------------------7e139d10110a64(分割线,将请求体的内容分成几块,后面带两个横杠表示内容结束)
  8. Accept-Encoding: gzip, deflate
  9. Host: localhost:8080
  10. Content-Length: 322
  11. DNT: 1
  12. Connection: Keep-Alive
  13. Cache-Control: no-cache
  14. Cookie: JSESSIONID=D51DCB996556C94861B2C72C4D978010
  15.  
  16. -----------------------------7e139d10110a64
  17. Content-Disposition: form-data; name="info"
  18.  
  19. aaa
  20. -----------------------------7e139d10110a64
  21. Content-Disposition: form-data; name="upload"; filename="C:\Users\jt\Desktop\aa.txt"
  22. Content-Type: text/plain
  23.  
  24. hello world!!!
  25. -----------------------------7e139d10110a64—-(有两个横杠表示结束)

  要想获得普通项的参数,不能像以前那样通过request.getParameter()来得到了.因此,借住第三方工具包,本文采用的是Apache公司的FileUpload工具包.代码如下:

  1. public class UploadServlet extends HttpServlet {
  2. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  3. try {
  4. DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
  5. ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
  6. 6 request.setCharacterEncoding("utf-8");
  7. List<FileItem> fileitems = servletFileUpload.parseRequest(request);
  8. 8 //System.setProperty("sun.jnu.encoding","utf-8");//设置系统对文件名编码的字符集
  9. for (FileItem itme : fileitems) {
  10. if (itme.isFormField()) {//是普通项
  11. String name = itme.getFieldName();
  12. String value = itme.getString("utf-8");
  13. 13 //String value = itme.getString();
  14. 14 //value = new String(value.getBytes("iso-8859-1"),"utf-8");
  15. System.out.println(name+"---"+value);
  16. } else {//文件上传项
  17. String realPath = this.getServletContext().getRealPath("/upload");
  18. File file = new File(realPath);
  19. if (!file.exists()) {
  20. file.mkdirs();//不存在就创建文件夹
  21. }
  22. //获得文件输入流
  23. InputStream is = itme.getInputStream();
  24. //获得输出流
  25. String filename =itme.getName();
  26. System.out.println(filename);
  27. 27 //System.out.println(System.getProperty("file.encoding"));
  28. 28 //System.out.println(System.getProperty("sun.jnu.encoding"));
  29. int index = filename.lastIndexOf("\\");//兼容IE浏览器,如果是IE浏览器,则获得filename为全路径
  30. if (index != -1) {
  31. filename = filename.substring(index + 1);
  32. }
  33. System.out.println(filename);
  34. String newFilename = Utils.getName(filename);//工具类,防止文件名重名,调用UUID
  35. String path = Utils.getFilename(newFilename);//工具类,将文件进行分类存放
  36. File newFile = new File(realPath +"/"+ path);
  37. if (!newFile.exists()) {
  38. newFile.mkdirs();
  39. }
  40. FileOutputStream os = new FileOutputStream(realPath +"/"+ path+ newFilename);
  41. IOUtils.copy(is,os);
  42. is.close();
  43. os.close();
  44. }
  45. }
  46. } catch (FileUploadException e) {
  47. e.printStackTrace();
  48. }
  49. }

  上面代码中标红部分是比较关键的地方.下面对普通项和文件项乱码问题分别进行解释:

1.普通项

  获得普通项的值得代码为:

  1. String value = itme.getString("utf-8");

  和这个方法有个重载的如下:

  1. String value = itme.getString();

  很显然大家也知道结果,上面那个采用字符集"utf-8"进行编码,如果value含有中文,那么结果不会乱码,而采用下面一种则会乱码.我当时就在想,我在程序开始已经设置了请求缓冲流的字符集如下:

  1. request.setCharacterEncoding("utf-8");

  为什么我调用下面getString()还会出现乱码呢?去查看源码才发现自己对这几个方法根本没有理解,只是套模板用而已.下面先看一下setCharacterEncoding()方法的作用,API中的解释如下:

  1. public void setCharacterEncoding(String env) throws java.io.UnsupportedEncodingException
  2. 重写此请求正文中使用的字符编码的名称。必须在使用 getReader() 读取请求参数或读取输入之前调用此方法。否则,此方法没有任何效果。

   当你提交不含文件的表单,调用getParameter方法从请求缓冲流获得数据时,设置该方法可以解决乱码问题,(只限Post请求和Tomcat8.0的get请求).查看getParameter源码如下:

  1. 6 private void mergeParameters(){
  2. 7 if ((queryParamString == null || queryParamString.length() < 1))
  3. 8 return;
  4. 9 HashMap queryParameters = new HashMap();
  5. 10 String encoding = getCharacterEncoding();
  6. 11 if encoding == null
  7. 12 encoding = "ISO-8859-1";
  8. 13 try{
  9. 14 RequestUtil.parseParametersqueryParameters queryParamString encoding);
  10. 15 }catch Exception e){
  11. 16 ;
  12. 17 }
  13. 18 Iterator keys = parameters.keySet().iterator();
  14. 19 while keys.hasNext()){
  15. 20   String key = String keys.next();
  16. 21   Object value = queryParameters.getkey);
  17. 22   if value == null){
  18. 23     queryParameters.putkey parameters.getkey));
  19. 24     continue;
  20. 25     }
  21. 26     queryParameters.putkey mergeValuesvalue parameters.getkey)));
  22. 27   }
  23. 28   parameters = queryParameters;
  24. 29 }
  1.  主要在10 11 12三行代码,10行调用了getCharacterEncoding()方法获得字符集,如果没设置的话就默认设置字符集为iso-8859-1.
        而在提交含有文件(即设置了enctype属性)的请求中就不一样了,下面看一下getString()方法的源码:
  1. 1 public String getString() {
  2. 2 byte[] rawdata = get();//通过缓冲流获得字节数组
  3. 3 String charset = getCharSet();//获得字符集,并没有看到setCharSet方法,因此,调用该方法,只能得到charset=null
  4. 4 if (charset == null) {//如果字符集是空
  5. 5 charset = DEFAULT_CHARSET;//这是个自定义常量为ISO-8859-1
  6. 6 }
  7. 7 try {
  8. 8 return new String(rawdata, charset);//通过iso-8859-1进行编码得到了结果,肯定会乱码
  9. 9 } catch (UnsupportedEncodingException e) {
  10. 10 return new String(rawdata);
  11. 11 }
  12. 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编码,也能获得正确的结果.

  1. String value = new String((value.getbytes("iso-8859-1"),"utf-8");
  1. 2.文件项上传(文件名乱码和文件内容乱码)
    请参考:
  2. https://blog.csdn.net/QQ578473688/article/details/77265815?locationNum=7&fps=1

关于TomCat上传文件中文名乱码的问题的更多相关文章

  1. 关于commons-fileupload组件上传文件中文名乱码问题

    java web开发,常用到的文件上传功能,常用的commons-fileupload和commons-io两个jar包.关于如何使用这两个jar来完成文件上传的功能,这里不做详解.使用commons ...

  2. C# 使用 fckeditor 上传文件中文名乱码的问题---转

    提到中文乱码,首先肯定是由于编码问题引起的所以就从编码转换入手,尝试了将UTF-8转换为GB2312,但发现无论如何没有办法转成功 看到很多文章说修改配置文件 <globalization re ...

  3. Tomcat上传文件报错:returned a response status of 403 Forbidden

    出现这样的错误是没有权限对服务器进行写操作.需要在这个项目所在的tomcat中配置可写操作即可: 在tomcat的web.xml添加下面代码: <init-param><param- ...

  4. drupal7 上传文件中文乱码

    drupal7自带有file模块,可以上传文件. 但是存在问题:如果上传的文件名称是中文,存储在文件下面的文件名称是乱码的,解决办法如下:参考出处 includes/file.inc中,修改两处代码, ...

  5. restTemplate.postForObject上传文件中文乱码(???.xls)

    一.问题描述 项目中, 使用restTemplate上传文件时, 文件名中文乱码, 一串问号, 源文件名为: 测试中文乱码哦哦哦.zip, 通过restTemplate.postForObject调用 ...

  6. Linux学习23-Xftp上传文件显示乱码问题

    前言 当我们在windows新建一个文件,里面有中文时,使用Xftp上传到linux服务器上,会出现乱码问题. Windows的默认编码为GBK Linux的默认编码为UTF-8 Xftp上传文件乱码 ...

  7. tomcat 上传文件权限不足

    参考:https://www.cnblogs.com/houchaoying/p/8652040.html tomcat-bin-catalina.sh UMASK="0027" ...

  8. php 上传文件名出现乱码

    想必很多朋友在进行utf8编码的php开发上传功能的时候,都会遇到这样的一个问题,就是上传中文文件名的文件时,文件名会变成乱码,其实我们可以用iconv函数对文件名进行重新编码就解决问题了 可能会有不 ...

  9. SpringMVC使用FileUpload上传文件

    进口FileUpload和common-io的Jar包 注意:1.Struts2其它方法需要使用的:struts2过滤,将改变reqeust类型,由HttpServletRequest成为MultiP ...

随机推荐

  1. [USACO5.4]奶牛的电信Telecowmunication

    裸的最小割,拆点时要考虑清楚到底是怎么连 如果之前i->i+n,之后又x->y+n,显然出不了解 所以可以改为i+n->i 如果要输出方案 考虑每一个一个点,如果删去这个点,最小割变 ...

  2. 含隐变量模型求解——EM算法

    1 EM算法的引入1.1 EM算法1.2 EM算法的导出2 EM算法的收敛性3EM算法在高斯混合模型的应用3.1 高斯混合模型Gaussian misture model3.2 GMM中参数估计的EM ...

  3. XeLaTeX中文模板

    XeLaTeX对中文的支持很友好,可以直接调用系统已安装字体进行文档的撰写.其中需要引用字体的名字,开始遇到了写问题,经常发现字体未引用,现在大概明白了. 引用字体的时候,如果不加中括号,就需要引用字 ...

  4. 书写Css文件要点

    1. 自定义样式名 实例1:<style type="text/css"> input.ng-invalid{ // .号一定要在对应的元素名后面, 没有空格 colo ...

  5. gulp工程化工具

    gulpfile.js var gulp = require('gulp'); var rename = require('gulp-rename') var pump = require('pump ...

  6. AsyncTask源码笔记

    AsyncTask源码笔记 AsyncTask在注释中建议只用来做短时间的异步操作,也就是只有几秒的操作:如果是长时间的操作,建议还是使用java.util.concurrent包中的工具类,例如Ex ...

  7. Ios 若干兼容处理

    最后处理兼容真是各种苦逼,还算好,最后解决了,再此总结一下 position:fixed 和 input 的问题? ios 对position:fixed 的定位处理兼容性不是很好,例如,在同时又in ...

  8. mysql-5.7.12安装

    CentOS 7的yum源中貌似没有正常安装mysql时的mysql-sever文件,需要去官网上下载   # wget http://dev.mysql.com/get/mysql-communit ...

  9. pycharm 的安装及selenium环境的搭建

    6.呵呵哒,前面写了一篇pycharm的安装,,结果自己都看不懂了,copy了别人的,,,自己现在再写一遍,这篇文章主要写pycharm 的安装及selenium 环境的搭建,selenium的搭建不 ...

  10. Vue项目环境搭建(node+webpack)

    安装node.js 下载地址:https://nodejs.org/en/download/ node -v //查看node.js版本 项目环境配置: 安装vue-cli:npm install - ...