zoukankan      html  css  js  c++  java
  • servlet3.0实现文件上传功能

    servlet3.0

    必须使用tomcat7以上的技术才能支持servlet3.0
    servlet3.0 比 servlet2.5 多提供了三个新特性:
      注解开发:方便
      文件上传:有些api不是特别全
      异步请求:基本不用,使用ajax替代

    文件上传技术:

    1.servlet3.0
    2.JSPSmartUpload 嵌入到JSP中完成文件上传,主要用于model1年代
    3.FileUpload Apache的文件上传的组件。
    4.Struts2 底层是FileUpload。
    。。。

    文件上传的三要素:

      1.表单的提交方式必须是post,因为get有大小限制;
      2.表单中需要有文件上传的表单元素:<input type= "file" name="upload">这个元素必须要有name属性和值;
      3.表单的enctype属性的值必须是multipart/form-data

    使用注解代替web.xml

      使用注解配置servlet

        @WebServlet(urlPatterns="/ServletName",loadOnStartup=2,initParams={@WebInitParam(name="username",value=""),@WebInitParam(name="password",value="")})

      使用注解开发Listener:
        @WebListener
      使用注解开发Filter;
        @WebFilter(urlPatterns="/*")

    注意:
    当没有设置enctype属性的时候,只能获得文件的名称,没有文件内容;
    设置enctype属性为multipart/form-data后可以获得文件名及文件内容;

    使用servlet3.0实现文件上传:
      在创建servlet的时候需要额外加一个注解@MultipartConfig,否则3.0的request的提供的新的方法无法使用。

    使用servlet3.0注解技术实现文件上传代码示例

     1 <html>
     2 <head>
     3 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
     4 <title>Hello Miss Dang</title>
     5 </head>
     6 <body>
     7     <h1>index.jsp</h1>
     8     <form action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data">
     9         文件描述<input  type="text" name="filedesc" /><br/>
    10         请选择需要上传的文件:<input type="file" name="upload" />
    11         <input type="submit" value="上传" />
    12     </form>
    13 </body>
    14 </html>
    前端表单上传文件代码示例
     1 package servlet;
     2 
     3 import java.io.FileOutputStream;
     4 import java.io.IOException;
     5 import java.io.InputStream;
     6 import java.io.OutputStream;
     7 
     8 import javax.servlet.ServletException;
     9 import javax.servlet.annotation.MultipartConfig;
    10 import javax.servlet.annotation.WebServlet;
    11 import javax.servlet.http.HttpServlet;
    12 import javax.servlet.http.HttpServletRequest;
    13 import javax.servlet.http.HttpServletResponse;
    14 import javax.servlet.http.Part;
    15 
    16 @WebServlet("/UploadServlet")
    17 @MultipartConfig
    18 public class UploadServlet extends HttpServlet {
    19     
    20     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    21         doPost(request, response);
    22     }
    23 
    24     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    25         request.setCharacterEncoding("UTF-8");
    26         System.out.println("文件描述:"+request.getParameter("filedesc"));
    27         Part part = request.getPart("upload");
    28         System.out.println("文件大小:"+part.getSize());
    29         System.out.println("form表单中part部分的name属性名称"+part.getName());
    30         //获得上传的文件名称
    31         String header = part.getHeader("Content-Disposition");//获得Content-Disposition的头信息
    32         int idx = header.lastIndexOf("filename="");//获取filename=“字符串的开始下标
    33         String fileName = header.substring(idx+"filename="".length(), header.length()-1);
    34         System.out.println("文件名:"+fileName);
    35         //获得文件内容:
    36         InputStream is = part.getInputStream();
    37         OutputStream os = new FileOutputStream(this.getServletContext().getRealPath("/upload")+"/"+fileName);
    38         byte[] bt = new byte[1024];
    39         int len = 0;
    40         while ((len = is.read(bt)) != -1) {
    41             os.write(bt, 0, len);
    42         }
    43         is.close();
    44         os.close();
    45     }
    46 
    47 }
    后端servlet代码示例

     文件上传问题:文件名重名

    使用随机的唯一文件名:
    使用uuid作为随机文件名
    UUID。randomUUID().toString().replace("_","")+"_"+fileName;

    文件上传问题:文件夹问题(一个目录下存放文件过多)

    一个目录下文件过多,导致打开都很慢,更别说读写操作更慢,影响性能。

    目录分离:
      按时间分:按周 按月分(按访问量来划分)
      按数量分:一个目录下存放n个文件,如果满了就创建新的目录存放。
      按用户分;
      按目录分离算法分:
        使用唯一文件名.hashCode();--得到一个代表当前这个文件的int类型的值,int类型占4个字节32位,可以让hashCode值&0xf;(oxf是十六进制数,代表15,内存中表示是1111),得到一个int值,可以用这个int值作为一级目录,让这个hashCode右移4位&0xf;得到一个int值,用这个int值作为二级目录,以此类推。

    1 public static String getFilePath(String fileName) {
    2         int code1 = fileName.hashCode();
    3         int d1 = code1 & 0xf;//获得一级目录
    4         int code2 = code1 >>> 4;
    5         int d2 = code2 & 0xf;//获得二级目录
    6         //可以根据自己的需求获得多级目录。
    7         return "/"+d1+"/"+d2;
    8     }

    判断文件夹是否存在,如果不存在创建

    File file = new File(path);
    if(!file.exits()){
      file.mkdirs();
    }

  • 相关阅读:
    使用webstorm来创建并且运行vue项目详细教程
    Jmeter后置处理器之Json提取器
    Linux常用命令
    Linux安装Mysql
    Linux安装JDK
    redhat6.5安装yum
    Linux安装python
    Linux安装Tomcat
    搞懂Redis协议RESP
    1TB是多大?
  • 原文地址:https://www.cnblogs.com/laodang/p/9543569.html
Copyright © 2011-2022 走看看