JavaWeb处理文件上传
1.简述
在一个项目中,文件上传功能是十分常见的,经常要使用到,像最平常的就有设置账号头像。但是要完成这一功能,要解决哪些问题呢?怎样才可以实现这一功能呢?下面我就用一个具体示例来详细讲解一下吧~
2.文件上传分析
- 前端分析:普通表单提交默认 enctype =“application/x-www-form-urlencoded”,而要上传文件类型的表单需要设置enctype=“multipart/form-data”(它不对字符进行编码,用于发送二进制的文件),所以后端接收时不能再使用request.getParameter(),而是用request.getInputStream()解析二进制流,得到ServletInputStream对象。另外,表单提交方式必须为post。
- 后端分析:首先,要判断表单类型是否符合文件类型表单;其次,要创建上传的文件的存取路径;最后,就是使用fileUpload组件,实现文件上传。
3.示例讲解
说明:本次的示例用到的环境是maven+tomcat 9,tomcat 9以上的tomcat版本不适用,因为和fileUpload组件还不兼容。(这是因为fileUpload组件的ServletFileUpload包到了tomcat 10之后就找不到了,还没有更新修改)
3.1、导包
使用fileUpload组件需要引入两个jar包:
- commons-fileUpload.jar
- commons-io.jar
3.2、前端代码
测试页面index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>uploadFile test</title>
</head>
<body>
<form method="post" action="/upload.do" enctype="multipart/form-data">
上传用户:<input type="text" name="username"><br>
<p><input type="file" name="file1"></p>
<p><input type="file" name="file2"></p>
<p><input type="submit">|<input type="reset"></p>
</form>
</body>
</html>
测试结果页面message.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>文件上传</title>
</head>
<body>
<h1 align="center">${msg}</h1> <!--msg后端返回-->
</body>
</html>
3.3、后端代码
里面有很多拓展的功能代码块,标志着(可选)的代码可自行删去,看起来代码量就少了
总结下来就点:
- 判断上传的文件是普通表单还是带文件的表单
- 创新上传的文件保存的路径
- 设置缓存
- 处理上传的文件(重点掌握)
- 请求转发结果消息
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.判断上传的文件是普通表单还是带文件的表单
if (!ServletFileUpload.isMultipartContent(req)) {
return;//这是一个普通表单,直接返回终止方法运行
}
//2.创新上传的文件保存的路径 保存在WEB-INF路径下(因为安全,用户是无法直接访问到这个目录下的文件的)
String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload");
File uploadFile = new File(uploadPath);
if (!uploadFile.exists()) {
uploadFile.mkdir();//如果这个文件目录不存在,则创建它
}
//3.设置缓存,存放临时文件(即文件超过预期大小的话,则放在临时文件下,过几天会自动删除,或者提醒用户转为永久文件)
String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");
File tempFile = new File(tempPath);
if (!tempFile.exists()) {
uploadFile.mkdir();
}
//4.处理上传的文件 使用现有的Apache的文件上传组件(commons-fileupload 依赖)来实现
//4.1 创建DiskFileItemFactory对象 (处理文件上传路径或者大小限制)
DiskFileItemFactory factory = getDiskFileItemFactory(tempFile);
//4.2 工厂得到ServletFileUpload文件上传类
ServletFileUpload upload = new ServletFileUpload(factory);
//4.3 处理上传的文件
String msg = uploadParseRequest(upload,req,uploadPath);
//5.请求转发消息,返回运行结果
req.setAttribute("msg",msg);
req.getRequestDispatcher("/message.jsp").forward(req,resp);
}
//获得经过自己的一些要求处理后的DiskFileItemFactory对象 factory
public static DiskFileItemFactory getDiskFileItemFactory(File file){
//创建DiskFileItemFactory对象 (处理文件上传路径或者大小限制)
DiskFileItemFactory factory = new DiskFileItemFactory();
factory.setSizeThreshold(1024*1024);//设置缓存区大小(可选)
factory.setRepository(file);//这个是为缓存区大小设置一个仓库 即目录文件(可选)
return factory;
}
//处理上传的文件,返回一个处理结果字符穿
public static String uploadParseRequest(ServletFileUpload upload,HttpServletRequest req,String uploadPath){
String msg = "";
//1. 监听文件文件上传进度(可选)
upload.setProgressListener(new ProgressListener() {
public void update(long l1, long l, int i) {
System.out.println("已上传:"+l1+" 总大小:"+l);
}
});
//2. 处理一些要上传的文件的约束(可选)
upload.setHeaderEncoding("UTF-8");//文件编码
upload.setFileSizeMax(1024*1024*2);//单个文件最大值
upload.setSizeMax(1024*1024*10);//总文件大小
//3 处理上传的文件(核心块)
//把前端请求解析,封装成一个FileItem对象
List<FileItem> fileItems = null;
try {
fileItems = upload.parseRequest(req);
for (FileItem fileItem : fileItems) {
//过滤掉大小不符合的文件
if (fileItem.getSize() > upload.getFileSizeMax()){
msg = "文件上传失败!文件大小大于10M";
continue;
}
//判断上传表单控件的 是type=text 还是type=file
if (fileItem.isFormField()){//type=text
String name = fileItem.getFieldName();//获取表单控件的名字
String value = fileItem.getString("UTF-8");//获取值,处理乱码
System.out.println(name+": "+value);
}else {//type=file
String uploadFileName = fileItem.getName();//获取上传文件名字(是带有路径在的)
System.out.println("上传的文件名:"+uploadFileName);
//可能存在文件名不合法的情况
if (uploadFileName == null || uploadFileName.trim().equals("")){
msg = "文件上传失败!文件名不符合规范";
continue;
}
//截取上传的文件名
String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/")+1);//从最后一个/后开始截取
//截取后缀名
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);//从最后一个.后开始截取
//可以使用UUID(唯一标识的通用码),保证文件名唯一
String uuidPath = UUID.randomUUID().toString();//生成一共随机的uuid
//创建存放目录
String realPath= uploadPath+"/"+uuidPath;
//给每个文件创建一个对应的文件夹
File realFile = new File(realPath);
if (!realFile.exists()){
realFile.mkdirs();
}
//文件传输,写入磁盘
fileItem.write(new File(realPath,fileName + "." + fileExtName));
msg = "文件上传成功!";
}
}
} catch (Exception e) {
e.printStackTrace();
}
return msg;
}
}
**注意:**不要忘了Servlet的注册噢~
以上就是关于文件上传的全部内容啦~内容并不多,拿上代码去自己电脑测试学习去吧,对于示例代码有报错的可以提问出来帮你解决哦!