zoukankan      html  css  js  c++  java
  • 文件上传(java)

      [1] 简介
            > 将一个客户端的本地的文件发送到服务器中保存。
            > 上传文件是通过流的形式将文件发送给服务器。
        
        [2] 表单的设置(文件上传一般利用表单)
        
            > 向服务器上传一个文件时,表单要使用post请求。
            > 表单的默认属性enctype="application/x-www-form-urlencoded"
                - 这个属性的意思是请求体中的内容将会使用URL编码
            > 上传文件的表单enctype需要设置为 multipart/form-data
                - multipart/form-data表示的是表单是一个多部件的表单
                - 如果类型设置为它,则我们的每一个表单项都会作为一个单独的部件发送给服务器。
                - 多个部件之间使用类似 -----------------------------7df2d08c0892 分割符来分开
            > 当表单设置为multipart/form-data时,我们request.getParameter()将失效,我们不能再通过该方法获取请求参数。

    1 <form action="${pageContext.request.contextPath }/FileUploadServlet" method="post" enctype="multipart/form-data">
    2         用户:<input type="text" name="name">
    3         <input type="file" name="photo"><br>
    4         <input type="submit" value="提交">
    5    </form>

        [3] FileUpload
            > 我们一般情况下使用commons-fileupload-1.3.1.jar这个工具来解析多部件请求。
            > fileupload 依赖 commons-io 所以我们要是Filtupload需要同时导入io包。
            > 核心类:
                DiskFileItemFactory
                    - 工厂类,用于构建一个解析器实例。
                    
                ServletFileUpload
                    - 解析器类,通过该类实例来解析request中的请求信息。
                    
                FileItem
                    - 工具会将我们请求中每一个部件,都封装为一个FileItem对象,处理文件上传时,只需要调用该对象的方法
                    -    方法:
                        boolean    isFormField()  --> 当前表单项是否是一个普通表单项,true是普通表单项, false是文件表单项
                        String    getContentType() --> 返回的是文件的类型,是MIME值
                        String    getFieldName()   --> 获取表单项的name属性值
                        String    getName()         --> 获取上传的文件的名字
                        long getSize()          --> 获取文件的大小
                        String    getString(String encoding) --> 获取表单项的value属性值,需要接受一个编码作为参数。
                        void    write(File file)    --> 将表单项中的内容写入到磁盘中
                    
            > 使用步骤:
                1.获取工厂类实例[DiskFileItemFactory]
                2.获取解析器类实例[ServletFileUpload]
                3.解析request获取FileItem[parseRequest()]       

         
     1 @WebServlet("/FileUploadServlet")
     2 public class FileUploadServlet extends HttpServlet {
     3     private static final long serialVersionUID = 1L;
     4  
     5     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     6 
     7         //创建工厂类
     8         DiskFileItemFactory factory=new DiskFileItemFactory();
     9         //创建FileUploadServlet对象,通过这个对象完成上传功能
    10         ServletFileUpload fileUpload=new ServletFileUpload(factory);
    11         //用这个fileUpload对象解析request请求
    12         try {
    13             List<FileItem> fileList = fileUpload.parseRequest(request);
    14             for(FileItem item:fileList){
    15                 if (item.isFormField()) {
    16                     //代表普通表单项
    17                     String name = item.getFieldName();
    18                     String value = item.getString("UTF8");
    19                     System.out.println(name+":"+value);
    20                 }else {
    21                     //代表上传的文件
    22                     long size = item.getSize();
    23                     String contentType = item.getContentType();
    24                     String name = item.getName();
    25                     String fieldName = item.getFieldName();
    26                                     System.out.println(size+":"+contentType+":"+name+":"+fieldName);
    27                     String uuid = UUID.randomUUID().toString();//名字重复,后一章会覆盖前一章
    28                     uuid.replace("-", "");
    29                     item.write(new File("C:\Users\kanglu\Desktop\"+uuid+"_"+name));
    30                 }//MIME 
    31             }
    32         }catch (Exception e) {
    33             // TODO Auto-generated catch block
    34             e.printStackTrace();
    35         }
    36     }
    37 }
    文件上传基本实现

        [4] 细节
            第一个问题
            > 部分浏览器会将文件的完整路径作为文件名发送。
                C:UserslilichaoDesktopday20图片蒙娜丽莎.jpg
            > 像这类文件名我们需要截取一下字符串,只获取名字这部分,而不需要获取路径部分的信息。
                通过如下代码对文件名进行截取字符串的操作:
                    if(name.contains("\")){
                        //如果包含则截取字符串
                        name = name.substring(name.lastIndexOf("\")+1);
                    }
                  
            第二个问题
            > 上传的文件有可能出现重名,后上传的文件会将先上传的文件覆盖。
            > 解决:给文件名加一个唯一的前缀。
                    唯一标识_fennu.jpg
                    UUID_fennu.jpg   

    1  //添加唯一前缀
    2  String uuid = UUID.randomUUID().toString();//名字重复,后一章会覆盖前一章
    3                  uuid.replace("-", "");

            第三个问题
            > 有些情况需要限制上传文件的大小。
                - 设置单个文件大小为50KB:
                    fileUpload.setFileSizeMax(1024*50);
                - 设置完单个文件大小限制以后,一旦上传的文件超过限制,则会抛出如下异常:
                    FileSizeLimitExceededException
                    所有可以对该异常进行捕获,当出现该异常时则设置一个错误消息。
                
                - 设置多个文件的总大小为150KB
                    fileUpload.setSizeMax(1024*150);
                - 当多个文件的大小超出范围时,会抛出如下异常
                    SizeLimitExceededException

     1 //单个文件
     2 fileUpload.setFileSizeMax(1024*50);
     3 try{
     4         ......
     5 }catch (FileSizeLimitExceededException e) {
     6     System.out.println("文件大小超出限制");
     7 }
     8 
     9 //多个文件
    10 设置插入多个文件
    11 <input type="file" name="photo"><br>
    12 <input type="file" name="photo"><br>
    13 限制大小处理
    14 fileUpload.setSizeMax(1024*150);
    15 try{
    16         ......
    17 }catch (SizeLimitExceededException e) {
    18     System.out.println("整体文件大小超出限制");
    19 }
    限制文件大小

            第四个问题
                > 当用户上传一个空的文件,依然会将文件保存到硬盘上。
                > 在保存文件应该先对文件的大小进行判断,如果size为0,则不处理。

    1 long size = item.getSize();
    2 if(size==0){
    3     System.out.println("文件大小为空");
    4     continue;
    5 }//若是多个文件,空文件可能位于首位,所以用continue;
    6 //若是单个文件,可用break;
    7 //此处针对上面所写代码,其位于for循环中

      [5]上传服务器

        上面代码中文件直接传到自己的电脑上,用户不能通过浏览器进行网络访问。

        若要能通过浏览器访问,可上传到tomcat服务器位于eclipse的镜像中。(本人使用的是eclipse进行编码)

     1  将文件上传到服务器上:
     2   1、将links和tc-servlet包复制到eclipse文件目录下;
     3  
     4   2、    //将文件存在tomcat服务器镜像上,获取镜像目录
     5       ServletContext servletContext=request.getServletContext();
     6       String realPath = servletContext.getRealPath("/upload");//要存储的具体位置
     7       File file = new File(realPath);
     8       if(!file.exists()){
     9           file.mkdirs();//文件不存在,创建文件(目录)
    10          //file.isDirectory()表明上传的文件是个目录
    11      }

       通过realPath获取文件所在位置,在浏览器上输入(如图片地址),即可获取

    1  localhost:9999/web-upload/upload/168ea717-401b-485c-9d1f-c62cfa50d361_fennu.jpg
    2  //在浏览器地址栏输入如上地址内容即可查看刚刚上传的文件(以图片为例),
    3  //localhost:9999为tomcat端口号,web-upload为所写项目名,
    4  //upload为文件所在位置,
    5  //168ea717-401b-485c-9d1f-c62cfa50d361_fennu.jpg为图片名
    6 6//_前内容为随机生成的唯一标识符

     
     完整代码,包含上传服务器:

    package com.neuedu.servlet;
    
    import java.io.File;
    import java.io.IOException;
    import java.util.List;
    import java.util.UUID;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadBase.FileSizeLimitExceededException;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    
    @WebServlet("/FileUploadServlet")
    public class FileUploadServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
     
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            //创建工厂类
            DiskFileItemFactory factory=new DiskFileItemFactory();
            //创建FileUploadServlet对象,通过这个对象完成上传功能
            ServletFileUpload fileUpload=new ServletFileUpload(factory);
            
            fileUpload.setFileSizeMax(1024*50);
            
            //将文件上传到服务器,是能在互联网上访问
            ServletContext servletContext=request.getServletContext();
            String realPath = servletContext.getRealPath("/upload");
            File file = new File(realPath);
            if(!file.exists()){
                file.mkdirs();//文件不存在,创建文件(目录)
                //file.isDirectory()表明上传的文件是个目录
            }
            
    
            //用这个fileUpload对象解析request请求
            try {
                List<FileItem> fileList = fileUpload.parseRequest(request);
                for(FileItem item:fileList){
                    if (item.isFormField()) {
                        //代表普通表单项
                        String name = item.getFieldName();
                        String value = item.getString("UTF8");
                        System.out.println(name+":"+value);
                    }else {
                        //代表上传的文件
                        fileUpload.setFileSizeMax(1024*50);
                        long size = item.getSize();
                        String contentType = item.getContentType();
                        String name = item.getName();
                        String fieldName = item.getFieldName();
                        if(size==0){
                            System.out.println("文件大小为空");
                            continue;
                        }
                        System.out.println(size+":"+contentType+":"+name+":"+fieldName);
                        String uuid = UUID.randomUUID().toString();//名字重复,后一章会覆盖前一章
                        uuid.replace("-", "");
                        try {
                            item.write(new File(realPath+"\"+uuid+"_"+name));
                        } catch (Exception e) {
                            // TODO: handle exception
                        }
                    }//MIME
                }
            }catch (FileSizeLimitExceededException e) {
                System.out.println("文件大小超出限制");
            }
            catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
    }
    



  • 相关阅读:
    git commit之后未submit,rebase之后找不到自己代码的处理方法
    Objective-C语言--属性和实例变量
    synthesize 与dynamic的区别
    isKindOfClass和isMemberOfClass 区别
    python 报错整理
    使用fastJson 来解析 json
    使用Gson 解析json
    android json数据解析
    Android 常用布局
    cocos2dx 学习代码记录
  • 原文地址:https://www.cnblogs.com/kangxingyue-210/p/7389250.html
Copyright © 2011-2022 走看看