在客户端发送上传文件请求时,一般会与普通请求一样,将请求发送给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参数之间的绑定。