文件上传下载

文件上传下载

文件上传

文件上传的应用
比如个人信息的管理,上传头像
比如商品信息的管理,上传商品的图片
这些都需要通过浏览器客户端将图片上传到服务器的磁盘上

文件上传原理

所谓的文件上传就是服务器端通过request对象获取输入流,将浏览器端上传的数据读取出来,保存到服务器端

客户端浏览器注意事项

  • 请求方式必须是 post
  • 需要使用组件
  • 表单必须设置enctype="multipart/form-data"
    服务器端处理 通过request对象,获取InputStream, 可以将浏览器提交的所有数据读取到.

上传开源框架-commons-upload

Apache 开源组织提供了一个用来处理表单文件上传的一个开源组件( Commons-fileupload),该组件性能优异,并且其API使用极其简单,可以让开发人员轻松实现web文件上传功能,因此在web开发中实现文件上传功能,通常使用Commons-fileupload组件实现。

使用Commons-fileupload组件实现文件上传,需要导入该组件相应的支撑jar包:Commons-fileupload和commons-io, commons-io 不属于文件上传组件的开发jar文件,但Commons-fileupload 组件从1.1版本开始,它工作时需要commons-io包的支持jar包路径:

保存一个完整的表单信息,除了将文件上传到服务器以外,还需要将其他表单项信息保存到对象,并存储到数据中心,而对应的图片信息则保存为保存的路径即可。
那么怎么获取到其他的表单项数据?item.getFileName(),item.getString()
为了更好完成对其他表单项的值的获取,需要借助另一个开源框架 BeanUtils
它除了自身的jar包,还依赖于commons-logging.jar

所需要的包

文件上传案例

文件上传下载_第1张图片
image

文件上传下载_第2张图片
image

文件上传下载_第3张图片
image

文件上传下载_第4张图片
image

上传单个图片到磁盘


     
     
用户名:
密码:
文件上传:
//版本1:解析图片,存储到D:/b.jpg
    private void deal1(HttpServletRequest request) throws IOException, FileNotFoundException {
        String action = request.getParameter("action");
        if("upload".equals(action)){
            
            //1. 实例化文件上传的工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            
            //2.从工厂中获取fileUpload的对象
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
            
            //3.通过fileUpload对象解析request
            try {
                //解析request后,将内容放入第三方提供的FileItem实体类中
                List list = fileUpload.parseRequest(request);
                //遍历集合,取出FileItem实体类中的数据
                for(FileItem fileItem : list){
                    //System.out.println(fileItem);  //打印FileItem实体类对象
                    //判断是否为文本表单内容
                    if(!fileItem.isFormField()){  //处理非文本表单内容---处理图片
                        
                        //-------io流操作-------
                        InputStream iStream = fileItem.getInputStream();
                        int len;
                        byte[] b = new byte[1024];
                        FileOutputStream fos = new FileOutputStream("d://"+fileItem.getName());
                        while((len=iStream.read(b))!=-1){
                            fos.write(b, 0, len);
                        }
                        //----------关流s----------
                        iStream.close();
                        fos.close();
                    }
                }
                
                
            } catch (FileUploadException e) {
                e.printStackTrace();
            }
            
        }
    }

优化版

//版本2:io流的优化;图片的路径要跟着项目走--不能随意指定:d:/a.jpg
    private void deal2(HttpServletRequest request) throws IOException, FileNotFoundException {
        String action = request.getParameter("action");
        if("upload".equals(action)){
            
            //1. 实例化文件上传的工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            
            //2.从工厂中获取fileUpload的对象
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
            
            //3.通过fileUpload对象解析request
                try {
                    List list = fileUpload.parseRequest(request);
                    for(FileItem fileItem : list){
                        if(!fileItem.isFormField()){  
                            //图片的路径要跟着项目走--不能随意指定:d:/a.jpg
                            //io流的优化
                            
                            //获取的是项目的部署路径下的upload
                            String path = getServletContext().getRealPath("upload");
                            //判断部署的upload路径是否存在,如果不存在则创建
                            File parent = new File(path);
                            if(!parent.exists()){
                                parent.mkdirs();   //创建父目录
                            }
                            
                            //拼完整图片的文件路径
                            File allFile = new File(parent, fileItem.getName());
                            
                            
                            //------------io流操作:第三方处理-----------
                            //参数1:上传的文件资源
                            IOUtils.copy(fileItem.getInputStream(), new FileOutputStream(allFile));
                        }
                    }
                    
                } catch (FileUploadException e) {
                    e.printStackTrace();
                }
        }
    }

解决重名的问题

//版本3:处理文件上传的重名问题?  uuid,时间
    private void deal3(HttpServletRequest request) throws IOException, FileNotFoundException {
        String action = request.getParameter("action");
        if("upload".equals(action)){
            
            //1. 实例化文件上传的工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            
            //2.从工厂中获取fileUpload的对象
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
            
            //3.通过fileUpload对象解析request
            
            List list;
            try {
                list = fileUpload.parseRequest(request);
                for(FileItem fileItem : list){
                    if(!fileItem.isFormField()){  
                        //图片的路径要跟着项目走--不能随意指定:d:/a.jpg
                        //io流的优化
                        
                        //获取的是项目的部署路径下的upload
                        String path = getServletContext().getRealPath("upload");
                        
                        //处理日期
                        SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/HH/mm/ss");
                        String strDate = sdf.format(new Date());
                        
                        //判断部署的upload路径是否存在,如果不存在则创建
                        File parent = new File(path+strDate);
                        if(!parent.exists()){
                            parent.mkdirs();   //创建父目录
                        }
                        
                        //--处理重命名方式1: uuid
                        //String uuid = UUID.randomUUID().toString();
                        //String fileName = uuid+"_"+fileItem.getName();
                        //File allFile = new File(parent, fileName);
                        
                        //处理重命名方式2: 日期处理: 2019/3/11/11/38/56/a.jpg  2019/3/11/11/38/57/a.jpg
                        File allFile = new File(parent, fileItem.getName());
                        
                        IOUtils.copy(fileItem.getInputStream(), new FileOutputStream(allFile));
                    }
                }
                
            } catch (FileUploadException e) {

                e.printStackTrace();
            }
                    
        }
    }

上传文件并使用BeanUtils保存checkbox表单


     
     
用户名:
密码:
爱好:
文件上传:
    //版本4:在后台存储完整数据
    private void deal4(HttpServletRequest request)
            throws UnsupportedEncodingException, IOException, FileNotFoundException {
        //1. 实例化文件上传的工厂
        DiskFileItemFactory factory = new DiskFileItemFactory();
        
        //2.从工厂中获取fileUpload的对象
        ServletFileUpload fileUpload = new ServletFileUpload(factory);
        
        //3.通过fileUpload对象解析request
        
        List list;
        User user = new User();
        Map map = new HashMap<>();
        try {
            list = fileUpload.parseRequest(request);
            for(FileItem fileItem : list){
                if(fileItem.isFormField()){  //处理文本表单内容
                    
                    //获取到map集合中key对应的值,如果为空,则进行存储;否则,进行与旧值拼接
                    String value = map.get(fileItem.getFieldName());
                    if(value == null){
                        map.put(fileItem.getFieldName(), fileItem.getString("utf-8"));
                    }else{
                        map.put(fileItem.getFieldName(), value+","+fileItem.getString("utf-8"));
                    }
                    
                    
                }else{    //处理二进制内容
                    //获取的是项目的部署路径下的upload
                    String path = getServletContext().getRealPath("upload");
                    
                    //判断部署的upload路径是否存在,如果不存在则创建
                    File parent = new File(path);
                    if(!parent.exists()){
                        parent.mkdirs();   //创建父目录
                    }
                    
                    //--处理重命名方式1: uuid
                    String uuid = UUID.randomUUID().toString();
                    String fileName = uuid+"_"+fileItem.getName();
                    File allFile = new File(parent, fileName);
                    
                    IOUtils.copy(fileItem.getInputStream(), new FileOutputStream(allFile));
                    
                    //user.setUrl(allFile.getAbsolutePath());  //存储图片路径
                }
            }
            
        } catch (FileUploadException e) {

            e.printStackTrace();
        }
        //将map的数据注入的User对象,["username":"zs","password":"123"]
        try {
            BeanUtils.populate(user, map);
            
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

展示单个图片、展示多个图片

    //版本5:展示单个图片、展示多个图片
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String action = request.getParameter("action");
        if("upload".equals(action)){
            
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload fileUpload = new ServletFileUpload(factory);
            
            List list;
            User user = new User();
            Map map = new HashMap<>();
            try {
                list = fileUpload.parseRequest(request);
                for(FileItem fileItem : list){
                    if(fileItem.isFormField()){  //处理文本表单内容
                        
                        //获取到map集合中key对应的值,如果为空,则进行存储;否则,进行与旧值拼接
                        String value = map.get(fileItem.getFieldName());
                        if(value == null){
                            map.put(fileItem.getFieldName(), fileItem.getString("utf-8"));
                        }else{
                            map.put(fileItem.getFieldName(), value+","+fileItem.getString("utf-8"));
                        }
                        
                        
                    }else{    //处理二进制内容
                        //获取的是项目的部署路径下的upload
                        String path = getServletContext().getRealPath("upload");
                        
                        //判断部署的upload路径是否存在,如果不存在则创建
                        File parent = new File(path);
                        if(!parent.exists()){
                            parent.mkdirs();   //创建父目录
                        }
                        
                        //--处理重命名方式1: uuid
                        String uuid = UUID.randomUUID().toString();
                        String fileName = uuid+"_"+fileItem.getName();
                        File allFile = new File(parent, fileName);
                        
                        IOUtils.copy(fileItem.getInputStream(), new FileOutputStream(allFile));
                        
                        //注意:此处不能存带盘符的完整路径;应该存相对路径
                        //user.setUrl(allFile.getAbsolutePath());  //存储图片路径
                        //需求1: 存储单张图片路径
                        //user.setUrl("upload"+File.separator+fileName);  //File.separator 获取路径符号
                        //需求2: 存储多张图片路径
                        user.getUrList().add("upload"+File.separator+fileName);
                    }
                }
                
            } catch (FileUploadException e) {

                e.printStackTrace();
            }
            //将map的数据注入的User对象,["username":"zs","password":"123"]
            try {
                BeanUtils.populate(user, map);
                
                request.setAttribute("urls", user.getUrList());
                request.getRequestDispatcher("show2.jsp").forward(request, response);
                
            } catch (IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
                    
        }
    }

文件下载

主要实现方式有两种

1.  超链接下载
2.  以超链接的方式下载压缩文件
3.  以超链接的方式下载图片文件
4.  以超链接的方式下载中文文件名的文件
5.  Servlet下载

有些超链接搞不定的事情就交给Servlet来搞定

采用流的方式来读和写

设置响应的头部信息

response.setHeader("Content-disposition", "attachment;fileName="+fileName);
细节:

下载的文件名是中文怎么办?

代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Insert title here


      
      下载b.jpg
下载b.rar
下载高圆圆.rar
package com.qf.servlet;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;

public class DownloadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String path = request.getParameter("path");
        path = new String(path.getBytes("iso-8859-1"), "utf-8");  //download/高圆圆.jar
        
        //注意: 往往上传或下载的图片名不要有中文,且不要以数字开头
        
        //获取文件名
        String fileName = path.substring(path.indexOf("/")+1);
        
        //将中文文件名进行转码,类似cookie应用
        fileName = URLEncoder.encode(fileName, "utf-8");
        
        //设置响应的头部信息
        response.setHeader("Content-disposition", "attachment;fileName="+fileName);
        
        //注意:io流的读写,是针对完整路径
        path = getServletContext().getRealPath(path);
        //通过第三方方式写出去
        IOUtils.copy(new FileInputStream(path), response.getOutputStream());
    }


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

总结:

1. 文件上传案例:
   1. 导入jar包:Commons-fileupload和commons-io
   2. 客户端的操作:
        1.表单的请求方式:method=post
        2.设置enctype=multipart/form-data
        3.控件类型: type="file"
   3. 服务器端的操作:
        1.创建DiskFileItemFactory
        2.创建ServletFileUpload
        3.通过ServletFileUpload的parseRequest方法得到所有的FileItem   
    4.  遍历集合中的所有FileItem对象
        判断如果为非文本表单内容,则将该图片通过io流方式取出
2. 文件上传操作及优化----版本升级
   1. 获取到FileItem对象后,取出io流内容----先读后写
   2. 存储图片路径跟着项目走(存到部署目录下);第三方io操作优化
   3. 处理文件名重名问题:  加前缀uuid、加入时间目录
   4. 存储完整表单数据: 文本表单、二进制数据等
         建立实体类---存图片时,只需存图片路径即可  
                               存文本表单时,需通过第三方jar包去注入
         导入jar包:    BeanUtils、commons-logging.jar                        
    存复选框数据时,如何存?
    判断map集合中是否存储该key,如果有则拼接;   
   5、存单张图片、存多张图片(实体类中要有集合的属性用于存url路径)
3. 文件的下载:
   1.简单的图片下载可以通过超链接直接下载即可  
   2.如果超链接下载不了(例如中文图片名);通过servlet去处理
   servlet处理步骤: 获取到图片路径
                   get请求的转码
                                      提取图片的文件名用于设置头部信息,且仍需转码
                                      通过io流进行下载: IOUtils.copy                 

other

写相对路径报错


文件上传下载_第5张图片
image

文件上传下载_第6张图片
image

然后


文件上传下载_第7张图片
image

说明web项目和java项目还是有区别的
文件上传下载_第8张图片
image

[站外图片上传中...(image-7b84af-1552350602309)]


文件上传下载_第9张图片
image

.

你可能感兴趣的:(文件上传下载)