文件上传下载两种方式

文件的上传和下载

上传
一,借助三方工具类实现上传文件
二,用springmvc框架中的类– 不过需要在springmvc.xml中配置上传文件解析器
下载
下载都是一样的,两个流,一个头
两个流:需要读取服务器端本地硬盘到内存的输入流,另一个是从服务器内存到客户端的输出流
一个头:设置下载的响应头



需要jar包:
commons-fileupload-1.3.1.jar
commons-io-2.2.jar


正文

在通过表单上传文件时,需要注意以下几点
1,post请求
2,输入框类型设置为file
3,把表单中属性修改 enctype=’multipart/form-data’多部件类型
该表单属性默认为 application/x-www-form-urlencoded,所以需要修改

  <!-- 测试文件上传和下载 -->
 <form action="${pageContext.request.contextPath}/file/FileUploadServlet" 
         method="post" enctype="multipart/form-data">
                 <p>用户名:<input type="text" name="uname" /> </p>
                 <p>密码:<input type="password" name="pwd" /> </p>
                 <p>照片:<input type="file" name="photo" /> </p>
                 <p> <input type="submit" value="注册"> </p>
 </form>
Servlet部分

在服务器端 webapp下首先创建一个upload文件夹,用来存放上传的文件,需要考虑上传文件的重名问题
两种解决方案:
1,把上传的文件放到upload下的不同文件夹下(可以通过获取系统的毫秒值来命名)
2,把上传的文件重新命名(通过UUID类生成的随机字符命名)
这里采用第二种方式

      public void doPost(HttpServletRequest request,
  HttpServletResponse response) throws ServletException, IOException {

        /*  String uname = request.getParameter("uname");
          String password= request.getParameter("pwd");
          String photo=request.getParameter("photo");*/

        /*  user.setName(uname);
          user.setPassword(password);
          System.out.println(user);*/

          //借助其他三方工具jar包
          //1,创建对象,创建保存字符串的临时文件及保存位置
           DiskFileItemFactory factory=new DiskFileItemFactory();
           //2,
           ServletFileUpload upload=new ServletFileUpload(factory);
           //创建一个user对象,封装信息
           User user=new User();
            //3,从字符串获取内容  分两步, 普通键值对 和 文件信息
               try {
                List<FileItem> items = upload.parseRequest(request);
                 //4,遍历集合,获取普通键值对信息

                for(FileItem item :items) {
                     //获取键名
                    String fileName=item.getFieldName();

                    //判断是普通键值对信息
                    if(item.isFormField()) {
                      if("uname".equals(fileName)){
                              user.setName(item.getString());
                          }
                          if("password".equals(fileName)){
                              user.setPassword(item.getString());
                          }
                    }else {
                        //文件信息
                    //5,解决重名问题,生成随机字符串,采用随机字符+ 文件原名=新文件名
                         String uuid=UUID.randomUUID().toString();

                          //去掉uuid生成的随机字符中的 -, 以空串代替,实现去除
                         uuid=uuid.replace("-", "");
                      //获取原文件名,
                         String oldFileName=item.ge虑tName();
           //考存带有路径的问题,做判断,有则截取,这里\需要转义,所以用\\
             int  index=  oldFileName.lastIndexOf("\\");
     //判断\路径分隔符的位置,如果为-1,则没有,如果有,则截取后面的文件名部分
                              if(index!=-1){
                                  //有路径,则从后一位截取,获取文件名和后缀名
                           oldFileName.substring(index+1); 
                              }
                        //拼接新文件名
                         String newFileName=uuid+"-"+oldFileName;
    //6,获取upload的文件夹路径 ,这里相对于项目的路径,web项目也可说是相对于classes目录
    String path= request.getServletContext().getRealPath("/upload");

                        //创建文件对象,指定文件夹下,文件名
                       File file=new File(path,newFileName);


                  //7,把文件信息写入到指定文件
                      item.write(file);
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
    }

下载

主要是通过response响应对象的输出流响应给对象

    //下载功能
    protected void download(HttpServletRequest request,
     HttpServletResponse response) throws ServletException, IOException {
               //一个头,两个流

           //1,获取前台传过来的文件名
            String fileName= request.getParameter("fileName");
            //响应头 --固定格式  这里变量拼接,因此要转义filename后双引号     
  response.addHeader("content-Disposition", "attachment;filename=\""+fileName+"\"");

         //获取该文件在服务器端的资源路径,因为是从服务器下载文件 
            String path=request.getServletContext().getRealPath("/upload");
             //创建该下载文件的文件对象
             File file=new File(path,fileName);
           //2一个输入流,从服务器硬盘到内存
        BufferedInputStream  bis=new BufferedInputStream(new FileInputStream(file));

  //3,一个输出流,从服务器端内存到客户端,这里是多态,因OutputStream是接口,
  //父类引用指向子类对象,实现动态绑定
            OutputStream sos = response.getOutputStream();

            int len=-1;
            byte[] b=new byte[1024];
            while((len=bis.read(b))!=-1) {
                sos.write(b,0,len);
            }
            sos.close();
            bis.close();
    }

springmvc中实现上传

1,配置文件

<!-- 配置上传文件的解析器 -->
    <!-- 实现上传时,这个解析器的id是固定名称multipartResolver -->
    <bean id="multipartResolver" 
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传文件的大小设置,上传文件的大小不能超过参数的指定值,值单位是B,
这里设置的是10M,value中不可以用运算符,为了图方便,直接乘会报错(试过!) -->
        <property name="maxUploadSize" value="10485760"></property>
        <!-- 上传文件的默认编码格式 -->
        <property name="defaultEncoding" value="utf-8"></property>
        <!-- 类似懒加载的属性.可以定义该属性.让解析文件的时候再抛异常 -->
        <property name="resolveLazily" value="true"></property>
    </bean>

2,conroller中
这里对于上传文件的命名采用的是2者的组合方式,既创建文件夹,又修改文件名方式

/*这里要注意在前台表单中上传文件中input输入框的名字要和这里形参的MultipartFile的的一致,
 才能实现匹配,获取上传数据*/
     @RequestMapping("/user_upload.do") 
    public String fileUpload(User user,MultipartFile photo_str,
    HttpServletRequest request,Model model) throws IllegalStateException, IOException{
          //1,接收普通数据 user
          //user这里只是接收表单中其他数据,将其封装到user类中的,方便处理数据

          //2,接收文件数据      ,文件存储位置, 解决文件重名问题

          if(photo_str!=null) {
          //也得先在webapp下创建一个upload文件夹, 获取到upload位置,
       //当然也可以配置tomcat的虚拟路径,直接存储到tomcat服务器中,这里是存储到项目中的
String path = request.getSession().getServletContext().getRealPath("/upload"); 
          //获取旧文件名
          String oldname = photo_str.getOriginalFilename();
          //获取后缀名,最后一个.的下标
           int index = oldname.lastIndexOf(".");
           //截取,只获取 .后缀名 部分
           String exname = oldname.substring(index);
           //生成新的文件名
          String uuid = UUID.randomUUID().toString().replace("-","");
           //文件名和后缀拼接成新的文件名
           String  newName=uuid+exname;

             //获取系统的当前毫秒值,用来做文件夹的名字
          long ms=System.currentTimeMillis();
           //和upload的绝对路径拼接,形成一个upload文件夹下的完整文件路径
           path=path+"/"+ms;

          //根据路径创建文件对象 -- 
           File file=new File(path);
           //创建文件夹,先判断是否存在,理论上是不会存在的
           if(!file.exists()) {
               file.mkdirs();
           }
           //创建文件夹下文件
            file=new File(path,newName);

            //将上传照片写入文件
            photo_str.transferTo(file);

            //user对象只是封装的图片的完整路径
            user.setPhoto(file.getPath());
          }
     }
springmvc中实现下载
//文件下载
     @RequestMapping("/user_fileDownload.do") 
     public String fileDownload(String fileName,
HttpServletResponse reponse,HttpServletRequest request) throws IOException{
         //一个头,两个流
         InputStream is=null;
         OutputStream os=null;
            //首先还是获取upload目录下的文件名路径
         String path = request.getSession().getServletContext().getRealPath("/upload/"+fileName);
          //根据获取的路径,读入文件到内存中
          //从服务器端本地读入文件流
 is=new BufferedInputStream(new FileInputStream(path)); 
 //解决文件名在下载时遇到中文出现乱码问题----反向编码一次
    //注意这个编码要在文件读取文件到输入流中之后,不然把文件名先改变编码后,
   //在服务器端根据路径去读文件到输入流,会找不到这个文件,因为编码方式不同,文件名就变了,会报错
         fileName =new String(fileName.getBytes("utf-8"),"iso8859-1");
         reponse.addHeader("content-Disposition", "attachment;fileName="+fileName);
         byte[] b=new byte[1024];
         os=reponse.getOutputStream(); //写出到客户端的写出流

         int len=-1;
         while((len=is.read(b))!=-1){
             os.write(b, 0, len);
         } 
         os.close();
         is.close();

     }



学习总结,水平有限,如有错误,敬请指正,感激不尽!

猜你喜欢

转载自blog.csdn.net/qq_39494996/article/details/82085286