处理下载文件名乱码问题,包括某些情况下chrome出现的乱码。
一、引入jar包
1. commons-fileupload-1.2.1.jar
2. commons-io-1.4.jar
二、文件上传
html代码
1
2
3
4
5<form name="upload_test" action="${pageContext.request.contextPath}/FileServlet?method=upload" method="post" enctype="multipart/form-data">
用户名: <input type="text" name="userName" > <br>
文件: <input type="file" name="fileName" > <br>
<input type="submit" value="上传" >
</form>java代码
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64private void upload(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uri = null;
try {
//文件上传工厂
FileItemFactory factory = new DiskFileItemFactory();
//文件上传核心工具类
ServletFileUpload upload = new ServletFileUpload(factory);
/******设置大小限制参数******/
// 单个文件大小限制
upload.setFileSizeMax(10*1024*1024);
// 总文件大小限制
upload.setSizeMax(50*1024*1024);
// 对中文文件编码处理
upload.setHeaderEncoding("UTF-8");
//判断: 当前表单是否为文件上传表单
if(upload.isMultipartContent(request)){
//把请求数据转换为一个FileItem对象,再用集合封装
List<FileItem> list = upload.parseRequest(request);
// 遍历: 得到每一个上传的数据
for (FileItem item : list) {
// 判断类型(true:普通表单 || false:上传表单)
if(item.isFormField()){
//获取名称
String name = item.getFieldName();
//获取值
String value = item.getString();
//打印内容
System.out.println("name: " + name + "\tvalue: " + value);
} else {
/*****上传表单*****/
//获取文件名称
String name = item.getName();
// ----处理上传文件名重名问题----
//获取一个36位的uuid字符串
String id = UUID.randomUUID().toString();
//拼接文件名
name = id + "#" + name;
//得到上传目录
String basePath = getServletContext().getRealPath("upload");
System.out.println("basePath: " + basePath);
//创建要上传的文件对象
File file = new File(basePath, name);
//上传
item.write(file);
// 删除组件运行时产生的临时文件
item.delete();
}
}
} else {
System.out.println("不是上传表单");
}
uri = "/success.jsp";
} catch (FileUploadException e) {
e.printStackTrace();
uri = "/error/error.jsp";
} catch (Exception e) {
e.printStackTrace();
uri = "/error/error.jsp";
} finally {
request.getRequestDispatcher(uri).forward(request, response);
}
}
三、文件列表
html代码
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<table border="1" width="80%" align="center" cellpadding="5" cellspacing="0">
<tr>
<th>序号</th>
<th>文件名</th>
<th>操作</th>
</tr>
<c:choose>
<c:when test="${not empty requestScope.fileMap}">
<c:forEach items="${requestScope.fileMap }" var="en" varStatus="vs">
<tr>
<td>${vs.count }</td>
<td>${en.value }</td>
<td>
<!-- 构建一个地址 -->
<c:url var="url" value="FileServlet">
<c:param name="method" value="down"></c:param>
<c:param name="fileName" value="${en.key }"></c:param>
</c:url>
<!-- 使用上面地址 -->
<a href="${url }">下载</a>
</td>
</tr>
</c:forEach>
</c:when>
<c:otherwise>
<tr>
<td align="center" colspan="3">对不起,没有你要找的数据</td>
</tr>
</c:otherwise>
</c:choose>
</table>java代码
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
29private void downList(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 实现思路:先获取upload目录下所有文件的文件名,再保存;跳转到down.jsp列表展示
//初始化map集合Map<包含唯一标记的文件名, 简短文件名>
Map<String, String> fileMap = new HashMap<String, String>();
//获取上传目录
String basePath = getServletContext().getRealPath("/upload");
System.out.println(basePath);
//目录
File file = new File(basePath);
//遍历目录获取文件名
String[] list = file.list();
//遍历,封装
if (list != null && list.length > 0) {
for (String name : list) {
System.out.println(name);
String shortName = name.substring(name.lastIndexOf("#")+1);
System.out.println("shortName: " + shortName);
fileMap.put(name, shortName);
}
}
//保存到request域
request.setAttribute("fileMap", fileMap);
//转发
request.getRequestDispatcher("/downlist.jsp").forward(request, response);
}
三、文件下载
java代码
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
34private void down(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 获取用户下载的文件名称(url地址后追加数据,get)
String fileName = request.getParameter("fileName");
System.out.println("未编码:" + fileName);
//获取文件目录路径
String basePath = getServletContext().getRealPath("/upload");
//获取文件流
InputStream is = new FileInputStream(new File(basePath, fileName));
//截取字符串
String shortName = fileName.substring(fileName.lastIndexOf("#")+1);
System.out.println("截取后未编码:" + shortName);
shortName = new String(shortName.getBytes(),"ISO8859-1");
System.out.println("截取后编码:" + shortName);
//设置浏览器编码
response.setCharacterEncoding("UTF-8");
// 设置下载的响应头
response.addHeader("content-disposition", "attachment;fileName="+shortName);
// 获取response字节流
OutputStream os = response.getOutputStream();
byte[] by = new byte[1024];
int len = -1;
while ((len = is.read(by)) != -1) {
os.write(by, 0, len);
}
//关闭
os.close();
is.close();
}