SpringMVC框架的文件上传

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC框架的文件上传相关的知识,希望对你有一定的参考价值。

SpringMVC框架的文件上传

SpringMVC框架的文件上传是基于commons-fileupload组件的文件上传,只不过SpringMVC框架在原有文件上做了进一步的封装,简化了文件上传代码的实现,取消了不同上传组件上的编程差异。

commons是Apache开源代码组织中的一个Java子项目,该项目包括文件该项目包括文件的上传、命令行处理、数据库连接池、XML配置文件处理等模块,fileupload就是用来处理基于表单的文件上传的子项目,commos-fileupload组件性能优良,并支持任意大小文件的上传。

标签会在浏览器中显示一个输入框和一个按钮,输入框可共用户填写本地文件命和路径名,按钮可以让浏览器打开一个文件选择框供用户选择文件。

对于基于表单的文件上传,需要设置enctype属性,并将它设置为multipart/form-data,同时将表单的提交方式设置为post。

表单的enctype属性指定表单数据的编码方式,其中multipart/form-data该编码方式以二进制的方式来处理表单数据,并将文件指定的文件内容封装到请求参数中。

MultipartFile接口,在SpringMVC框架中上传文件时将文件相关信息及操作封装到MultipartFile对象中,因此开发者只需要使用MultipartFile类型声明模型类的一个属性即可对被上传文件进行操作。

下面学习一个单文件上传的案例

1-创建web应用并导入相关jar包。
2-在web.xml部署DispatcherServlet,用于总体控制,同时需要添加字符编码过滤器。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         id = "WebApp_ID" version="4.0">
    <!--部署DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <!--表示容器启动时加载的servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--任意的请求都通过DispatcherServlet-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置 CharacterEncodingFilter解决中文乱码问题-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <!-- 配置编码格式为UTF-8 -->
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

3-在web目录下创建JSP页面oneFile.jsp,在该页面用于上传单个文件。

<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/10/2
  Time: 9:57
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action = "${pageContext.request.contextPath}/onefile" method="post" enctype="multipart/form-data">
    选择文件:<input type = "file" name = "myFile"/> <br>
    文件描述:<input type = "text" name = "description"/> <br>
    <input type = "submit" value = "提交"/>
</form>
</body>
</html>

4-在src目录下创建pojo包,在该包中创建FileDomain类,在该类中声明一个MultipartFile类型的属性封装被上传的文件信息,属性名与文件选择页面oneFile.jsp类型的表单参数名myFile相同。

import org.springframework.web.multipart.MultipartFile;

/**
 * 在该类中声明一个Multipart类型的属性封装被文件上传的文件信息,
 * 属性名与jsp页面file类型的表单参数myFile相同
 */
public class FileDomain {
    private String description ;
    private MultipartFile myFile ;

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public MultipartFile getMyFile() {
        return myFile;
    }

    public void setMyFile(MultipartFile myFile) {
        this.myFile = myFile;
    }
}

5-在src目录下创建了controller包,在该包中创建FileUploadController控制器类,在该控制器类中完成文件上传。

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import pojo.FileDomain;

import javax.servlet.http.HttpServletRequest;
import java.io.File;

@Controller
public class FileUploadController {
    @RequestMapping("/onefile")
    public String oneFileUpLoad(@ModelAttribute FileDomain fileDomain, HttpServletRequest request){
        String realpath = request.getServletContext().getRealPath("/uploads/") ; //上传的位置
        String fileName = fileDomain.getMyFile().getOriginalFilename() ; //获取上传的文件名称
        File targetFile = new File(realpath, fileName) ;//以路径名和文件命创建文件
            if(!targetFile.exists()){ //如果目标文件不存在,则创建目录
                targetFile.mkdirs() ;
        }
        //目标文件存在,则上传文件
        try {
            fileDomain.getMyFile().transferTo(targetFile);
        }catch(Exception e){
            e.printStackTrace();
        }
        return "showOne" ;
    }
}

6-在WEB-INF创建配置文件springmvc-servlet.xml,在该配置文件中扫描指定包,使得注解生效,配置视图解析器,使用Spring的CommonsMultipartResolver配置multipartResolve用于文件上传。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--使用扫描机制,扫描控制器类-->
    <context:component-scan base-package="controller"/>
    <mvc:annotation-driven />

    <!--配置视图解析器-->
    <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" id = "internalResourceViewResolver">
        <!--前缀-->
        <property name = "prefix" value = "/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name = "suffix" value = ".jsp"/>
    </bean>

    <!--使用Spring的CommonsMultipartResolver配置MultipartResolver用于文件上传-->
    <!--配置默认编码方式,允许上传文件的最大值,单位为字节,配置文件的临时路径-->
    <bean id = "multipartResolver" class = "org.springframework.web.multipart.commons.CommonsMultipartResolver"
          p:defaultEncoding="UTF-8"
          p:maxUploadSize="5400000"
          p:uploadTempDir="WEB-INF">
    </bean>

</beans>


7-在WEB-INF目录下创建JSP文件夹,在该文件夹中创建视图显示页面showOne.jsp

<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/10/2
  Time: 10:27
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${fileDomain.description}<br>
${fileDomain.myFile.originalFilename}
</body>
</html>

下面学习SpingMVC框架的多文件上传的案例
1-在web目录下创建JSP页面multiFile.jsp,该页面使用表单上传多个文件。

<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/10/2
  Time: 14:25
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action = "${pageContext.request.contextPath}/multifile" method="post" enctype="multipart/form-data">
    选择文件1:<input type = "file" name = "myfile"> <br>
    文件描述1:<input type = "text" name = "description"> <br>
    选择文件2:<input type = "file" name = "myfile"> <br>
    文件描述2:<input type = "text" name = "description"> <br>
    选择文件3:<input type = "file" name = "myfile"> <br>
    文件描述3:<input type = "text" name = "description"> <br>
    <input type = "submit" value = "提交"/>
</form>
</body>
</html>

2-在pojo包中创建MultiFileDomain类用于封装文件信息。

import org.springframework.web.multipart.MultipartFile;

import java.util.List;

public class MultiFileDomain {
    //该类用于封装文件信息
    private List<String> description ;
    private List<MultipartFile> myfile ;

    public List<String> getDescription() {
        return description;
    }

    public void setDescription(List<String> description) {
        this.description = description;
    }

    public List<MultipartFile> getMyfile() {
        return myfile;
    }

    public void setMyfile(List<MultipartFile> myfile) {
        this.myfile = myfile;
    }
}

3-在控制器类中添加多文件上传处理方法multiFileUpload.

  //添加多文件上传处理的方法
    @RequestMapping("/multifile")
    public String multiFileUpload(@ModelAttribute MultiFileDomain multiFileDomain, HttpServletRequest request){
        String realpath = request.getServletContext().getRealPath("uploadfiles") ;
        File targetDir = new File(realpath) ;
        if(!targetDir.exists()){
            targetDir.mkdirs() ;
        }
        List<MultipartFile> files = multiFileDomain.getMyfile() ;
        for(int i=0; i<files.size(); i++){
            MultipartFile file = files.get(i) ;
            String fileName = file.getOriginalFilename() ;
            File targetFile = new File(realpath, fileName) ;
            try{
                file.transferTo(targetFile);
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return "showMulti" ;
    }

4-在jsp文件夹中创建文件显示页面showMulti.jsp

<%@ taglib prefix="C" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/10/2
  Time: 14:45
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<table>
    <tr>
        <td>  详情  </td> <td>  文件名  </td>
    </tr>
    <!--同时取两个数组的元素-->
    <C:forEach items = "${multiFileDomain.description}" var = "description" varStatus="loop">
        <tr>
            <td>${description}</td>
            <td>${multiFileDomain.myfile[loop.count - 1].originalFilename}</td>
        </tr>
    </C:forEach>
</table>
</body>
</html>

以上是关于SpringMVC框架的文件上传的主要内容,如果未能解决你的问题,请参考以下文章

如何使用springmvc实现文件上传

在SpringMVC框架中实现文件上传和下载

JAVAEE框架技术之6-springMVC拦截器和文件上传功能

JAVAEE框架技术之6-springMVC拦截器和文件上传功能

JAVAEE框架技术之6-springMVC拦截器和文件上传功能

JSP+SpringMVC框架使用WebUploader插件实现注册时候头像图片的异步上传功能