大家好,又见面了,我是你们的朋友全栈君。
Java代码实现文件上传
在文件上传过程中,文件是以流的形式从浏览器提交到服务端的。一般情况下采用Apache公司的开源文件上传组件common-fileupioad来进行文件的上传。由于common-fileupioad依赖于common-io,所以还要下载common-io这个包。
准备工作:
下载jar包,建立项目,把包导入lib目录,将lib添加到项目输出目录,配置好Tomcat。
我们只编写简单的前端和全部的后端代码,美化前端的任务交给前端管理员
文件上传四个要求:
- 为保证服务器安全,上传文件应该放在外界无直接访问的目录下,比如放于WEB-INF目录下。
- 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
- 要限制上传文件的最大值。
- 可以限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。
中点需要了解的两个类:
Filetem类:
//isFormField方法用于判断FileItem类对象封装的数据是一个普通文本表单
//还是一个文件表单,如果是普通表单字段则返回true,否则返回false
boolean isFormField();
//getFieldName方法用于返回表单标签name属性的值。
String getFieldName();
//getString方法用于将FileItem对象中保存的数据流内容以一个字符串返回
String getString();
//getName方法用于获得文件上传字段中的文件名。
String getName();
//以流的形式返回上传文件的数据内容。
InputStream getInputStream()
//delete方法用来清空FileItem类对象中存放的主体内容
//如果主体内容被保存在临时文件中,delete方法将删除该临时文件。
void delete();
ServletFileUpload 类:
代码实现
method必须是post,post对上传的数据没有限制,get无法获取大型文件
form表单默认提交纯文本,要上传文件就要更改enctype属性为文件流
-
编写上传文件的upload.jsp文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>上传</title> </head> <body> <form action="${pageContext.request.contextPath}/hh" enctype="multipart/form-data" method="post"> 上传用户:<input type="text" name="username"><br/> 上传文件1:<input type="file" name="file1"><br/> 上传文件2:<input type="file" name="file2"><br/> <input type="submit" value="提交"> </form> </body> </html>
-
编写UploadServlet.java文件:
-
判断上传的文件是带文件的表单还是普通的表单。如果是普通文件,直接返回;如果带文件的表单就执行在一个步骤。
-
创建一个上传文件的保存路径,为了安全,建议在WEB-INF目录下创建upload目录(WEB-INF目录下的文件,用户不能直接访问)。
-
需要创建一个临时路径,假如文件超过预期的大小,就将其放入临时文件中,过段时间自动删除或提醒用户进行后续操作,同样,在WEB-INF下建立tmp文件。由于这个目录不应该由人来创建,所以用系统判断来创建。
-
处理上传文件一般用流来获取我们不建议用原生态的文件上传流来获取,建议用之前提到的Apache的上传文件组件来实现获取流。
-
创建DiskFileItemFactory对象,处理文件上传路径,或大小限制。(这一步可以抽成方法,解耦)
-
由构造器传入创建DiskFileItemFactory对象来创建ServletFileUpload对象。
-
设置监听对象,监听文件上传进度(注意参数的传递)。
-
封装成一个fileitem类,的到upload对象。
处理乱码问题,设置单个文件上传的最大值,设置总共能上传文件的大小。
-
-
把前端请求解析,封装成fileitem对象,拿到一个集合,遍历集合。
- 注意判断是否是普通表单还是带文件的表单
- 并且处理乱码问题
- 如果判断后是需要上传的表单,就获取文件地址,判断地址是否合法(是否为空或地址不存在)
- 过得文件名字,获得文件后缀名。
- 使用UUID来保证文件名字唯一。(UUID:随机生成一个唯一识别的通用码)
- 至此处理文件完毕
-
编辑处理文件的真实路径(文件存在路径(uploadpath)+/+文件名),给每个文件创建对应的文件。至此存放地址处理完毕
-
获得文件上传的流(fileitem.getinputstream),创建一个文件输入流。创建字符缓冲区,并判断文件是否读取完毕。最后按顺序关闭outputstream和inputstream。至此文件传输完毕。
package com.david.uploadfile; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.ProgressListener; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import javax.servlet.http.HttpServletRequest; import java.io.*; import java.util.List; import java.util.UUID; public class UpLoadServlet extends javax.servlet.http.HttpServlet { protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { doGet(request,response); } protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException { try { if (!ServletFileUpload.isMultipartContent(request)) { return; } String uploadPath = this.getServletContext().getRealPath("/WEB-INF/upload"); File uploadfile = new File(uploadPath); if (!uploadfile.exists()) { uploadfile.mkdir(); } String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp"); File file = new File(tmpPath); if (!file.exists()) { file.mkdir(); } DiskFileItemFactory factory = getDiskFileItemFactory(file); ServletFileUpload upload = getServletFileUpload(factory); String msg = uploadParseRequest(upload, request, uploadPath); request.setAttribute("msg", msg); request.getRequestDispatcher("info.jsp").forward(request, response); }catch (FileUploadBase.FileUploadIOException e){ e.printStackTrace(); } catch (FileUploadException e) { e.printStackTrace(); } } private static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath) throws FileUploadException, IOException { String msg = ""; List<FileItem> fileItems = upload.parseRequest(request); for (FileItem fileItem : fileItems) { if (fileItem.isFormField()){ String name = fileItem.getFieldName(); String value = fileItem.getString("UTF-8"); System.out.println(name+":"+value); }else { String uploadFileName = fileItem.getName(); System.out.println("上传的文件名"+uploadFileName); if (uploadFileName.trim().equals("")||uploadFileName==null){ continue; } String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/")+1); String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1); System.out.println("文件信息 [件名:"+fileName+"---文件类型"+fileExtName+"]"); String uuidPath = UUID.randomUUID().toString(); String realPath = uploadPath+"/"+uuidPath; File realPathfile = new File(realPath); if (!realPathfile.exists()){ realPathfile.mkdir(); } InputStream inputStream = fileItem.getInputStream(); FileOutputStream fos = new FileOutputStream(realPath+"/"+fileName); byte[] buffer = new byte[1024*1024]; int len = 0; while ((len=inputStream.read(buffer))>0){ fos.write(buffer,0,len); } fos.close(); inputStream.close(); msg = "文件上传成功!"; fileItem.delete(); } } return msg; } private static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) { ServletFileUpload upload = new ServletFileUpload(factory); upload.setProgressListener(new ProgressListener() { @Override public void update(long pBytesRead, long pContentLength, int pItems) { System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead); } }); upload.setHeaderEncoding("UTF-8"); upload.setFileSizeMax(1024*1024*10); upload.setSizeMax(1024*1024*10); return upload; } private static DiskFileItemFactory getDiskFileItemFactory(File file) { DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setSizeThreshold(1024*1024); factory.setRepository(file); return factory; } }
尽量保证Servlet类中代码干净,将可以封装的代码封装起来,需要时调用
-
-
写一个提示信息的界面关联servlet。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> ${msg} </body> </html>
-
配置web.xml,编辑index.jsp首页。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <servlet> <servlet-name>UpLoadFileServlet</servlet-name> <servlet-class>com.david.uploadfile.UpLoadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UpLoadFileServlet</servlet-name> <url-pattern>/hh</url-pattern> </servlet-mapping> </web-app>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>首页</title> </head> <body> <a href="upload.jsp">点击上传</a> </body> </html>
-
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/146684.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...