-创建jsp页面
创建一个包含上传文件表单的jsp页面:
<body>
<h1>文件上传</h1>
<form action="<c:url value='/UploadServlet' />" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" /><br/>
文 件:<input type="file" name="filename"><br/>
<input type="submit" value="上传" />
</form>
</body>
需要注意的是form默认的编码格式为application/x-www-form-urlencoded,不能用于上传文件。在此,我们需要将他修改为multipart/form-data
-创建响应表单请求的UploadServlet
在获取文件的上传时,我们不能再通过简单的request.getAttribute()方法去获取表单内容了,因为他的请求体发生了改变,我们可以通过HttpWatch这样的工具去查看请求体。我们可以通过Apache提供的开源组件commons-fileupload.jar(他以来commons-io.jar)来简化我们获取表单信息的步骤。
在文件上传中需要注意一下几个问题:
1.文件必须保存到WEB-INF下!
2.文件名称相关问题,有些浏览器会提交文件绝对路径,我们需要切割。
3.目录打散,分散文件的分布,避免将所有文件放在一个目录下。
4.上传文件的大小限制。
5.缓存大小与临时目录。这个默认为10K,目录为“java.io.tmpdir”对应的目录,具体可以在DiskFileItemFactory中设置。
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
DiskFileItemFactory factory = new DiskFileItemFactory(); //获取工厂
ServletFileUpload sfu = new ServletFileUpload(factory); //获取解析器
sfu.setFileSizeMax(10 * 1024); //限制单个文件的大小不得超过10K
sfu.setSizeMax(1024 * 1024); //限制请求的所有数据大小不得超过1M
try {
List<FileItem> listFileItem = sfu.parseRequest(request);//获取表单项列表
//文件保存目录,上传文件存放于WEB-INF目录下,使浏览器不可直接访问
String root = this.getServletContext().getRealPath("/WEB-INF/files/");
FileItem fileItem1 = listFileItem.get(0);
System.out.println(fileItem1.getFieldName() + ":" + fileItem1.getString("utf-8"));
FileItem fileItem2 = listFileItem.get(1);
//System.out.println("Content-Type:" + fileItem2.getContentType());
//System.out.println("Size:" + fileItem2.getSize());
//System.out.println("FileName:" + fileItem2.getName());
String fileName = fileItem2.getName();
//当文件名称是绝对路径时,我们需要截取文件名部分
int index = fileName.lastIndexOf("\\");
if(index != -1){
fileName = fileName.substring(index + 1);
}
//文件名重名问题,uuid_fileName
String uuid = UUID.randomUUID().toString().replace("-", "").toUpperCase();
System.out.println(uuid);
String saveName = uuid + "_" + fileName; // 文件保存名字,避免同名文件的冲突
//目录打散-哈希打散,使用文件名哈希值的十六进制的前两位
int hashCode = fileName.hashCode();
String hex = Integer.toHexString(hashCode).toUpperCase();
File dirFile = new File(root, hex.charAt(0) + "/" + hex.charAt(1));
//创建目录链,自动生成该链中不存在的目录
dirFile.mkdirs();
File destFile = new File(dirFile, saveName);
//写入文件
fileItem2.write(destFile);
} catch (FileUploadException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}