文件上传主要使用到CommonsMultipartResolver这个实体类,使用程序上下文和ServletContext 容器初始化,将临时文件保存到servlet的临时目录,继承于CommonsFileUploadSupport,其构造函数代码如下:
public CommonsMultipartResolver(ServletContext servletContext) {
this();
setServletContext(servletContext);
}
可以使用request.getSession().getServletContext().getRealPath("/");获取当前服务器的根目录,将文件保存到指定位置。在实现文件上传功能是需要配置如下运行环境:
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>test</groupId>
<artifactId>fileUpDown</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>fileUpDown Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
</dependencies>
<build>
<finalName>fileUpDown</finalName>
</build>
</project>
web.xml:
<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<filter>
<description>字符集过滤器</description>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<description>字符集编码</description>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>*.do</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>
spring.xml:
<?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-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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:annotation-config />
<mvc:annotation-driven />
<context:component-scan base-package="controllers" />
<!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->
<bean id="mappingJacksonHttpMessageConverter"
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=utf-8</value>
</list>
</property>
</bean>
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="mappingJacksonHttpMessageConverter" /><!-- json转换器 -->
</list>
</property>
</bean>
<!-- 支持上传文件 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
<!-- 100M -->
<property name="maxUploadSize" value="104857600"></property>
<property name="defaultEncoding" value="utf-8"></property>
</bean>
</beans>
代码实现如下:
@RequestMapping(value = "/upLoadFile.do", method = RequestMethod.POST)
public void upLoadFile(HttpServletRequest request,HttpServletResponse response)
throws IllegalStateException, IOException {
//打印request参数
logger.info("name:"+request.getParameter("name"));
//MultipartResolver 用于处理文件上传
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(
request.getSession().getServletContext());
// 判断 request 是否有文件上传
if (multipartResolver.isMultipart(request)) {
// request转换成多部分request
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
// 取得request中的所有文件名
Iterator<String> iter = multiRequest.getFileNames();
while (iter.hasNext()) {
// 取得上传文件
MultipartFile f = multiRequest.getFile(iter.next());
if (f != null) {
// 取得当前上传文件的文件名称
String myFileName = f.getOriginalFilename();
// 如果名称不为"",说明该文件存在,否则说明该文件不存在
if (myFileName.trim() != "") {
// 定义上传路径
String strDirPath = request.getSession().getServletContext().getRealPath("/");
String path = strDirPath+"audio"+File.separator+ myFileName;
File localFile = new File(path);
f.transferTo(localFile);
}
}
}
}
response.sendRedirect("index.jsp");
}
前端可以使用表单实现文件上传,也可以使用Ajax实现。
表单获取,其中文件存放在项目的webapp->WEB-INF下
<form action="./upLoadFile.do" method="post" enctype="multipart/form-data">
选择文件:<input type="file" name="file"/>
<input type="submit" value="提交"/>
</form>
Ajax获取
<div id="uploadForm">
<input id="file" type="file" />
<button id="upload" type="button" οnclick="upload()">upload</button>
<img src="" id="img">
</div>
<script>
//FormData和FileReader方式实现文件上传
function upload() {
var inputBox = document.getElementById("file");
debugger;
//用于读取文件
var reader = new FileReader();
reader.readAsDataURL(inputBox.files[0]); //发起异步请求
img.src = reader.result;
reader.onload = function() {
console.log("加载成功");
}
var formData = new FormData();
formData.append('file', $('#file')[0].files[0]);
formData.append("name", "liu");
$.ajax({
url: 'http://localhost:8080/fileUpDown/upLoadFile.do',
type: 'POST',
cache: false,
data: formData,
processData: false,
contentType: false
}).done(function(res) {}).fail(function(res) {});
}
</script>
文件的下载:
在执行下载操作时需要设置报文的请求头,使用HttpHeaders进行相关的参数设置,如:headers.setContentDispositionFormData("attachment", fileName); 用于设置服务器内部的文件储存位置,headers.setContentType(MediaType.MULTIPART_FORM_DATA);用于设置报文header的媒体类型。在接口返回时,需要使用到ResponseEntity,该类继承于HttpEntity,添加了响应报文所需要的状态码。前端使用超链接即可实现文件下载:<a href="./download.do" >文件下载</a>
@RequestMapping("download.do")
public ResponseEntity<byte[]> download(HttpServletRequest request) throws IOException {
String strDirPath = request.getSession().getServletContext().getRealPath("/");
String path = strDirPath+"audio"+File.separator+ "Superstition.mp3";
File file=new File(path);
HttpHeaders headers = new HttpHeaders();
String fileName=new String("Superstition.mp3".getBytes("UTF-8"),"iso-8859-1");//为了解决中文名称乱码问题
headers.setContentDispositionFormData("attachment", fileName);
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.CREATED);
}