稍微复杂一些 直接使用Servlet实现有难度,一般使用apache commons组件中commons-fileUpload组件,大大降低操作的难度。
commons-fileUpload离不开commons-io组件
commons-fileUpload的常用类
FileItemFactory DiskFileItemFactory:工厂类,生产FileItem
FileItem:每个表单项都会被封装成一个FileItem对象
ServletFileUpload:实现上传操作,将表单数据封装到FileItem中
第一节 文件上传的实现
@WebServlet("/servlet/FileUpLoad")
public class FileUpLoad extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
//【A】创建文件上传的工厂对象
FileItemFactory factory=new DiskFileItemFactory();
//【B】获得文件上传的组件对象
ServletFileUpload upload=new ServletFileUpload(factory);
//设置文件上传的编码
upload.setHeaderEncoding("utf-8");
try {
//【C】 获得前台所有的表单数据
List<FileItem> list = upload.parseRequest(req);
String name="";
int age=0;
int score=0;
String filename="";
String filetype="";
for(FileItem item : list){
//System.out.println(item.getFieldName()+"--"+item.getSize()+"--"+item.getName()+"--"+item.getContentType()+"--"+item.isFormField());
if(!item.isFormField()){
//证明是文件表单
filetype=item.getContentType();
String subString = item.getName().substring(item.getName().lastIndexOf("."));
/******【F】设置上传文件的类型 .jpg .png .gif */
if(!(".jpg".equals(subString)||".png".equals(subString)||".gif".equals(subString))){
req.setAttribute("msg","上传文件的类型必须是图片");
req.getRequestDispatcher("/add.jsp").forward(req,resp);
return;
}
/*****【E】指定上传文件的大小*******/
if(item.getSize()>20*1024){
req.setAttribute("msg","文件最大为20k");
req.getRequestDispatcher("/add.jsp").forward(req,resp);
return;
}
/****【D】使用UUID保证文件不重复**********/
String uuid = UUID.randomUUID().toString();
// 1.jpg 1.1.jpg .jpg
filename=uuid+subString;
//文件的上传
/***【C】动态获得服务器目录*/
String realPath = req.getServletContext().getRealPath("/imgs");
System.out.println(realPath);
/****【B】创建文件夹*****/
File file=new File(realPath);
if(!file.exists()){
file.mkdirs();
}
item.write(new File(file,filename));
}else{
//文本表单项
if("name".equals(item.getFieldName())){
name = item.getString("utf-8");
}
if("age".equals(item.getFieldName())){
age = Integer.parseInt(item.getString());
}
if("score".equals(item.getFieldName())){
score =Integer.parseInt(item.getString());
}
}
}
Student student=new Student(0, name, age, score, filename, filetype);
//执行添加的操作
StudentService studentService=new StudentServiceImpl();
int i = studentService.add(student);
if(i>0){
resp.sendRedirect(req.getContextPath()+"/show2.jsp");
}else {
req.setAttribute("msg","注册失败");
req.getRequestDispatcher("/add.jsp").forward(req,resp);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 遇到的问题:
* 1、文件上传的时候名字中文乱码: o
* A、 req.setCharacterEncoding("utf-8");
* B、 upload.setHeaderEncoding("utf-8");
* 2、上传的文件夹名称必须给出:
* file.exists()
* 3、上传不到当前服务器的路径中:
* String realPath = req.getServletContext().getRealPath("/imgs");
* 4、相同的图片名称会覆盖
* String uuid = UUID.randomUUID().toString();
* 5、无法指定上传文件的大小:
* A、upload.setSizeMax(20);
* B、item.getSize()>20*102
* 6、无法指定上传文件的类型 :
* ".jpg".equals(subString)
第三节 文件下载实现
@WebServlet("/servlet/FileDownLoad")
public class FileDownLoad extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String realPath = req.getServletContext().getRealPath("/imgs");
String filename = req.getParameter("filename");
File file=new File(realPath+"/"+filename);
//[A]从服务器中把指定的文件读过来
InputStream input=new FileInputStream(file);
//设置下载文本的长度
resp.setContentLength((int) file.length());
//设置文本的类型
resp.setContentType(req.getParameter("filetype"));
resp.setHeader("Content-Disposition","attachment;filename="+filename);
//[B]把读过来的文件写到本地
OutputStream output=resp.getOutputStream();
IOUtils.copy(input,output);
output.close();
input.close();
}}