Spring MVC 4 使用常规的fileupload上传文件(带源码)

来源:互联网 发布:视频广告过滤 知乎 编辑:程序博客网 时间:2024/06/15 22:08

【本系列其他教程正在陆续翻译中,点击分类:spring 4 mvc 进行查看。源码下载地址在文章末尾。

【翻译 by 明明如月 QQ 605283073】

上一篇: 

Spring MVC 4 文件上传下载 Hibernate+MySQL例子 (带源码)

原文地址:http://websystique.com/springmvc/spring-mvc-4-file-upload-example-using-commons-fileupload/

本文将实现使用SpringMultipartResolver实现单个或者多文件上传.Spring提供内置multipart 支持用来处理web 应用中文件上传。





注意:multipart 是 enctype=”multipart/form-data”的内容.

简单预览

Spring使用MultiPartResolver接口实现文件上传.

  • 1. 使用Apache Commons . Spring CommonsMultipartResolver 使用Apache Commons FileUpload 实现 MultipartResolver  . 它需要apache 的commons-fileupload.jar 包. 虽然不针对Servlet 3但是Servlet 3.x容器中使用也没问题。
  • 2. 要想用Servlet 3.0 multipart 请求 需要配置[XML or JavaConfig]..
  •  XML 设置, 你需要在 web.xml的"multipart-config" 节点配置DispatcherServlet.
    如果是Annoataion/JavaConfig配置, 在DispatcherServlet 注册javax.servlet.MultipartConfigElement  .或者使用 @MultipartConfig定义servlet.

本文主要用CommonsMultipartResolver . 下一篇文章使用Servlet 3.0 来实现文件上传.

步骤:

  • 创建一个CommonsMultipartResolver类型的bean , 指明和文件上传相关的配置文件
  • 在类路径包含 Apache Commons commons-fileupload.jar文件.
  • 表单中要含有[enctype=”multipart/form-data”]
  • 处理文件的input类型应该是 ‘file’

类似如下:

<form method="POST" enctype="multipart/form-data" >....<input type="file" id="file" />....<input type="submit" value="Upload"></form>

完整的例子

用到的技术和软件
  • Spring 4.2.0.RELEASE
  • Apache Commons fille-upload 1.3.1
  • validation-api 1.1.0.Final
  • Bootstrap v3.3.2
  • Maven 3
  • JDK 1.7
  • Tomcat 8.0.21
  • Eclipse JUNO Service Release 2

项目结构



在pom.xml文件中声明依赖

<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.websystique.springmvc</groupId>  <artifactId>Spring4MVCFileUploadCommonsExample</artifactId>  <packaging>war</packaging>  <version>1.0.0</version>  <name>Spring4MVCFileUploadCommonsExample Maven Webapp</name>  <url>http://maven.apache.org</url>        <properties><springframework.version>4.2.0.RELEASE</springframework.version></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${springframework.version}</version></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version></dependency><!-- For user input validation --><dependency>            <groupId>javax.validation</groupId>            <artifactId>validation-api</artifactId>            <version>1.1.0.Final</version>        </dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency></dependencies><build><pluginManagement><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.2</version><configuration><source>1.7</source><target>1.7</target></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>2.4</version><configuration><warSourceDirectory>src/main/webapp</warSourceDirectory><warName>Spring4MVCFileUploadCommonsExample</warName><failOnMissingWebXml>false</failOnMissingWebXml></configuration></plugin></plugins></pluginManagement><finalName>Spring4MVCFileUploadCommonsExample</finalName></build></project>

创建配置类

package com.websystique.springmvc.configuration;import java.io.IOException;import org.springframework.context.MessageSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.support.ResourceBundleMessageSource;import org.springframework.web.multipart.commons.CommonsMultipartResolver;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.view.InternalResourceViewResolver;import org.springframework.web.servlet.view.JstlView;@Configuration@EnableWebMvc@ComponentScan(basePackages = "com.websystique.springmvc")public class HelloWorldConfiguration extends WebMvcConfigurerAdapter{@Bean(name="multipartResolver") public CommonsMultipartResolver getResolver() throws IOException{CommonsMultipartResolver resolver = new CommonsMultipartResolver();//Set the maximum allowed size (in bytes) for each individual file.resolver.setMaxUploadSizePerFile(5242880);//5MB//You may also set other available properties.return resolver;}@Override    public void configureViewResolvers(ViewResolverRegistry registry) {        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();        viewResolver.setViewClass(JstlView.class);        viewResolver.setPrefix("/WEB-INF/views/");        viewResolver.setSuffix(".jsp");        registry.viewResolver(viewResolver);    }    @Bean    public MessageSource messageSource() {        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();        messageSource.setBasename("messages");        return messageSource;    }    @Override    public void addResourceHandlers(ResourceHandlerRegistry registry) {        registry.addResourceHandler("/static/**").addResourceLocations("/static/");    }}


配置里面最重要的是 CommonsMultipartResolver Bean. 它是Apache Commons FileUpload里面的 MultipartResolver接口的实现。
你可以设置文件最大限制,headerEncoding 等,我们例子里只限制5M。

对应的XML配置形式:
<beans xmlns="http://www.springframework.org/schema/beans"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xmlns:mvc="http://www.springframework.org/schema/mvc"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.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-4.0.xsd">     <context:component-scan base-package="com.websystique.springmvc" />    <mvc:annotation-driven />     <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">     <!-- one of the several properties available; the maximum file size in bytes -->        <property name="maxUploadSizePerFile" value="5242880"/>    </bean>    <mvc:resources mapping="/static/**" location="/static/" />    <mvc:default-servlet-handler />    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">        <property name="basename">            <value>messages</value>        </property>    </bean>    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix">            <value>/WEB-INF/views/</value>        </property>        <property name="suffix">            <value>.jsp</value>        </property>    </bean> </beans>


创建模型类

Spring提供org.springframework.web.multipart.MultipartFile 类代表上传的文件,提供getName(), getContentType(), getBytes(), getInputStream()等方法。
package com.websystique.springmvc.model; import org.springframework.web.multipart.MultipartFile; public class FileBucket {     MultipartFile file;         public MultipartFile getFile() {        return file;    }     public void setFile(MultipartFile file) {        this.file = file;    }}

包装类:
package com.websystique.springmvc.model; import java.util.ArrayList;import java.util.List; public class MultiFileBucket {     List<FileBucket> files = new ArrayList<FileBucket>();         public MultiFileBucket(){        files.add(new FileBucket());        files.add(new FileBucket());        files.add(new FileBucket());    }         public List<FileBucket> getFiles() {        return files;    }     public void setFiles(List<FileBucket> files) {        this.files = files;    }}


创建控制器类

package com.websystique.springmvc.controller; import java.io.File;import java.io.IOException;import java.util.ArrayList;import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.util.FileCopyUtils;import org.springframework.validation.BindingResult;import org.springframework.web.bind.WebDataBinder;import org.springframework.web.bind.annotation.InitBinder;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.multipart.MultipartFile; import com.websystique.springmvc.model.FileBucket;import com.websystique.springmvc.model.MultiFileBucket;import com.websystique.springmvc.util.FileValidator;import com.websystique.springmvc.util.MultiFileValidator; @Controllerpublic class FileUploadController {     private static String UPLOAD_LOCATION="C:/mytemp/";         @Autowired    FileValidator fileValidator;          @Autowired    MultiFileValidator multiFileValidator;          @InitBinder("fileBucket")    protected void initBinderFileBucket(WebDataBinder binder) {       binder.setValidator(fileValidator);    }      @InitBinder("multiFileBucket")    protected void initBinderMultiFileBucket(WebDataBinder binder) {       binder.setValidator(multiFileValidator);    }          @RequestMapping(value={"/","/welcome"}, method = RequestMethod.GET)    public String getHomePage(ModelMap model) {        return "welcome";    }     @RequestMapping(value="/singleUpload", method = RequestMethod.GET)    public String getSingleUploadPage(ModelMap model) {        FileBucket fileModel = new FileBucket();        model.addAttribute("fileBucket", fileModel);        return "singleFileUploader";    }     @RequestMapping(value="/singleUpload", method = RequestMethod.POST)    public String singleFileUpload(@Valid FileBucket fileBucket, BindingResult result, ModelMap model) throws IOException {         if (result.hasErrors()) {            System.out.println("validation errors");            return "singleFileUploader";        } else {                        System.out.println("Fetching file");            MultipartFile multipartFile = fileBucket.getFile();             //Now do something with file...            FileCopyUtils.copy(fileBucket.getFile().getBytes(), new File(UPLOAD_LOCATION + fileBucket.getFile().getOriginalFilename()));                         String fileName = multipartFile.getOriginalFilename();            model.addAttribute("fileName", fileName);            return "success";        }    }          @RequestMapping(value="/multiUpload", method = RequestMethod.GET)    public String getMultiUploadPage(ModelMap model) {        MultiFileBucket filesModel = new MultiFileBucket();        model.addAttribute("multiFileBucket", filesModel);        return "multiFileUploader";    }     @RequestMapping(value="/multiUpload", method = RequestMethod.POST)    public String multiFileUpload(@Valid MultiFileBucket multiFileBucket, BindingResult result, ModelMap model) throws IOException {                  if (result.hasErrors()) {            System.out.println("validation errors in multi upload");            return "multiFileUploader";        } else {                        System.out.println("Fetching files");            List<String> fileNames= new ArrayList<String>();                         //Now do something with file...            for(FileBucket bucket : multiFileBucket.getFiles()){                FileCopyUtils.copy(bucket.getFile().getBytes(), new File(UPLOAD_LOCATION + bucket.getFile().getOriginalFilename()));                fileNames.add(bucket.getFile().getOriginalFilename());            }                         model.addAttribute("fileNames", fileNames);            return "multiSuccess";        }    }               }

Spring FileCopyUtils 工具类,可以将流从一个地方拷贝到目标文件夹。例子中目标目录是 C:/mytemp 所有文件将传到这里。

创建Validators类

package com.websystique.springmvc.util; import org.springframework.stereotype.Component;import org.springframework.validation.Errors;import org.springframework.validation.Validator; import com.websystique.springmvc.model.FileBucket; @Componentpublic class FileValidator implements Validator {         public boolean supports(Class<?> clazz) {        return FileBucket.class.isAssignableFrom(clazz);    }     public void validate(Object obj, Errors errors) {        FileBucket file = (FileBucket) obj;                 if(file.getFile()!=null){            if (file.getFile().getSize() == 0) {                errors.rejectValue("file", "missing.file");            }        }    }}

package com.websystique.springmvc.util; import org.springframework.stereotype.Component;import org.springframework.validation.Errors;import org.springframework.validation.Validator; import com.websystique.springmvc.model.FileBucket;import com.websystique.springmvc.model.MultiFileBucket; @Componentpublic class MultiFileValidator implements Validator {         public boolean supports(Class<?> clazz) {        return MultiFileBucket.class.isAssignableFrom(clazz);    }     public void validate(Object obj, Errors errors) {        MultiFileBucket multiBucket = (MultiFileBucket) obj;                 int index=0;                 for(FileBucket file : multiBucket.getFiles()){            if(file.getFile()!=null){                if (file.getFile().getSize() == 0) {                    errors.rejectValue("files["+index+"].file", "missing.file");                }            }            index++;        }             }}

messages.properties
missing.file= Please select a file.

创建视图


singleFileUploader.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%><html> <head>    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">    <title>Spring 4 MVC File Upload Example</title>    <link href="<c:url value='/static/css/bootstrap.css' />"  rel="stylesheet" type="text/css"></link>    <link href="<c:url value='/static/css/app.css' />" rel="stylesheet" type="text/css"></link></head><body>      <div class="form-container">        <h1>Spring 4 MVC File Upload Example </h1>        <form:form method="POST" modelAttribute="fileBucket" enctype="multipart/form-data" class="form-horizontal">                     <div class="row">                <div class="form-group col-md-12">                    <label class="col-md-3 control-lable" for="file">Upload a file</label>                    <div class="col-md-7">                        <form:input type="file" path="file" id="file" class="form-control input-sm"/>                        <div class="has-error">                            <form:errors path="file" class="help-inline"/>                        </div>                    </div>                </div>            </div>                 <div class="row">                <div class="form-actions floatRight">                    <input type="submit" value="Upload" class="btn btn-primary btn-sm">                </div>            </div>        </form:form>        <a href="<c:url value='/welcome' />">Home</a>    </div></body></html>

success.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html><head>    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">    <title>File Upload Success</title>    <link href="<c:url value='/static/css/bootstrap.css' />" rel="stylesheet"></link>    <link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link></head><body>    <div class="success">        File  <strong>${fileName}</strong> uploaded successfully.        <br/><br/>        <a href="<c:url value='/welcome' />">Home</a>     </div></body></html>


multiFileUploader.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%><html> <head>    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">    <title>Spring 4 MVC File Multi Upload Example</title>    <link href="<c:url value='/static/css/bootstrap.css' />"  rel="stylesheet" type="text/css"></link>    <link href="<c:url value='/static/css/app.css' />" rel="stylesheet" type="text/css"></link></head><body>      <div class="form-container">        <h1>Spring 4 MVC Multi File Upload Example </h1>        <form:form method="POST" modelAttribute="multiFileBucket" enctype="multipart/form-data" class="form-horizontal">                     <c:forEach var="v" varStatus="vs" items="${multiFileBucket.files}">                <form:input type="file" path="files[${vs.index}].file" id="files[${vs.index}].file" class="form-control input-sm"/>                <div class="has-error">                    <form:errors path="files[${vs.index}].file" class="help-inline"/>                </div>            </c:forEach>            <br/>            <div class="row">                <div class="form-actions floatRight">                    <input type="submit" value="Upload" class="btn btn-primary btn-sm">                </div>            </div>        </form:form>                 <br/>        <a href="<c:url value='/welcome' />">Home</a>    </div></body></html>

multiSuccess.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html><head>    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">    <title>File Upload Success</title>    <link href="<c:url value='/static/css/bootstrap.css' />" rel="stylesheet"></link>    <link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link></head><body>    <div class="success">            <c:forEach var="fileName" items="${fileNames}">                File  <strong>${fileName}</strong> uploaded successfully<br/>            </c:forEach>            <br/>        <a href="<c:url value='/welcome' />">Home</a>    </div></body></html>

welcome.jsp
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html> <head>    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">    <title>Spring 4 MVC File Upload Example</title>    <link href="<c:url value='/static/css/bootstrap.css' />"  rel="stylesheet"></link>    <link href="<c:url value='/static/css/app.css' />" rel="stylesheet"></link></head><body>    <div class="form-container">        <h1>Welcome to FileUploader Example</h1>                 Click on below links to see FileUpload in action.<br/><br/>                 <a href="<c:url value='/singleUpload' />">Single File Upload</a>  OR  <a href="<c:url value='multiUpload' />">Multi File Upload</a>    </div> </body></html>

创建初始化类

package com.websystique.springmvc.configuration; import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; public class HelloWorldInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {       @Override    protected Class<?>[] getRootConfigClasses() {        return new Class[] { HelloWorldConfiguration.class };    }       @Override    protected Class<?>[] getServletConfigClasses() {        return null;    }       @Override    protected String[] getServletMappings() {        return new String[] { "/" };    }   }

构建部署和运行应用


在tomcat里面发布
访问 http://localhost:8080/Spring4MVCFileUploadCommonsExample/

点击 单文件上传链接:


如果没有选择文件直接点击“upload”

提示:请选择一个文件

选择文件




你可以去C:/mytemp 文件夹看看,文件是否传上去了

现在返回  选择  multi upload(多文件)上传链接

如果没有选择文件 直接点击上传也会有验证失败的提示:


选择文件:


查看上传的文件:


本文结束。下一篇将讲述 使用Spring 3.0指定api实现文件上传》


项目下载地址:http://websystique.com/?smd_process_download=1&download_id=1741
2 0
原创粉丝点击