一、上传文件
1、上传页面:upload.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <html>
5 <head>
6 <title>动态添加文件</title>
7
8 <script type="text/javascript">
9
10 //动态添加上传文件
11 function addFile(){
12 var files = document.getElementById("files");
13 //创建节点
14 var input = document.createElement("input");
15 input.type = "file";
16 input.name = "file";
17
18 var btn = document.createElement("input");
19 btn.type = "button";
20 btn.value = "删除";
21
22 btn.onclick = function del(){
23 this.parentNode.parentNode.removeChild(this.parentNode);
24 }
25
26 var div = document.createElement("div");
27 div.appendChild(input);
28 div.appendChild(btn);
29
30 files.appendChild(div);
31 }
32
33 </script>
34 </head>
35
36 <body>
37 <form action="${pageContext.request.contextPath }/servlet/UploadServlet2" enctype="multipart/form-data" method="post">
38 <table>
39 <tr>
40 <td>
41 上传用户
42 </td>
43 <td>
44 <input type="text" name="username">
45 </td>
46 </tr>
47 <tr>
48 <td>
49 上传文件
50 </td>
51 <td>
52 <input type="button" value="添加上传文件" onclick="addFile()">
53 </td>
54 </tr>
55
56 <tr>
57 <td></td>
58 <td>
59 <div id="files"></div>
60 </td>
61 </tr>
62
63 <tr>
64 <td></td>
65 <td>
66 <input type="submit" value="上传">
67 </td>
68 </tr>
69 </table>
70 </form>
71 </body>
72 </html>
2、上传文件处理类:UploadServlet.java
1 public class UploadServlet extends HttpServlet {
2
3 public void doGet(HttpServletRequest request, HttpServletResponse response)
4 throws ServletException, IOException {
5
6 List types = Arrays.asList("jpg","gif","avi","txt");
7
8 try{
9 DiskFileItemFactory factory = new DiskFileItemFactory(); //10k
10 factory.setSizeThreshold(1024*1024);
11 factory.setRepository(new File(this.getServletContext().getRealPath("/temp")));
12
13 ServletFileUpload upload = new ServletFileUpload(factory);
14 upload.setProgressListener(new ProgressListener(){
15 public void update(long pBytesRead, long pContentLength, int pItems) {
16 System.out.println("当前已解析:" + pBytesRead);
17 }
18 });
19
20 upload.setFileSizeMax(1024*1024*5);
21 if(!upload.isMultipartContent(request)){
22 //按照传统方式获取表单数据
23 request.getParameter("username");
24 return;
25 }
26 upload.setHeaderEncoding("UTF-8");
27
28 //把文件解析到一个list集合
29 List<FileItem> list = upload.parseRequest(request);
30
31 for(FileItem item : list){
32 if(item.isFormField()){
33 //为普通输入项
34 String inputName = item.getFieldName();
35 String inputValue = item.getString("UTF-8");
36 //inputValue = new String(inputValue.getBytes("iso8859-1"),"UTF-8");
37 System.out.println(inputName + "=" + inputValue);
38 }else{
39
40 String filename = item.getName().substring(item.getName().lastIndexOf("\")+1); //""
41
42 //判断是否为空文件,如果为空跳至下一次循环
43 if(filename==null || filename.trim().equals("")){
44 continue;
45 }
46
47
48 //限制上传文件的类型
49 /*String ext = filename.substring(filename.lastIndexOf(".")+1);
50 if(!types.contains(ext)){
51 request.setAttribute("message", "本系统不支持" + ext + "这种类型");
52 request.getRequestDispatcher("/message.jsp").forward(request, response);
53 return;
54 }*/
55 InputStream in = item.getInputStream();
56 int len = 0;
57 byte buffer[] = new byte[1024];
58 String saveFileName = generateFileName(filename);
59 String savepath = generateSavePath(this.getServletContext().getRealPath("/WEB-INF/upload"),saveFileName);
60 FileOutputStream out = new FileOutputStream(savepath + File.separator + saveFileName);
61 while((len=in.read(buffer))>0){
62 out.write(buffer, 0, len);
63 }
64 in.close();
65 out.close();
66 item.delete(); //删除临时文件,必须删除
67 }
68 }
69 }catch (FileUploadBase.FileSizeLimitExceededException e) {
70
71 //如果限制了上传文件的大小、必须捕捉这个异常
72 request.setAttribute("message", "文件大小不能超过5m");
73 request.getRequestDispatcher("/message.jsp").forward(request, response);
74 return;
75 }catch (Exception e) {
76 throw new RuntimeException(e);
77 }
78
79 //上传成功、跳转全局消息显示页面
80 request.setAttribute("message", "上传成功!!");
81 request.getRequestDispatcher("/message.jsp").forward(request, response);
82 }
83
84
85
86 //生成目录、文件不能全部保存同一个目录、要打散保存在不同的目录
87 public String generateSavePath(String path,String filename){
88
89 //得到文件名在内存中的哈希值,在内存中是32位二进制
90 int hashcode = filename.hashCode(); //121221
91
92 //低四位与上15得到一级目录
93 int dir1 = hashcode&15;
94
95 //右移4位再与上15得到二级目录
96 int dir2 = (hashcode>>4)&0xf;
97
98 String savepath = path + File.separator + dir1 + File.separator + dir2;
99
100 //判断目录是否存在、不存在就创建
101 File file = new File(savepath);
102 if(!file.exists()){
103 file.mkdirs();
104 }
105 return savepath;
106 }
107
108
109 //生成唯一的文件名、防止同名文件被覆盖
110 public String generateFileName(String filename){
111 //83434-83u483-934934
112 return UUID.randomUUID().toString() + "_" + filename;
113 }
114
115 public void doPost(HttpServletRequest request, HttpServletResponse response)
116 throws ServletException, IOException {
117 doGet(request, response);
118 }
119
120 }
二、文件下载
1、列出所有文件处理类:ListFileServlet.java
1 //列出网站所有文件
2 public class ListFileServlet extends HttpServlet {
3
4 public void doGet(HttpServletRequest request, HttpServletResponse response)
5 throws ServletException, IOException {
6 String path = this.getServletContext().getRealPath("WEB-INF/upload");
7 Map map = new HashMap();
8 listfile(new File(path),map);
9
10 //保存map
11 request.setAttribute("map", map);
12 //跳转到列表页面
13 request.getRequestDispatcher("/listfile.jsp").forward(request, response);
14 }
15
16 //保存迭代出来的文件
17 public void listfile(File file, Map map) {
18 if(!file.isFile()){//如果是目录,迭代
19 File children[] = file.listFiles();
20 for(File f : children){
21 listfile(f, map);
22 }
23 }else{//如果是文件、把文件在服务器的文件名和原始文件名保存在map集合中
24
25 //截取得到原始文件名
26 String filename = file.getName().substring(file.getName().indexOf("_")+1);
27 map.put(file.getName(), filename);
28 }
29 }
30
31 public void doPost(HttpServletRequest request, HttpServletResponse response)
32 throws ServletException, IOException {
33 doGet(request, response);
34 }
35
36 }
2、文件列表页面:listfile.jsp
1 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
2 <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
4 <html>
5 <head>
6 <title>文件列表</title>
7 </head>
8
9 <body>
10 <c:forEach var="entry" items="${requestScope.map}">
11
12 <!-- url编码,否则中文文件名会出现乱码 -->
13 <c:url var="url" value="/servlet/DownloadServlet">
14 <c:param name="filename" value="${entry.key }"></c:param>
15 </c:url>
16 ${entry.value }<a href="${url }">下载</a><br/>
17 </c:forEach>
18 </body>
19 </html>
3、下载处理类:DownloadServlet.java
1 public class DownloadServlet extends HttpServlet {
2
3
4 public void doGet(HttpServletRequest request, HttpServletResponse response)
5 throws ServletException, IOException {
6 //得到要下载的文件名
7 String filename = request.getParameter("filename");
8 //转码
9 filename = new String(filename.getBytes("iso8859-1"),"UTF-8");
10
11 //找出这个文件 File.separator与平台无关的盘符分隔符 windows c:\ linux不一样
12 String path = this.getServletContext().getRealPath("WEB-INF/upload")+File.separator+getPath(filename);
13 File file = new File(path+File.separator+filename);
14 if(!file.exists()){
15 request.setAttribute("message", "对不起,你要下载的文件已经被删除");
16 request.getRequestDispatcher("/message.jsp").forward(request, response);
17 //退出
18 return;
19 }
20
21 //得到文件的原始文件名
22 String oldName = file.getName().substring(file.getName().indexOf("_")+1);
23
24
25
26 //通知浏览器以下载的方式打开
27 response.setHeader("content-disposition","attachment;filename="+URLEncoder.encode(oldName,"UTF-8"));
28 FileInputStream in = new FileInputStream(file);
29 int len = 0;
30 byte buffer[] = new byte[1024];
31 OutputStream out = response.getOutputStream();
32 while((len=in.read(buffer))>0){
33 out.write(buffer, 0, len);
34 }
35 in.close();
36
37 }
38
39
40 public String getPath(String filename) {
41 //得到哈希值
42 int hashCode = filename.hashCode();
43 //得到一级目录
44 int dir1 = hashCode&15;
45
46 //得到二级目录
47 int dir2 = (hashCode>>4)&0xf;
48 return dir1+File.separator+dir2;
49 }
50
51
52 public void doPost(HttpServletRequest request, HttpServletResponse response)
53 throws ServletException, IOException {
54 doGet(request, response);
55 }
56
57 }