广州北大青鸟计算机职业培训学校
互联网技术培训、软件技术培训、大数据培训、云计算培训、数据分析培训信息网
当前位置:网站首页 > 软件教程 > Java技术 > 正文

惠州JavaWeb如何处理文件上传的细节?_北大青鸟IT学校

作者:邓华发布时间:2021-06-10分类:Java技术浏览:1051


导读:JavaWeb如何处理文件上传的细节?最近惠州北大青鸟很多学员都在问这个问题,那么下面惠州北大青鸟学术部老师给大家解答一下这个问题。

JavaWeb如何处理文件上传的细节?最近惠州北大青鸟很多学员都在问这个问题,那么下面惠州北大青鸟学术部老师给大家解答一下这个问题。

  上述的代码虽然可以成功将文件上传到服务器上面的指定目录当中,但是文件上传功能有许多需要注意的小细节问题,以下列出的几点需要特别注意的

  1、为保证服务器安全,上传文件应该放在外界无法直接访问的目录下,比如放于WEB-INF目录下。

  2、为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名。

  3、为防止一个目录下面出现太多文件,要使用hash算法打散存储。

  4、要限制上传文件的最大值。

  5、要限制上传文件的类型,在收到上传文件名时,判断后缀名是否合法。

  针对上述提出的5点细节问题,我们来改进一下UploadHandleServlet,改进后的代码如下:

  1. package me.gacl.web.controller;


  2.  import java.io.File;

  3.  import java.io.FileOutputStream;

  4.  import java.io.IOException;

  5.  import java.io.InputStream;

  6.  import java.util.List;

  7.  import java.util.UUID;


  8.  import javax.servlet.ServletException;

  9.  import javax.servlet.http.HttpServlet;

  10.  import javax.servlet.http.HttpServletRequest;

  11.  import javax.servlet.http.HttpServletResponse;

  12.  import org.apache.commons.fileupload.FileItem;

  13.  import org.apache.commons.fileupload.FileUploadBase;

  14.  import org.apache.commons.fileupload.ProgressListener;

  15.  import org.apache.commons.fileupload.disk.DiskFileItemFactory;

  16.  import org.apache.commons.fileupload.servlet.ServletFileUpload;


  17.  /**

  18.  * @ClassName: UploadHandleServlet

  19.  * @Description: TODO(这里用一句话描述这个类的作用)

  20.  * @author: 孤傲苍狼

  21.  * @date: 2015-1-3 下午11:35:50

  22.  *

  23.  */

  24.  public class UploadHandleServlet extends HttpServlet {


  25.   public void doGet(HttpServletRequest request, HttpServletResponse response)

  26.     throws ServletException, IOException {

  27.      //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全

  28.      String savePath = this.getServletContext().getRealPath("/WEB-INF/upload");

  29.      //上传时生成的临时文件保存目录

  30.      String tempPath = this.getServletContext().getRealPath("/WEB-INF/temp");

  31.      File tmpFile = new File(tempPath);

  32.      if (!tmpFile.exists()) {

  33.       //创建临时目录

  34.       tmpFile.mkdir();

  35.      }


  36.      //消息提示

  37.      String message = "";

  38.      try{

  39.       //使用Apache文件上传组件处理文件上传步骤:

  40.       //1、创建一个DiskFileItemFactory工厂

  41.       DiskFileItemFactory factory = new DiskFileItemFactory();

  42.       //设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。

  43.       factory.setSizeThreshold(1024*100);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB

  44.       //设置上传时生成的临时文件的保存目录

  45.       factory.setRepository(tmpFile);

  46.       //2、创建一个文件上传解析器

  47.       ServletFileUpload upload = new ServletFileUpload(factory);

  48.       //监听文件上传进度

  49.       upload.setProgressListener(new ProgressListener(){

  50.        public void update(long pBytesRead, long pContentLength, int arg2) {

  51.         System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);

  52.         /**

  53.         * 文件大小为:14608,当前已处理:4096

  54.          文件大小为:14608,当前已处理:7367

  55.          文件大小为:14608,当前已处理:11419

  56.          文件大小为:14608,当前已处理:14608

  57.         */

  58.        }

  59.       });

  60.       //解决上传文件名的中文乱码

  61.       upload.setHeaderEncoding("UTF-8"); 

  62.       //3、判断提交上来的数据是否是上传表单的数据

  63.       if(!ServletFileUpload.isMultipartContent(request)){

  64.        //按照传统方式获取数据

  65.        return;

  66.       }


  67.       //设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB

  68.       upload.setFileSizeMax(1024*1024);

  69.       //设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB

  70.       upload.setSizeMax(1024*1024*10);

  71.       //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项

  72.       List<FileItem> list = upload.parseRequest(request);

  73.       for(FileItem item : list){

  74.        //如果fileitem中封装的是普通输入项的数据

  75.        if(item.isFormField()){

  76.         String name = item.getFieldName();

  77.         //解决普通输入项的数据的中文乱码问题

  78.         String value = item.getString("UTF-8");

  79.         //value = new String(value.getBytes("iso8859-1"),"UTF-8");

  80.         System.out.println(name + "=" + value);

  81.        }else{//如果fileitem中封装的是上传文件

  82.         //得到上传的文件名称,

  83.         String filename = item.getName();

  84.         System.out.println(filename);

  85.         if(filename==null || filename.trim().equals("")){

  86.          continue;

  87.         }

  88.         //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt

  89.         //处理获取到的上传文件的文件名的路径部分,只保留文件名部分

  90.         filename = filename.substring(filename.lastIndexOf("\\")+1);

  91.         //得到上传文件的扩展名

  92.         String fileExtName = filename.substring(filename.lastIndexOf(".")+1);

  93.         //如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法

  94.         System.out.println("上传的文件的扩展名是:"+fileExtName);

  95.         //获取item中的上传文件的输入流

  96.         InputStream in = item.getInputStream();

  97.         //得到文件保存的名称

  98.         String saveFilename = makeFileName(filename);

  99.         //得到文件的保存目录

  100.         String realSavePath = makePath(saveFilename, savePath);

  101.         //创建一个文件输出流

  102.         FileOutputStream out = new FileOutputStream(realSavePath + "\\" + saveFilename);

  103.        //创建一个缓冲区

  104.         byte buffer[] = new byte[1024];

  105.         //判断输入流中的数据是否已经读完的标识        int len = 0;

  106.         //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据

  107.         while((len=in.read(buffer))>0){

  108.          //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中

  109.          out.write(buffer, 0, len);

  110.         }

  111.         //关闭输入流

  112.         in.close();

  113.         //关闭输出流

  114.         out.close();        //删除处理文件上传时生成的临时文件        //item.delete();        message = "文件上传成功!";

  115.        }

  116.       }

  117.      }catch (FileUploadBase.FileSizeLimitExceededException e) {

  118.       e.printStackTrace();

  119.       request.setAttribute("message", "单个文件超出最大值!!!");

  120.       request.getRequestDispatcher("/message.jsp").forward(request, response);

  121.       return;

  122.      }catch (FileUploadBase.SizeLimitExceededException e) {

  123.       e.printStackTrace();

  124.       request.setAttribute("message", "上传文件的总的大小超出限制的最大值!!!");

  125.       request.getRequestDispatcher("/message.jsp").forward(request, response);

  126.       return;

  127.      }catch (Exception e) {

  128.       message= "文件上传失败!";

  129.       e.printStackTrace();

  130.      }

  131.      request.setAttribute("message",message);

  132.      request.getRequestDispatcher("/message.jsp").forward(request, response);

  133.   }


  134.   /**

  135.   * @Method: makeFileName

  136.   * @Description: 生成上传文件的文件名,文件名以:uuid+"_"+文件的原始名称

  137.   * @Anthor:孤傲苍狼

  138.   * @param filename 文件的原始名称

  139.   * @return uuid+"_"+文件的原始名称

  140.   */

  141.   private String makeFileName(String filename){ //2.jpg

  142.    //为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名

  143.    return UUID.randomUUID().toString() + "_" + filename;

  144.   }  

  145.   /**

  146.   * 为防止一个目录下面出现太多文件,要使用hash算法打散存储

  147.   * @Method: makePath

  148.   * @Description: 

  149.   * @Anthor:孤傲苍狼

  150.   *

  151.   * @param filename 文件名,要根据文件名生成存储目录

  152.   * @param savePath 文件存储路径

  153.   * @return 新的存储目录

  154.   */

  155.  private String makePath(String filename,String savePath){

  156.    //得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址

  157.    int hashcode = filename.hashCode();

  158.    int dir1 = hashcode&0xf; //0--15

  159.    int dir2 = (hashcode&0xf0)>>4; //0-15

  160.    //构造新的保存目录

  161.    String dir = savePath + "\\" + dir1 + "\\" + dir2; //upload\2\3 upload\3\5

  162.    //File既可以代表文件也可以代表目录   File file = new File(dir);

  163.   //如果目录不存在

  164.    if(!file.exists()){

  165.     //创建目录

  166.     file.mkdirs();

  167.   }

  168.    return dir;

  169.   }


  170.   public void doPost(HttpServletRequest request, HttpServletResponse response)

  171.     throws ServletException, IOException {


  172.    doGet(request, response);

  173.   }

  174.  }

针对上述提出的5点小细节问题进行改进之后,我们的文件上传功能就算是做得比较完善了。

想了解更多关于Java的资讯吗?可以来惠州北大青鸟新方舟校区了解一下。

java4.png

Java

标签:惠州计算机JAVA软件开发惠州计算机Java软件开发惠州计算机JAVA培训惠州计算机JAVA软件开发学校惠州计算机Java软件开发培训JAVAJava软件开发北大青鸟IT计算机学校北大青鸟IT软件学校北大青鸟IT学校


Java技术排行
标签列表
网站分类
文章归档
最近发表