springmvc中使用文件上传功能

项目代码:https://github.com/PeiranZhang/springmvc-fileupload

Servlet3.0之前使用文件上传功能

Servlet3.0之前需要使用commons file upload和commons io组件,依赖一下了两个jar

  • commons-fileupload-1.3.jar
  • commons-io-2.4.jar

spring配置文件中配置bean

    <!--Servlet 3.0之前,需要定义CommonsMultipartResolver来支持文件上传功能,bean id固定为"multipartResolver"-->        
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--定义上传文件最大为1KB-->
    <property name="maxUploadSize" value="1000000"/>
    <property name="uploadTempDir" value="file:E://tmp"/>
    <property name="defaultEncoding" value="UTF-8"/>
    </bean>

文件上传jsp编写

下面代码中,指定了enctype,同时使用了多个文件上传,name="files"。另外,form表单中也可以使用其他的文本框。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传</title>
</head>
<body>
<!--需要指定enctype="multipart/form-data",才能使用文件上传功能-->
<form action="save_file" method="post" enctype="multipart/form-data" >
    <table>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td>Select a file to upload</td>
            <td><input type="file" name="files" /></td>
        </tr>
        <tr>
            <td>Name</td>
            <td><input type="text" name="name" /></td>
        </tr>
        <tr>
            <td>Email</td>
            <td><input type="text" name="email" /></td>
        </tr>
        <tr>
            <td><input type="submit" value="Submit" /></td>
        </tr>
    </table>
</form>
</body>
</html

Contorller处理代码

@Controller
public class UploadFileController {
@RequestMapping(value = "/upload_file")
public String uploadFile(){
    return "uploadFile";
}

@RequestMapping(value = "/save_file")
/**
 * 多个文件上传,对应需要MultipartFile[]数组,否则不需要数组
 */
public String saveFile(@RequestParam("files")MultipartFile[] files,
                       @RequestParam("name") String name,
                       HttpServletRequest request,Model model){
    //保存文件
    if(files != null && files.length > 0){
        for(MultipartFile file : files){
            String fileName = file.getOriginalFilename();
            String dir = "E://test";
            File saveFile = new File(dir,fileName);
            try {
                //文件保存到本地
                file.transferTo(saveFile);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    //显示添加请求对象,在fileLists.jsp重可以使用EL表达式访问对象,即${files}
    request.setAttribute("files",files);
    request.setAttribute("name",name);
    //也可以不添加对象,在fileLists.jsp总可以直接使用EL隐式对象param来访问,即${param.email}来访问
    //request.setAttribute("email",email);

    //使用Model添加,为啥在jsp中访问不到?
    //model.addAttribute(files);
    //model.addAttribute(name);
    return "fileLists";
}
}

Controller中处理方法使用@RequestParam注解接受请求中的参数,传递给处理方法参数,使用MultipartFile数组参数接收上传的文件。另外,可以通过在参数中定义HttpServletRequest对象来获得原始的请求对象,然后调用request.setAttribute方法设置视图对象,在返回的jsp视图中通过EL表达式引用这些对象,EL表达式中提供了一些隐式对象,例如param,这是一个包含所有请求参数,并用参数名作为key的Map,通过param隐式对象,可以直接访问某一个请求参数。具体访问方式见代码中注解部分。

fileLists.jsp代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<html>
<head>
    <title>File List</title>
</head>
<body>
<table>
    <tr>
        <td>Name:</td>
        <td>${name}</td>
    </tr>
    <tr>
        <td>Email</td>
        <td>${param.email}</td>
    </tr>
    <c:forEach items="${files}" var="file">
        <tr>
            <td>OriginalFileName:</td>
            <td>${file.originalFilename}</td>
        </tr>
        <tr>
            <td>Type:</td>
            <td>${file.contentType}</td>
        </tr>
    </c:forEach>
</table>
</body>
</html>

fileLists.jsp中通过EL表达式来访问对象,包含param隐式对象和controller中添加的files对象,该对象为MultipartFile数组

Servlet3.0及3.0之后使用文件上传功能

有了Servlet 3.0,就不需要Commons FileUpload和Commons IO元件了。在Servlet 3.0及其以上版本的容器中进行服务器端文件上传的编程,是围绕着注解类型MultipartConfig和javax. servlet.http.Part接口进行的。处理已上传文件的Servlets必须以@MultipartConfig进行注解。Spring MVC的DispatcherServlet处理大部分或者所有请求。如果不修改源代码,将无法对Servlet进行注解。但值得庆幸的是,Servlet 3.0中有一种比较容易的方法,能使一个Servlet变成一个MultipartConfig Servlet,即给部署描述符(web.xml)中的Servlet声明赋值。在web.xml中添加multipart-config标签与用@MultipartConfig给DispatcherServlet进行注解的效果一样。

web.xml配置

<?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"
         version="4.0">
    <!-- 配置前端控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <!-- contextConfigLocation配置springmvc加载的配置文件适配器、处理映射器等-->
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/config/springmvc-config.xml</param-value>
        </init-param>
        <!--值不为0表示,tomcat启动该应用时,加载servlet,而不是等到第一请求到来时再加载servlet-->
        <load-on-startup>1</load-on-startup>
        <multipart-config>
            <!--临时目录,需要目录存在,否则报错-->
            <location>E:\\tmp</location>
            <max-file-size>20848820</max-file-size>
            <max-request-size>418018841</max-request-size>
            <!--上传文件超出这个容量界限时,会被写入磁盘。-->
            <file-size-threshold>1048576</file-size-threshold>
        </multipart-config>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 所有访问都由DispatcherServlet进行解析-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    </web-app>

spring配置文件中,配置multipartResolver

<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver"></bean>

结果

文件上传

显示

参考

posted @ 2019-07-13 14:15  远去的列车  阅读(2077)  评论(0编辑  收藏  举报