1 文件上传表单
1)上传文件的本质是文本复制的过程2)技术层面,在Java中一定会用到IO操作,主要以二进制方式读写
3)传统方式下,对于上传文件字段不同的浏览器有着不同的解析方式,例如:
IE6:
upfile=c:\aa\bb\a.JPG
非IE6:
upfile=a.JPG
4)可以将form以MIME协议的方式将上传文件传递到服务端,服务端以二进制流的方式读写
代码: 客户端form enctype="multipart/form-data"/>
服务端request.getInputStream()
*2 上传文件的细节
(1)中文乱码的问题a)普通字段的中文乱码问题:FileItem.getString("UTF-8"),
注意:FileItem表示上传表单中的表单项内容
b)上传字段的中文乱码问题:ServletUploadFile.setHeaderEncoding("UTF-8");
(2)临时文件的删除的问题
a)通过FileItem.delete()
b)一定要在关闭IO流之后
(3)在同一个目录下上传相同文件名的问题
a)将文件名拼接一个唯一标识符,即UUID
(4)单个目录下文件过多的问题
a)采用位运算解决单个目录文件过多
b)思路:参见<<>>
(5)为安全将上传的文件放入客户端无法直接访问的目录中的问题
a)将上传的文件,放置到/WEB-INF/upload/目录下
(6)重构思想
a)做到通用性
(7)自定义封装上传文件工具类的问题
课堂练习:无上传文件提交/只能上传JPG或jpg文件
(8)上传文件的大小的问题
(9)上传多个文件的问题
(10)上传多个文件的界面问题
课堂练习:基于界面,限制上传文件的个数,参见<<课堂练习1.JPG>>
*3 显示下载文件列表
a)递归方式查询可供下载的文件,一定要有出口条件b)使用Map<UUID文件名,真实文件名>收集可供下载的文件
c)使用<c:url>和<c:param>对中文名进行URL编码
*4 下载文件
a)对传过来的中文编码进行URL解码b)通过UUID文件名,反向查到该文件所在的真实目录
5 文件上传下载与数据库结合
a)在将上传文件保存的同时,写往数据库表,一个上传文件对应一条记录,确保uuidFileName双方一致思考:
a)上传时,先硬盘,再表?
b)下载时,先硬盘,再表?
c)删除时,先硬盘,再表?
d)是否需要事务支持?
<html>
<head>
<script type="text/javascript">
//全局变量
var time = 0;
function addLine(addButton){
//创建内部div对象
var divElement = document.createElement("div");
//创建input对象[file类型]
var inputElement1 = document.createElement("input");
inputElement1.type="file";
inputElement1.name="upfile";
//创建input对象[button类型]
var inputElement2 = document.createElement("input");
inputElement2.type="button";
inputElement2.value="删除";
//对删除按钮添加事件监听
inputElement2.οnclick=function(){
//取得该按钮所在行的直接父元素
var divElement = this.parentNode.parentNode;
//通过父元素删除直接子元素
divElement.removeChild(this.parentNode);
time--;
if(time < 5){
//按钮生效
addButton.disabled=false;
//addButton.style.visibility="visible";
}
}
//依次将file类型和button类型的input对象加入到内部div对象中
divElement.appendChild(inputElement1);
divElement.appendChild(inputElement2);
//再次内部div对象加入到外部div对象
var outDivElement = document.getElementById("outDiv");
outDivElement.appendChild(divElement);
time++;
if(time == 5){
//将按钮失效
addButton.disabled=true;
//addButton.style.visibility="hidden";
}
}
</script>
</head>
<body>
<form
action="${pageContext.request.contextPath}/UploadServlet"
method="POST"
enctype="multipart/form-data">
<table border="1" align="center">
<caption>文件上传</caption>
<tr>
<th>上传用户</th>
<td><input type="text" name="username"/></td>
</tr>
<tr>
<th></th>
<td>
<div id="outDiv">
<%--
<div>
<input type="file" name="upfile"/>
<input type="button" value="删除"/>
</div>
--%>
</div>
</td>
</tr>
<tr>
<th></th>
<td>
<input
type="button"
value="添加上传文件"
οnclick="addLine(this)"
/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="上传"/>
<a href="${pageContext.request.contextPath}/ListFileServlet">
显示下载文件
</a>
</td>
</tr>
</table>
</form>
</body>
</html>
写Servlet控制上传文件:
public class UploadServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
try {
User user = UploadUtil.doUpload(request);
String uploadPath = this.getServletContext().getRealPath(UploadUtil.uploadPath);
List<Up> upList = new ArrayList<Up>();
//写入硬盘
UploadUtil.doSave(user,uploadPath,upList);
//写入数据库表
UpService upService = new UpService();
upService.addUps(upList);
request.setAttribute("message","上传文件成功");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response);
}catch(UpfileSizeException e){
e.printStackTrace();
request.setAttribute("message","<font color='green'>上传文件大小限制在200K以内</font>");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response);
}catch(UpfileTypeException e){
e.printStackTrace();
request.setAttribute("message","<font color='red'>只能上传JPG格式的文件</font>");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response);
}catch(NoUpfileException e){
e.printStackTrace();
request.setAttribute("message","<font color='blue'>无上传文件</font>");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response);
}catch (Exception e) {
e.printStackTrace();
request.setAttribute("message","上传文件失败");
request.getRequestDispatcher("/WEB-INF/message.jsp").forward(request,response);
}
}
}