SpringMVC 实现文件上传和下载

SpringMVC 实现文件上传和下载

相关理论知识这里不进行介绍。这里主要介绍具体怎么来编程实现这样一个功能。html

具体步骤

具体步骤以下java

一、使用Idea建立一个Springmvc项目,具体过程略。web

二、在pom.xml中添加相关的依赖spring

pom.xml具体完整内容以下apache

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>com.wrh</groupId>
      <artifactId>fileupdowm</artifactId>
      <packaging>war</packaging>
      <version>1.0-SNAPSHOT</version>
      <name>fileupdowm Maven Webapp</name>
      <url>http://maven.apache.org</url>
      <dependencies>
          <dependency>
              <groupId>junit</groupId>
              <artifactId>junit</artifactId>
              <version>4.12</version>
              <scope>test</scope>
          </dependency>
          <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
          <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-webmvc</artifactId>
              <version>4.3.8.RELEASE</version>
          </dependency>

        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.3.2</version>
        </dependency>
          <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
          <dependency>
              <groupId>javax.servlet</groupId>
              <artifactId>javax.servlet-api</artifactId>
              <version>3.1.0</version>
          </dependency>
      </dependencies>
      <build>
        <finalName>fileupdowm</finalName>
      </build>
    </project>

三、编写web.xml文件编程

具体内容以下,该文件没有什么特殊的东西。api

<?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_3_1.xsd" version="3.1">

    <display-name>winner-test Web Application</display-name>
    <servlet>
      <servlet-name>mvc-dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!--指定了核心配置文件的位置 -->
      <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:mvc-dispatcher.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>mvc-dispatcher</servlet-name>
      <url-pattern>*.do</url-pattern>
    </servlet-mapping>

  </web-app>

四、mvc-dispatcher.xml文件浏览器

在工程的resources目录下新建一个mvc-dispatcher.xml文件 ,并添加以下内容。spring-mvc

<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

        <!-- 配置包扫描器 -->
        <context:component-scan base-package="com.wrh.controller"/>
        <!-- 配置注解驱动 -->
        <mvc:annotation-driven/>
        <!-- 视图解析器 -->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/WEB-INF/views/"/>
            <property name="suffix" value=".jsp"/>
        </bean>
        <!-- 文件上传的配置 -->
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 指定所上传文件的总大小不能超过2000KB。注意maxUploadSize属性的限制不是针对单个文件,而是全部文件的容量之和 -->
            <property name="maxUploadSize" value="2000000"/>
        </bean>

        <!-- 该异常是SpringMVC在检查上传的文件信息时抛出来的,并且此时尚未进入到Controller方法中 -->
        <bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
            <property name="exceptionMappings">
                <props>
                    <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到WebContent目录下的error.jsp页面 -->
                    <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error</prop>
                </props>
            </property>
        </bean>

    </beans>

mvc-dispatcher.xml文件中核心时配置MultipartResolver,这里选择的是CommonsMultipartResolver实现类。除此以外,还有另一种:StandardServletMultipartResolver,后者更优。更多相关知识能够参考《Spring In Action》这本书。tomcat

五、编写控制器程序来处理上传和下载。

5.一、首先编写一个用于在本地选择上传文件的交互页面upload.jsp文件

具体内容以下:

<%-- Created by IntelliJ IDEA. User: wuranghao Date: 2017/5/30 Time: 上午10:33 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="upload.do" method="post" enctype="multipart/form-data">
            文件1: <input type="file" name="myfiles"/><br/>
            文件2: <input type="file" name="myfiles"/><br/>
            文件3: <input type="file" name="myfiles"/><br/>
            <input type="submit" value="上传">
        </form>
    </body>
    </html>

该文件直接放在工程的webapp文件夹下,便于外部使用url=localhost:8080/upload.jsp这样的形式来访问。该页面的表现形式以下图所示。

当点击页面上的上传按钮,将会将内容提交到url=localhost:8080/upload.do 上.所以须要在控制器中编写相应的处理方法来进行处理。具体见下面。

5.2 在控制器中编写上传文件的处理器方法

/** * @Author:wojiushimogui * @Description: * @Date:Created by 上午10:34 on 2017/5/30. */
    @Controller
    public class UpLoadController {
        /** * 上传图片,保存在相应的目录下。 * */
        @RequestMapping(value = "/upload.do" ,method = RequestMethod.POST)
        public String upload(@RequestParam MultipartFile[] myfiles, HttpServletRequest request) throws IOException {

            for(MultipartFile file : myfiles){
                //此处MultipartFile[]代表是多文件,若是是单文件MultipartFile就好了
                if(file.isEmpty()){
                    System.out.println("文件未上传!");
                }
                else{
                    //获得上传的文件名
                    String fileName = file.getOriginalFilename();
                    //获得服务器项目发布运行所在地址
                    String path1 = request.getSession().getServletContext().getRealPath("WEB-INF/views")+ File.separator;
                    // 此处未使用UUID来生成惟一标识,用日期作为标识
                    String path = path1+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+ fileName;
                    //打印文件上传路径,方便查看是否上传成功
                    System.out.println(path);
                    //把文件上传至path的路径
                    File localFile = new File(path);
                    file.transferTo(localFile);
                }
            }
            return "uploadSuccess";
        }

    }

到这里为止,就实现了上传文件。当运行该项目以后在浏览器输入:localhost:8080/upload.jsp并点击“上传”以后,若是在tomcat的工做目录下找到相应的文件(以下图所示),则代表上传成功。

既然有上传文件,则可能有下载文件,下载文件改如何来实现呢?具体看下面

六、下载文件

6.一、首先编写一个用于选择哪些下载文件的交互页面download.jsp

具体内容以下

<%-- Created by IntelliJ IDEA. User: wuranghao Date: 2017/5/30 Time: 上午10:40 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>
    <a href="download.do?fileName=201705301151463.png">下载</a>
    </body>
    </html>

download.jsp文件比较简单,这里为了简单的测试,这里直接了以前上传的某一个文件。
当点击该页面中的”下载“将会跳转到url=localhost:8080/download.do?fileName=01705301151463.png 。为实现下载,须要为此url编写相应的处理函数。

6.二、在控制器中编写下载文件的处理函数

/** * 下载指定图片 * */
        @RequestMapping("/download.do")
        public String download(String fileName, HttpServletRequest request,
                               HttpServletResponse response) {
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            response.setHeader("Content-Disposition", "attachment;fileName="
                    + fileName);
            try {
                String path = request.getSession().getServletContext().getRealPath
                        ("WEB-INF/views")+File.separator;
                InputStream inputStream = new FileInputStream(new File(path
                        + fileName));

                OutputStream os = response.getOutputStream();
                byte[] b = new byte[2048];
                int length;
                while ((length = inputStream.read(b)) > 0) {
                    os.write(b, 0, length);
                }

                // 这里主要关闭。
                os.close();

                inputStream.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 返回值要注意,要否则就出现下面这句错误!
            //java+getOutputStream() has already been called for this response
            return null;
        }

测试结果以下:

遇到的错误

一、因为在mvc-dispatcher.xml中配置MultipartResolver时,指定了上传文件的总大小为200K,若是文件超过此大小,则会报以下的错误。

二、原本想在项目的WEB-INF目录下新建一个子目录image,当部署成功后,上传成功的图片存储在此目录下,没想到的时报错,部署成功后并无生成此目录。可能细心的你发现了在上传文件的处理器方法中有这样一行代码:放在了视图文件夹中。

//获得服务器项目发布运行所在地址
String path1 = request.getSession().getServletContext().getRealPath("WEB-INF/views")+ File.separator;

参考资料

一、http://blog.csdn.net/qq_32953079/article/details/52290208