![5854046353316f1940cead4c1850b0bf.png](https://img-blog.csdnimg.cn/img_convert/5854046353316f1940cead4c1850b0bf.png)
文件的上传下载
以往我们让浏览器和服务器之间传输的都是普通文本数据,那么如果是文件怎么办?那么接下来我们就通过一个案例给大家展现一下文件的上传和下载
![25bca9df8e56610cdb25e26fc8896555.png](https://img-blog.csdnimg.cn/img_convert/25bca9df8e56610cdb25e26fc8896555.png)
目标1:向上数据库中增加一条学生信息,同时携带学生照片(文件的上传)
目标2:在浏览学生信息时,可以查看学生图片,并提供下载按钮(文件的下载)
1文件的上传
1.1页面展示效果
![96e4798efa66ce7f91b930bb7b0dad11.png](https://img-blog.csdnimg.cn/img_convert/96e4798efa66ce7f91b930bb7b0dad11.png)
1.2页面代码编写
<form action="fileUpload" method="post" enctype="multipart/form-data">
姓名<input type="text" name="stuname"><br/>
性别<input type="text" name="stugender"><br/>
年龄<input type="text" name="stuage"><br/>
照片<input type="file" name="filename"><br/>
<input type="submit">
</form>
注意:form表单的提交方式必须是post同时设置enctype属性必须是 multpart/form-data
1.3准备文件上传需要的jar包
![2fa02beaf99190805259b79a42f41038.png](https://img-blog.csdnimg.cn/img_convert/2fa02beaf99190805259b79a42f41038.png)
1.4后台收文件并保存到指定目录
package com.bjsxt.controller;
import com.bjsxt.pojo.Student;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
@WebServlet("/fileUpload")
public class FileUpload extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*获得文件上传工厂对象*/
FileItemFactory fileItemFactory =new DiskFileItemFactory();
/*获得文件上传组件*/
ServletFileUpload fileUpload=new ServletFileUpload(fileItemFactory);
try {
/*解析请求
表单中的每一个提交项都是一个Fileitem
* */
List<FileItem> list = fileUpload.parseRequest(req);
for (FileItem item: list) {
/*System.out.println("name"+item.getFieldName()
+"文件名"+item.getName()
+"数据大小"+item.getSize()
+"文件类型"+item.getContentType()
+"是不是文本表单项"+item.isFormField()
);*/
if(!item.isFormField()){
/*如果是文件 那么写入一个指定的目录*/
item.write(new File("d:/img/"+item.getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
![a4b90dec0f04771faa1c73f8f09c606c.png](https://img-blog.csdnimg.cn/img_convert/a4b90dec0f04771faa1c73f8f09c606c.png)
1.5文件上传常见问题处理
问题1 中文文件名乱码
解决:设置请求编码
// 设置请求编码为UTF-8
req.setCharacterEncoding("UTF-8");
// 通过文件上传工具类设置编码亦可
servletFileUpload.setHeaderEncoding("UTF-8");
问题2:图片存储路径不在项目中,不能通过网略访问
解决:使用相对路径将文件目录存储项目中
/*指定文件的保存路径*/
String dir = req.getServletContext().getRealPath("/upload");
问题3:多个同名文件上传存在命名冲突问题
解决:使用UUID生成文件名
/*指定文件的保存路径*/
String dir = req.getServletContext().getRealPath("/upload");
/*处理文件名*/
String name = item.getName();
String newName=UUID.randomUUID().toString()+ name.substring(name.lastIndexOf("."));
item.write(new File(dir,newName));
问题4:文件大小不能控制
解决:通过item.getSize获取文件大小后判断
if(ietm.getSize()>20*1024){
req.setAttribute(s:"msg",o:"文件最大是20k");
req.getRequestDispatcher(s:"/save.jsp").forward(req,resp);
return;
}
或者
fileUpload.setSizeMax(20*1024);
但是后者会直接报错,用户体验感不好
问题5:文件类型不能控制
解决:通过截取后缀名判断
![f54338aeb5d30ba288ab17da7e4acd54.png](https://img-blog.csdnimg.cn/img_convert/f54338aeb5d30ba288ab17da7e4acd54.png)
if(!(".png".equals(substring)||".gif".equals(substring)||".jgp".equals(substring))){
req.setAttribute(s:"msg",o:"文件类型只可以是图片");
req.getRequestDispatcher(s:"/save.jsp").forward(req.resp);
return;
}
问题6:如何获取普通表单项的值
解决: isFormField判断,通过getFieldName方法获取值
if(item.isFormField()){
if("stuname".equals(item.getFieldName())){
String stuname = item.getString("UTF-8");
student.setStuname(stuname);
}
if("stuage".equals(item.getFieldName())){
String stuage = item.getString("UTF-8");
student.setStuage(Integer.parseInt(stuage));
}
if("stugender".equals(item.getFieldName())){
String stugender = item.getString("UTF-8");
student.setStugender(Integer.parseInt(stugender));
}
}
uploadController优化后的代码
package com.bjsxt.controller;
import com.bjsxt.pojo.Student;
import com.bjsxt.service.StudentService;
import com.bjsxt.service.impl.StudentServiceImpl;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;
@WebServlet("/fileUpload")
public class FileUpload extends HttpServlet {
private StudentService studentService=new StudentServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
FileItemFactory fileItemFactory =new DiskFileItemFactory();
ServletFileUpload fileUpload=new ServletFileUpload(fileItemFactory);
fileUpload.setHeaderEncoding("UTF-8");
Student student =new Student();
try {
List<FileItem> list = fileUpload.parseRequest(req);
for (FileItem item: list) {
File dir =new File(req.getServletContext().getRealPath("/upload"));
if(!dir.exists()){
dir.mkdirs();
}
if(!item.isFormField()){
String uuid = UUID.randomUUID().toString();
String filename = item.getName();
String fileType=filename.substring(filename.lastIndexOf("."));
String ufilename=uuid+fileType;
item.write(new File(dir,ufilename));
student.setFilename(ufilename);
student.setFiletype(fileType);
}else{
if("stuname".equals(item.getFieldName())){
String stuname =item.getString("utf-8");
student.setStuname(stuname);
}
if("stugender".equals(item.getFieldName())){
String stugender =item.getString("utf-8");
student.setStugender(stugender);
}
if("stuage".equals(item.getFieldName())){
Integer stuage =Integer.parseInt(item.getString());
student.setStuage(stuage);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
int i = studentService.addStudent(student);
if(i>0){
resp.sendRedirect("studentController");
}else{
req.setAttribute("msg","添加失败");
req.getRequestDispatcher("addStudent.jsp").forward(req,resp);
}
}
}
在ShowStudent.jsp显示图片
< c:forEach items="${pageBean.list}" var="student">
<tr>
<td>${stu.stuid}</td>
<td>${stu.stuname}</td>
<td>${stu.stuage}</td>
<td>${stu.stugender}</td>
<td>
<img src="upload/${student.filename}" width="70px" height="40px">
</td>
<td> ${student.filetype}</td>
<td>
<a href="javascript:void(0)">下载</a>
</td>
</tr>
</c:forEach>
2文件的下载
2.1页面效果展示
点击下载按钮实现文件下载功能
![80d6c5db2c9957aab64a9d1ee3556342.png](https://img-blog.csdnimg.cn/img_convert/80d6c5db2c9957aab64a9d1ee3556342.png)
2.2后台Controller
package com.bjsxt.controller;
import org.apache.commons.io.IOUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
@WebServlet("/fileDownload")
public class FileDownload extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*获取要下载的文件名*/
String filename = req.getParameter("filename");
String filetype = req.getParameter("filetype");
/*构建指向文件的File类*/
String realPath = req.getServletContext().getRealPath("/upload");
System.out.println(realPath);
File file =new File(realPath,filename);
System.out.println(file);
/*构建从文件获取的IO流*/
InputStream is =new FileInputStream(file);
OutputStream os =resp.getOutputStream();
/*设置响应的数据大小*/
resp.setContentLength((int) file.length());
/*设置响应的文件类型*/
resp.setContentType(filetype);
/*设置响应头,告知浏览器响应 的信息为文件*/
resp.setHeader("Content-Disposition","attachment;filename="+filename);
IOUtils.copy(is,os);
}
}
2.3同步页面处理
<c:forEach items="${pageBean.list}" var="stu">
<tr>
<td>${stu.stuid}</td>
<td>${stu.stuname}</td>
<td>${stu.stuage}</td>
<td>${stu.stugender}</td>
<td>
<img alt="no图" width="100px" height="50px" src="upload/${stu.filename}">
</td>
<td>${stu.filetype}</td>
<td>
<a href="fileDownload?fileName=${stu.filename}&filetype=${stu.filetype}">下载</a>
</td>
</tr>
</c:forEach>
2.4异步页面处理
function showStudent(currentPage){
$.ajax({
type:'GET',
url:"studentController2?method=findByPage&stuname="+$("#stuname").val()+"&stuage="+$("#stuage").val()+"¤tPage="+currentPage+"&size="+$('#pageSize').val(),
data:null,
dataType:'json',
success:function(pagebean){
$('#studentBody').html('')
$.each(pagebean.list,function(i,e){
$('#studentBody').append(' <tr>n' +
' <td>'+e.stuid+'</td>n' +
' <td>'+e.stuname+'</td>n' +
' <td>'+e.stuage+'</td>n' +
' <td>'+e.stugender+'</td>n' +
' <td>n' +
' <img alt="no图" width="100px" height="50px" src="upload/'+e.filename+'">n' +
' </td>n' +
' <td>'+e.filetype+'</td>n' +
' <td>n' +
' <a href="fileDownload?fileName='+e.filename+'&filetype='+e.filetype+'">下载</a>n' +
' </td>n' +
' </tr>')
})
$('#currentPage').text(pagebean.currentPage)
$('#totalPage').text(pagebean.totalPage)
$('#totalSize').text(pagebean.totalSize)
$('#pageSize').val(pagebean.size)
$('#stuname').val(pagebean.stuname)
$('#stuage').val(pagebean.stuage)
}
})
}
本节作业:
实现文件的上传和下载案例