通过第三方库fileupload上传文件.
试图界面(index.jsp)
<body>
<form action="${pageContext.request.contextPath}/UploadFileServlet" method="post" enctype="multipart/form-data">
<input type="file" name="file"><br><br>
<input type="submit" value="提交">
</form>
</body>
在界面中我设置了enctype属性:enctype="application/x-www-form-urlencoded",这是默认值,通过他进行操作时,在服务器端通过getParamitar()等方法获取文件的值时,只能得到文件的带路径的名字, 如果要想得到文件的内容:必须修改成multipart/form-data类型
当在application/x-www-form-urlencoded下,使用getParameter接收值的时候,如果是ie浏览器:得到的是带路径的名字 如果是火狐:得到的是名字
当enctype类型是multipart/form-data的时候,使用getparameter(),接收不到数据,以内他只能接收字符流,此时传过来的是字节流
Servlet(UploadFileServlet.java)
package com.qianfeng.serlvet;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
public class UploadFileServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置编码
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter pw = response.getWriter();
//判断表单的格式
boolean b = ServletFileUpload.isMultipartContent(request);
//如果格式错误直接抛出异常
if(!b){
throw new RuntimeException("您的表单的enctype类型不是multi/form-data格式的");
}
//1.创建工厂对象
DiskFileItemFactory factory =new DiskFileItemFactory();
//2.创建用于文件上传的对象
ServletFileUpload sfu = new ServletFileUpload(factory);
//处理上传文件有中文的问题
sfu.setHeaderEncoding("utf-8");
String path = null;
//3.把提交过来的表单数据进行解析
try {
//得到的集合元素是数据项--把每个标签看做数据项
List<FileItem> list = sfu.parseRequest(request);
//遍历集合,将数据项进行分类
for(FileItem fileItem : list){
if(fileItem.isFormField()){
//普通数据项
processFormField(fileItem);
}else{
//文件
path = processFileUpload(fileItem);
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
pw.println("上传成功,文件保存在:<font style='color:red;'>"+path+"</font>");
pw.close();
}
//处理文件
public String processFileUpload(FileItem item){
//创建保存文件的文件夹---默认存储到服务器上
//注意:如果上传的文件不想让客户通过地址栏访问,就把它放在WEB-INF下面,这里默认不允许通过地址栏访问--安全
//通过相对路径获取绝对路径
String storeDirectory = this.getServletContext().getRealPath("/WEB-INF/upload");
//以绝对路径构造文件
File realFile = new File(storeDirectory);
//判断该目录是否存在
if(!realFile.exists()){
realFile.mkdirs();//将路径上的所有目录都创建出来
}
//获取文件的名字
String fileName = item.getName();
System.out.println("fileName1--"+fileName);
//通过工具获取文件的名字
//fileName = FilenameUtils.getName(fileName);
System.out.println("fileName2---"+fileName);
//处理同名的文件
fileName = UUID.randomUUID().toString()+"_"+fileName;
//处理把文件放在不同的子文件夹
String subdir = getChildDirectoryByHashCode(realFile,fileName);
//获取文件要存储的完整路径
File newFile = new File(realFile,subdir+File.separator+fileName);
//通过三方库的写方法执行写入
try {
item.write(newFile);
} catch (Exception e) {
e.printStackTrace();
}
return newFile.getAbsolutePath();
}
//创建子文件夹目录---通过哈希值
private String getChildDirectoryByHashCode(File realFile, String fileName) {
//通过文件获取hashcode
int hash = fileName.hashCode();
//转化为16进制
String hexhash = Integer.toHexString(hash);
String subdir = hexhash.charAt(0)+File.separator+hexhash.charAt(1); // 1/0 1/e
//根据生成的字符串生成真正的路径
File newdir = new File(realFile,subdir);
//该文件不存在,就创建
if(!newdir.exists()){
newdir.mkdirs();
}
return subdir;
}
//处理普通数据项
public void processFormField(FileItem item){
String name = item.getName();
String value = null;
try {
value = item.getString("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
注意点:
1.要提供form表单,method必须是post
2.enctype类型是multipart/form-data
3.表单必须提供file类型标签