springmvc基础知识(10): 上传文件

文件上传有很多种方式,下面就来看看springmvc是如何进行文件上传的.

使用spring接口MultipartFile

  • 添加jar包:

这里写图片描述
添加下面依赖就可以引入上面jar:

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
  • 配置上传文件解析器:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 设置文件编码格式 -->
    <property name="defaultEncoding" value="UTF-8"></property>
    <!-- 设置最大上传大小 -->
    <property name="maxUploadSize" value="10485760"></property>
</bean>

MultipartResolver用于处理文件上传,当收到请求时DispatcherServlet的 checkMultipart() 方法会调用 MultipartResolver 的 isMultipart() 方法判断请求中是否包含文件。如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart() 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest) 对象中,最后传递给 Controller,在 MultipartResolver 接口中有如下方法:
- boolean isMultipart(HttpServletRequest request); // 是否是 multipart
- MultipartHttpServletRequest resolveMultipart(HttpServletRequest
request); // 解析请求
- void cleanupMultipart(MultipartHttpServletRequest request);

MultipartFile 封装了请求数据中的文件,此时这个文件存储在内存中或临时的磁盘文件中,需要将其转存到一个合适的位置,因为请求结束后临时存储将被清空。在 MultipartFile 接口中有如下方法:
- String getName(); // 获取参数的名称
- String getOriginalFilename(); // 获取文件的原名称
- String getContentType(); // 文件内容的类型
- boolean isEmpty(); // 文件是否为空
- long getSize(); // 文件大小
- byte[] getBytes(); // 将文件内容以字节数组的形式返回
- InputStream getInputStream(); // 将文件内容以输入流的形式返回
- void transferTo(File dest); // 将文件内容传输到指定文件中


  • 处理方法:
@RequestMapping("/uploadByForm.do")
public String uploadByForm(MultipartFile file,HttpServletRequest request,Model model) throws IllegalStateException, IOException{
    if(!file.isEmpty()){
        //原文件名
        String originalFileName = file.getOriginalFilename();
        System.out.println("文件名:"+file.getOriginalFilename()+",文件大小:"+file.getSize());

        //获取项目根目录文件夹下 fileupload 子文件夹
        String ctxPath = request.getServletContext().getRealPath("/fileupload/");
        System.out.println(ctxPath);

        //获取文件后缀
        String extName = originalFileName .substring(originalFileName .lastIndexOf("."));
        //上传后的文件名
        String fileName = new Date().getTime() + extName;
        //将新文件名传回前台
        model.addAttribute("fileName",fileName);
        //文件按路径
        File filePath = new File(ctxPath,fileName);

        if(!filePath.getParentFile().exists()){
            //如果文件夹不存在就新建一个
            filePath.getParentFile().mkdirs();
        }
        //将文件上传到指定文件夹下
        file.transferTo(filePath);
    }
    return "success";
}
  • 在运行的工程根目录下创建fileupload文件夹用于存放上传的文件,我使用的是tomcat服务器,所以上传的文件放在了 tomcat安装路径/webapps/工程/fileupload 下面。
  • 重新生成了文件名,并将之传回前台,在前台页面可以根据这个文件名取工程目录中访问这个文件,以达到实时上传显示的目的。
  • 上产文件页面:
<h2>使用form表单上传文件</h2>
<form action="uploadByForm.do" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <button type="submit">upload</button>
</form>

必须设置 enctype=”multipart/form-data” 以二进制的方式传输数据

  • 上传文件

这里写图片描述

  • 上传成功后跳转页面:
<h2>接收到的后台传过来的文件名为:${fileName}</h2>
    <img alt="" src="<%=request.getContextPath()%>/fileupload/${fileName}">

这里写图片描述


使用输入输出流

@RequestMapping("/uploadByForm1.do")
public String uploadByForm1(MultipartFile file,HttpServletRequest request,Model model) throws IllegalStateException, IOException{
    if(!file.isEmpty()){
        //原文件名
        String originalFileName = file.getOriginalFilename();
        System.out.println("文件名:"+file.getOriginalFilename()+",文件大小:"+file.getSize());

        //获取项目根目录文件夹下 fileupload 子文件夹
        String ctxPath = request.getServletContext().getRealPath("/fileupload/");
        System.out.println(ctxPath);

        //获取文件后缀
        String extName = originalFileName .substring(originalFileName .lastIndexOf("."));
        //上传后的文件名
        String fileName = new Date().getTime() + extName;
        //将新文件名传回前台
        model.addAttribute("fileName",fileName);
        //文件按路径
        File filePath = new File(ctxPath,fileName);

        if(!filePath.getParentFile().exists()){
            //如果文件夹不存在就新建一个
            filePath.getParentFile().mkdirs();
        }
        //将文件上传到指定文件夹下
        file.transferTo(filePath);
    }
    return "success";
}

使用ajax上传文件:

  • jsp文件
<h2>使用ajax上传文件</h2>
<form enctype="multipart/form-data" id="uploadForm">
    <input type="file" id="file" name="file">
    <button type="button" id="upload">upload</button>
</form>
<p></p>
  • js部分
$(function() {
    $('#upload').click(function() {
        var form = new FormData($('#uploadForm')[0]);
        $.ajax({
            type : "POST",
            url : "uploadByAjax.do",
            data : form,
            // 下面三个参数要指定,如果不指定,会报一个JQuery的错误 
            cache : false,
            contentType : false,
            processData : false,
            async : false,
            success : function(data) {
                $('p').html('上传成功,文件名为:' + data);
            }
        });
    });
});

使用FormData序列化表单数据


需要注意的是:

  • 上面将上产的文件放入到工程目录下,这样做是不对的。
  • 一会在别的地方另外常见一个目录,然后通过配置一个虚拟路径映射到工程目录中,这样我们可以在工程中访问这个资源,也不用担心由于更新应用而导致上传文件丢失的问题。

tomcat的配置虚拟路径方法:
这里写图片描述
这里我配置的虚拟路径为 - /工程名/fileupload
这样在页面中使用 “<%=request.getContextPath()%>/fileupload/${fileName}” 就可以访问到刚上传的图片了。

猜你喜欢

转载自blog.csdn.net/abc997995674/article/details/80409387
今日推荐