一:浏览器post表单提交
通常的input组件表单提交时,按照form属性提交的其中enctype=”application/x-www-form-urlencoded”是默认值
<form action="RequestServlet" method="post" enctype="application/x-www-form-urlencoded">
- 1
该提交方式只是提交普通表单;对于file组所选中的文件内容是不上传的,因此需要设置:enctype属性
enctype="multipart/form-data"
- 1
多部分提交方式,但注意编码问题:对于post方式,浏览器会对中文进行编码处理,发送字节,而普通组件的值得根据pageEncoding=”“的格式编码。但是对于文件,是会检测文件本身的编码格式进行编码。
因此在后台我么获取的字节集,是根据pageEncoding=”“+文件本身的编码格式混合的字节集,对于requset.setchar..设置编码只能解析部分正确的编码,其余会乱码
对于后台接受的内容除了文件内容,是还有其他部分的识别码:
InputStream in=request.getInputStream();
int len=-1;
byte[] buf=new byte[1024];
while((len=in.read(buf))!=-1){
System.out.print(new String(buf,"utf-8"));
}
- 1
- 2
- 3
- 4
- 5
- 6
可以看出:
除了组件值:流中具有序列码,说明吗等识别码,并且对于不同编码的文件以同一编码流解析,会部分乱码!
如果要在后台接受文件,那么我们必须去解析这些内容,确定有几个文件,分别是什么编码,要抛弃掉识别码,分别以什么编码写相应文件对应的那段字节。这是十分复杂的。
然而有人帮我做好了解析工具,以便我们直接用就行了,我在这介绍一种:Apache的文件上传工具
使用该工具解析步骤(只说明基础版步骤):
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//※下面这句解决上传文件名的中文乱码
//注意,下面这句设置中文,如果是“multipart/form-data”表单,可以设置其中file组件的文件名,但对其中的普通表单组件无效。
//注意,下面这句设置中文,如果是我们以前用的“application/x-www-form-urlencoded”表单,可以设置其中的普通表单组件。
request.setCharacterEncoding("utf-8");
//先获取所接收文件我们要保存到哪里的路径
String path = getServletContext().getRealPath("/imgs");
//文件上传需要临时目录(如果不指定,那么该目录就是tomcat/temp )
File tempDir = new File("d:/a");
DiskFileItemFactory fileFactory = new DiskFileItemFactory(1024*8, tempDir);//创建用于解析文件的工厂类,同时设置缓冲区的位置和大小
//※※※※思路的入口
ServletFileUpload upload = new ServletFileUpload(fileFactory);
upload.setFileSizeMax(1024*1024*5);//设置每个文件最大为5M
upload.setSizeMax(1024*1024*8);//所有上传文件大小之和的最大值,此处设最多能上传8M
//以下开始解析
try {
List<FileItem> list= upload.parseRequest(request);
for(FileItem fi:list){
if(fi.isFormField()){//普通表单组件,如:<input type="text" name="desc1"/>
String str = fi.getString("utf-8");//※以指定编码的方式获取,来解决普通表单组件的中文乱码问题
System.out.println("普通表单组件..."+str);
}else{//文件组件
String fileName = fi.getName();//文件名
System.out.println("fileName:"+fileName);
//由于上传的文件“名字”可能会有中文,而服务器目录当中的资源名称不能够用中文,因此要把它转换成非中文的文件名(要考虑文件名不能重复)
String uuid = UUID.randomUUID().toString().replace("-", "");
String ext = fileName.substring( fileName.lastIndexOf("."));//截取文件的扩展名: .jpg
String newFileName = uuid+ext;
//真正的文件内容在 fi.getInputStream() 当中
FileUtils.copyInputStreamToFile(fi.getInputStream(), new File(path+"/"+newFileName));
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
上面代码我们要注意几点:
1:request.setCharacterEncoding(“utf-8”);在enctype值不同的情况下能起到什么作用
2:DiskFileItemFactory 与ServletFileUpload以及FileItem三个类的使用(需要网上下载相应jar包,导入项目中,jdk中无此类)
3:项目文件名不能有中文(原因:浏览器资源请求时会对中文编码;如此,一个名为:图片.jpg 到达后台会编码成 字节名,服务器根据字节名查文件,又怎么能查到文件呢?)
4:文件名的唯一性(资源名不能重复,服务器无法区分)
5:中文乱码问题(代码有处理)