七、三种文件上传方法与文件下载

一、原始方式

使用Apache Commons FileUpload,是apache提供的一个库,支持从HttpServletRequest中解析文件上传数据

1、导入文件上传的两个依赖:commons-fileupload、commons-io

2、表单entype属性设置为multipart/form-data;method属性为post

表示这个表单要提交的是文件类型

3、文件上传的三个对象

3.1 DiskFileItemFactory工厂对象

entype设置为multipart/form-data;DiskFileItemFactory会将每个表单元素封装成FileItem对象

3.2 ServletFileUpload文件上传解析器对象

文件上传解析器对象调用parseRequest(request)方法,获取存储了所有FileItem对象的List集合,遍历集合得到每个表单元素对象

3.3 FileItem对象

用于表示表单中的元素

3.3.1 判断是否是文件

Boolean isFormField()方法用于判断当前表单元素是否是一个文件,文件返回false

3.3.2 不是文件

getFiledName获取组件的名字,getString获取值。存储进数据库

3.3.3 是文件
  1. getName获取文件名,拼接文件路径
  2. 根据路径创建文件对象
  3. write(File file)将读取的文件写入指定的文件
  4. 在过程前后插入细节操作:
    比如避免文件名重复:
String fileName = fileItem.getName();
//为避免和已经存在的文件冲突,将文件名拼接,使名字不会重复
fileName = System.currentTimeMillis()+fileName;
String path = request.getServletContext().getRealPath("/upload/" + fileName);

判断父级路径(/upload/)是否存在

//构建文件
File file = new File(path);
//确保文件的父级目录文件夹存在(存在什么也不做,不存在就创建)
file.getParentFile().mkdirs();
//创建文件
file.createNewFile();

4、完整过程

@WebServlet("/TUploadServlet")
public class TUploadServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=utf-8");
        //1、创建工厂
        DiskFileItemFactory dff = new DiskFileItemFactory();
        //2、创建文件上传解析器
        ServletFileUpload sf = new ServletFileUpload(dff);
        //设置上传解析器编码
        sf.setHeaderEncoding("UTF-8");
        //3、将request对象获取到的数据转化为FileItem
        try {
            List<FileItem> fileItems = sf.parseRequest(request);
            for (FileItem fileItem : fileItems) {
                if (fileItem.isFormField()){
                    //普通文件
                    System.out.println(fileItem.getFieldName() + ":" + fileItem.getString("utf-8"));
                } else {
                    //文件处理逻辑
                    //4、创建文件上传路径
                    //4.1 拼接完整的文件目录
                    String fileName = fileItem.getName();
                    //为避免和已经存在的文件冲突,将文件名拼接,使名字不会重复
                    fileName = System.currentTimeMillis()+fileName;
                    String path = request.getServletContext().getRealPath("/upload/" + fileName);
                    //构建文件
                    File file = new File(path);
                    //确保文件的父级目录文件夹存在(存在什么也不做,不存在就创建)
                    file.getParentFile().mkdirs();
                    //创建文件
                    file.createNewFile();
                    //将读取到的文件流写入到指定的这个文件中去
                    fileItem.write(file);
                }
            }
        } catch (FileUploadException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

二、Servlet API注解简化

1、导入文件上传的两个依赖:commons-fileupload、commons-io

2、表单entype属性设置为multipart/form-data;method属性为post

3、Servlet加注解@MultipartConfig

4、做文件上传

4.1 通过getPart()方法获取文件

<input type="file" name="file"/>
Part part = request.getPart("file");

4.2 通过getSubmittedFileName方法获取文件名

String fileName = part.getSubmittedFileName();

4.3 拼接存储路径

String path = request.getServletContext().getRealPath("/upload/"+fileName);

4.4 part对象调write方法写入文件

5、完整过程

@WebServlet("/MyFileServlet")
@MultipartConfig
public class MyFileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //设置编码
        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html;charset=UTF-8");
        //普通表单组件
        String name = request.getParameter("name");
        //获取表单的文件
        Part part = request.getPart("file");
        //获取文件名
        String fileName = part.getSubmittedFileName();
        String path = request.getServletContext().getRealPath("/upload/"+fileName);
        part.write(path);
    }

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

三、SpringMVC通过JS文件上传

1、导入文件上传的两个依赖:commons-fileupload、commons-io

2、在dispatch-servlet中配置文件上传解析器

<!-- 注入文件上传解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="utf-8"/>
        <!-- 注入上传的文件最大是多少,一般都是100mb -->
        <property name="maxUploadSize" value="1000000"/>
    </bean>

3、表单entype属性设置为multipart/form-data;method属性为post

4、在js中获取上传的图片

  1. <input type="file">添加一个改变事件,用于获取页面选择的文件,当选择了图片的时候就会触发
  2. 在data数据模型内定义一个file作为全局变量;在getFile方法内接收文件对象,在提交事件中封装文件对象。
  3. 将表单的数据封装进FormData对象,发送请求携带FormData对象
<div align="center" id="mainvue">
    <form enctype="multipart/form-data" method="post">
        用户:<input type="text" name="uname" v-model="uname"><br>
        头像:<input type="file" name="pic" v-on:change="getFile($event)"><br>
        <input type="button" value="提交" v-on:click="submit()" >
    </form>
</div>
new Vue({
    el:'#mainvue',
    data:{
        uname:'',
        file:''
    },
    methods:{
        getFile(event){
            this.file=event.target.files[0];
        },
        submit(){
            var formData = new FormData();
            formData.append("uname", this.uname);
            formData.append("pic", this.file);
            console.log("append成功")
            axios.post("http://localhost:8080/prjspringmvc_js_fileupload_war_exploded/upload.do", formData).then(res=>{
                console.log(res.data);
            })
        }
    }
})

5、后端接收

  1. 控制方法的参数名要与表单组件的name一致,文件用MultipartFile对象接收
  2. getOriginalFilename():获取文件名称
  3. transferTo(File file):将接收的文件写入指定的文件
    封装进实体类对象也是如此,注意属性名与表单组件name一致
	@RequestMapping("/upload")
    public String upload(MultipartFile pic, String uname, HttpServletRequest request){
        System.out.println("文件上传开始");
        //isEmpty为true表示没有文件
        if (pic!=null&&!pic.isEmpty()){
            System.out.println("用户名:"+uname);
            //1、参数已经接收到了文件
            //2、获取文件名,拼接存储路径
            String fileName = pic.getOriginalFilename();
            String path = request.getServletContext().getRealPath("/upload/"+fileName);
            //3、创建目标文件
            File file = new File(path);
            file.getParentFile().mkdirs();
            try {
                pic.transferTo(file);
                System.out.println("上传成功");
                return "1";
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return "0";
    }

四、文件下载

1、步骤

  1. 获取前端传过来的要获取的文件名,拼接文件路径
    <a href="download.do?fileName=haisi.jpg">图片下载</a>
  2. 根据路径创建要下载的文件对象
  3. 设置响应头:响应方式为以附件的形式,并设置响应文件名为下载的文件名,否则下载的文件名就是链接的最后一部分,这里是download.do
  4. 设置响应的内容类型为可下载的文件setContentType
  5. 流的对拷:
    通过文件对象获取输入流对象,可以用缓冲流包装
    通过response获取输出流对象,循环从输入流读取,从输出流写出

2、完整代码

@RequestMapping("/download")
    public String download(String fileName, HttpServletRequest request, HttpServletResponse response){
        //1、拼接要下载的文件路径
        String path = request.getServletContext().getRealPath("/upload/" + fileName);
        System.out.println(path);
        //2、创建要下载的文件对象
        File file = new File(path);
        if (file.exists()){
            //3、设置响应方式:以附件的形式处理响应内容,必须设置响应文件名,否则就是链接的最后一部分(download.do)
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            //4、设置响应内容类型为一个可下载的文件
            response.setContentType("application/x-msdownload");
            try {
                //5、流的对拷
                BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
                BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());

                byte[] buffer = new byte[1024];
                int len=0;
                while ((len = in.read(buffer)) != -1) {
                    out.write(buffer, 0, len);
                }
                out.flush();
                in.close();
                out.close();
                System.out.println("下载成功!");
                return "1";
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        } else {
            System.out.println("文件不存在,下载失败");
        }
        return "0";
    }
  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值