文件上传-sevlet完成

文件上传的场景

文件上传,是程序开发中必须会使用到一个功能,比如:

1:添加商品,用户头像,文章封面等需求。

2:富文本编辑(附件件文件上传)。

文件上传的原理

文件上传的原理就是共享资源,大家都可以看你的在平台上上传的文件。也就是把用户的自己电脑中的文件通过程序上传到服务器的过程。

准备工作

文件上传需要jar包:commons-fileupload,commons-io

在pom.xml文件添加如下代码

 1 <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
 2 <dependency>
 3     <groupId>commons-fileupload</groupId>
 4     <artifactId>commons-fileupload</artifactId>
 5     <version>1.4</version>
 6 </dependency>
 7 <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
 8 <dependency>
 9     <groupId>commons-io</groupId>
10     <artifactId>commons-io</artifactId>
11     <version>2.6</version>
12 </dependency>

添加web支持,并编写index.jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <body>
        <%--
        GET:上传文件大小有限制
        POST:上传文件大小没有限制
         ${pageContext.request.contextPath}
         --%>
        <form action="upload.do" enctype="multipart/form-data"  method="post">
            上传用户:<input type="text" name="username"><br/>
            <P><input type="file" name="file1"></P>
            <P><input type="file" name="file1"></P>
            <P><input type="submit" value="提交"> | <input type="reset"></P>
        </form>
    </body>
</html>

解释

1:对于post请求来说:
数据量大小:
原则上post是默认无限制的,多大的数据都可以请求,

2:get请求限制

理论上GET请求数据长度没有限制的,真正起到限制的是浏览器对其长度进行了限制。
Google (chrome):URL最大长度限制为8182个字符。
Firefox (Browser):URL的长度限制为65,536个字符。

info.jsp页面

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%=request.getAttribute("msg")%>
</body>
</html>

先在web.xml中注册servlet

<servlet>
      <servlet-name>upload</servlet-name>
      <servlet-class>com.wang.FileSerlvet</servlet-class>
</servlet>
<servlet-mapping>
      <servlet-name>upload</servlet-name>
      <url-pattern>/upload.do</url-pattern>
</servlet-mapping>

编写文件上传FileServlet类

  1 public class FileSerlvet extends HttpServlet {
  2     private static final long serialVersionUID = 1L;
  7 protected void doPost(HttpServletRequest request, HttpServletResponse response)
  8         throws ServletException, IOException { 11     // 判断上传的文件普通表单还是带文件的表单
 12     if (!ServletFileUpload.isMultipartContent(request)) {
 13         return;//终止方法运行,说明这是一个普通的表单,直接返回
 14     }
 15     //创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访间上传的文件;
 16     String uploadPath =this.getServletContext().getRealPath("/WEB-INF/upload");
 17     File uploadFile = new File(uploadPath);
 18     if (!uploadFile.exists()){
 19     uploadFile.mkdir(); //创建这个月录
 20     }
 21     // 创建上传文件的保存路径,建议在WEB-INF路径下,安全,用户无法直接访问上传的文件
 22     String tmpPath = this.getServletContext().getRealPath("/WEB-INF/tmp");
 23     File file = new File(tmpPath);
 24     if (!file.exists()) {
 25         file.mkdir();//创建临时目录
 26     }
 27     // 处理上传的文件,一般都需要通过流来获取,我们可以使用 request, getInputstream(),原生态的文件上传流获取,十分麻烦
 28     // 但是我们都建议使用 Apache的文件上传组件来实现, common-fileupload,它需要旅 commons-io组件;
 29     try {
 30         // 创建DiskFileItemFactory对象,处理文件路径或者大小限制
 31         DiskFileItemFactory factory = getDiskFileItemFactory(file);
 32         /*
 33          * //通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件 factory.setSizeThreshold(1024 *
 34          * 1024); //缓存区大小为1M factory.setRepository (file);//临时目录的保存目录,需要一个File
 35          */
 36         // 2、获取ServletFileUpload
 37         ServletFileUpload upload = getServletFileUpload(factory);
 38         // 3、处理上传文件
 39         // 把前端请求解析,封装成FileItem对象,需要从ServletFileUpload对象中获取
 40         String msg = uploadParseRequest(upload, request, uploadPath);
 41         // Servlet请求转发消息
 42         System.out.println(msg);
 43         if(msg == "文件上传成功!") {
 44             // Servlet请求转发消息
 45             request.setAttribute("msg",msg);
 46             request.getRequestDispatcher("info.jsp").forward(request, response);
 47         }else {
 48             msg ="请上传文件";
 49             request.setAttribute("msg",msg);
 50             request.getRequestDispatcher("info.jsp").forward(request, response);
 51         }
 52     } catch (FileUploadException e) {
 53         // TODO 自动生成的 catch 块
 54         e.printStackTrace();
 55     }
 56 }
 57 public static DiskFileItemFactory getDiskFileItemFactory(File file) {
 58     DiskFileItemFactory factory = new DiskFileItemFactory();
 59     // 通过这个工厂设置一个缓冲区,当上传的文件大于这个缓冲区的时候,将他放到临时文件中;
 60     factory.setSizeThreshold(1024 * 1024);// 缓冲区大小为1M
 61     factory.setRepository(file);// 临时目录的保存目录,需要一个file
 62     return factory;
 63 }
 64 public static ServletFileUpload getServletFileUpload(DiskFileItemFactory factory) {
 65     ServletFileUpload upload = new ServletFileUpload(factory);
 66     // 监听长传进度
 67     upload.setProgressListener(new ProgressListener() {
 68         // pBYtesRead:已读取到的文件大小
 69         // pContextLength:文件大小
 70         public void update(long pBytesRead, long pContentLength, int pItems) {
 71             System.out.println("总大小:" + pContentLength + "已上传:" + pBytesRead);
 72         }
 73     });
 74     // 处理乱码问题
 75     upload.setHeaderEncoding("UTF-8");
 76     // 设置单个文件的最大值
 77     upload.setFileSizeMax(1024 * 1024 * 10);
 78     // 设置总共能够上传文件的大小
 79     // 1024 = 1kb * 1024 = 1M * 10 = 10м
 80     return upload;
 81 }
 82 public static String uploadParseRequest(ServletFileUpload upload, HttpServletRequest request, String uploadPath)
 83         throws FileUploadException, IOException {
 84     String msg = "";
 85     // 把前端请求解析,封装成FileItem对象
 86     List<FileItem> fileItems = upload.parseRequest(request);
 87     for (FileItem fileItem : fileItems) {
 88         if (fileItem.isFormField()) {// 判断上传的文件是普通的表单还是带文件的表单
 89             // getFieldName指的是前端表单控件的name;
 90             String name = fileItem.getFieldName();
 91             String value = fileItem.getString("UTF-8"); // 处理乱码
 92             System.out.println(name + ": " + value);
 93         } else {// 判断它是上传的文件
 94             // ============处理文件==============
 95             // 拿到文件名
 96             String uploadFileName = fileItem.getName();
 97             System.out.println("上传的文件名: " + uploadFileName);
 98             if (uploadFileName.trim().equals("") || uploadFileName == null) {
 99                 continue;
100             }
101             // 获得上传的文件名/images/girl/paojie.png
102             String fileName = uploadFileName.substring(uploadFileName.lastIndexOf("/") + 1);
103             // 获得文件的后缀名
104             String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
105             /*
106              * 如果文件后缀名fileExtName不是我们所需要的 就直按return.不处理,告诉用户文件类型不对。
107              */
108             System.out.println("文件信息[件名: " + fileName + " ---文件类型" + fileExtName + "]");
109             // 可以使用UID(唯一识别的通用码),保证文件名唯
110             // 0UID. randomUUID(),随机生一个唯一识别的通用码;
111             String uuidPath = UUID.randomUUID().toString();
112             // ================处理文件完毕==============
113             // 存到哪? uploadPath
114             // 文件真实存在的路径realPath
115             String realPath = uploadPath + "/" + uuidPath;
116             // 给每个文件创建一个对应的文件夹
117             File realPathFile = new File(realPath);
118             if (!realPathFile.exists()) {
119                 realPathFile.mkdir();
120             }
121             // ==============存放地址完毕==============
122              // 获得文件上传的流
123             InputStream inputStream = fileItem.getInputStream();
124             // 创建一个文件输出流
125             // realPath =真实的文件夹;
126             // 差了一个文件;加上翰出文件的名产"/"+uuidFileName
127             FileOutputStream fos = new FileOutputStream(realPath + "/" + fileName);
128             // 创建一个缓冲区
129             byte[] buffer = new byte[1024 * 1024];
130             // 判断是否读取完毕
131             int len = 0;
132             // 如果大于0说明还存在数据;
133             while ((len = inputStream.read(buffer)) > 0) {
134                 fos.write(buffer, 0, len);
135             }
136             // 关闭流
137             fos.close();
138             inputStream.close();
139             msg = "文件上传成功!";
140             fileItem.delete(); // 上传成功,清除临时文件
141             //=============文件传输完成=============
142         }
143     }
144     return msg;
145 }

 

上一篇:上传组件upload


下一篇:html+大文件上传