在客户端发送上传文件请求时,一般会与普通请求一样,将请求发送给SpringMVC的前端控制器DispatcherServlet,然后由DispatcherServlet调用HandlerMapping找到处理该请求的Controller。然后DispatcherServlet将请求提交给Controller(如果不适用可以会自动调用HandlerAdapter适配)。Controller调用业务逻辑进行处理,返回一个值。DispatcherServlet查询一个或多个viewResolver视图解析器,找到返回值对应的视图。只不过文件上传功能实现需要对springmvc配置文件添加文件上传相关的配置,同时注意引入相关的包。在编写jsp文件以及controller类时,需要将表单元素与对应的controller方法的传入参数进行相关联,从而将两者绑定,以下进行文件上传功能的具体实现。
1.配置
本文是利用SpringMVC实现文件上传功能的,因此首先对其进行一些必要的配置,比如springmvc.xml,主要做如下配置:首先该实例都是基于注解实现的,所以需要启用spring基于注解的DI;既然是使用注解的,那就需要对自动扫描相应的包;又因为在处理请求的时候需要将请求参数绑定到控制器参数,所以需要启用注解驱动;最后需要配置视图解析器,本文配置的解析器是InternalResolverViewResolver。以上是基本的配置,由于本文需要实现的功能是文件上传,那么需要配置文件上传需要的配置,即文件上传解析器(CommonsMultipartResolver)。具体配置内容如下所示:
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd"> <!-- 启用基于注解的DI --> <context:annotation-config/> <!-- 扫描控制层@Controller注解的文件 --> <context:component-scan base-package="springmvc"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <!-- 开启注释驱动,可以将请求参数绑定到控制器参数 --> <mvc:annotation-driven /> <mvc:default-servlet-handler /> <!-- 配置jsp视图解析器 ,需要有jstl这个jar包,否则不能映射--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="209715200"/> <property name="defaultEncoding" value="UTF-8"/> <property name="resolveLazily" value="true"/> </bean> </beans>
对于web.xml只需要配置springmvc上下文即可,配置内容如下所示:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <!-- The front controller of this Spring Web application, responsible for handling all application requests --> <servlet> <servlet-name>springDispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springMVC-servlet.xml</param-value> <!-- param-value中的是Spring的配置文件,这个是放在src目录下的配置文件,如果放在其他位置可以使用路径+文件名 例如在WEB-INF 文件夹下面springmvc.xml 那么就可以写为<param-value>/WEB-INF/springmvc.xml</param-value> --> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- Map all requests to the DispatcherServlet for handling --> <servlet-mapping> <servlet-name>springDispatcherServlet</servlet-name> <url-pattern>/</url-pattern> <!--过滤全部文件--> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app>
2.Controller类
假定文件上传功能需要两个页面,即一个上传页面,一个为上传成功页面。因此对应了两个url,也就对应了两个相应的方法。这里两个方法分别是:showUpload和doUpload,具体代码如下:
import java.io.File; import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.commons.logging.*; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import com.sun.istack.internal.logging.Logger; @Controller public class UpLoadController { private static final Log logger=LogFactory.getLog(UpLoadController.class); @RequestMapping(value="/upload",method=RequestMethod.GET) public String showLoad() { return "upload"; } @RequestMapping(value="/doUpload",method=RequestMethod.POST) public String doUpLoad(@RequestParam("file")MultipartFile file,@RequestParam("name")String name) throws IOException { logger.debug("当前输入文件是:"+file.getOriginalFilename()); String original=file.getOriginalFilename(); { FileUtils.copyInputStreamToFile(file.getInputStream(),new File("C:\\Users\\carson0408\\Desktop\\photo",name+original)); } return "success"; } }
3.jsp文件
根据controller类编写视图层,首先是上传界面,需要用到file控件用于文件的上传,具体如下:
upload.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <div> <center> <body> <h1>hello,carson!welcome to this page!</h1> <br/> <br/> </center> </div> <form align="center" method="post" action="doUpload" enctype="multipart/form-data"> <table width="100%"> <tr> <td align="right">File Name:</td> <td><input type="text" name="name"></td> </tr> <tr> <td align="right">Select File</td> <td ><input type="file" name="file"/></td> </tr> <tr> <td align="right"><input type="submit" /></td> </tr> </form> </body> </html>
接下来就是上传成功的页面:
success.jsp:
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html" charset="UTF-8"> <title>Insert title here</title> </head> <body> <center><h1>Congratulation!Succeed to upload the file!</h1></center> </body> </html>
接着根据controller类和jsp文件进行实例讲解,首先controller类中的showUpload方法返回的是upload字串,对应upload.jsp页面,即输入/upload URL响应到upload.jsp页面。从upload.jsp可以看出该页面主要由一个file控件还有一个提交控件以及一个文本控件构成,文本控件主要填写一个name,用于文件保存使用;file控件用于文件的上传,而提交控件则用于请求的上传。最后可以看出该表单的action对应的url是"doUpload",则对应应该有个用@RequestMapping(value="doUpload")修饰的方法,即doUpload方法,该方法有两个变量一个file,一个name,那么如何将变量与表单元素绑定在一起呢,首先对应的变量与元素名字一致,其次就是用@RequestParam()在参数前修饰。其中如何将file元素传递出来呢,这时候需要一个MultipartFile接口,将file元素传递出来。file对象有一些参数可以用于保存文件:
isEmpty():用于判断文件是否为空。
getInputStream():获取文件输入,获取文件源
getOrignalName():获取原始命名。
这里还需要一个Commons.io包下的一个类FileUtils的copyInputStreamToFile用于文件的保存。
copyInputStreamToFile(InputStream arg0,File arg1);第一个参数表示输入流,即读取文件的输入流,第二个参数是一个File对象,这里用new File(保存地址,文件命名)来创建对象。
4.运行项目
1.首先启用tomcat运行项目。
2.在浏览器输入:http://localhost:8080/FirstSpringMVC/upload
3.得到如下页面:
4.上传两个文件,一个命名str,另一个utr
上传成功页面:
两个文件上传之后:
查看相应的文件夹:C:\\Users\\carson0408\\Desktop\\photo
5.总结
文件上传实现主要以下几方面:
1.配置文件上传配置CommonsMultipartResolver
2.导入需要的包
3.注意jsp元素与Controller参数之间的绑定。