文件上传和下载+SSM
1. 文件上传
表单实现文件上传的三个条件
- form表单的method属性设置为post
- form表单的enctype属性设置为multipart/form-data
- 提供< input type=“file” name=“filename” />的文件上传输入框
<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="filename" multiple="multiple">
<input type="submit" value="上传">
</form>
当客户端form表单的enctype属性为multipart/form-data时,浏览器就会采用二进制流的方式来处理表单数据,服务器端就会对文件上传的请求进行解析处理。
Spring MVC为文件上传提供了直接的支持,这种支持是通MultipartResolver(多部件解析器)对象实现的。MultipartResolver是一个接口对象,需要通过它的实现类CommonsMultipartResolver来完成文件上传工作
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEnconding" value="utf-8"/>
<!-- 字节为单位 设置为2M-->
<property name="maxUploadSize" value="2097152"/>
</bean>
通过< property>元素可以对文件解析器类CommonsMultipartResolver的如下属性进行配置
属性 | 作用 |
---|---|
maxUploadSize | 上传文件最大长度(以字节为单位) |
maxInMemorySize | 缓存中的最大尺寸 |
defaultEncoding | 默认编码格式 |
resolveLazily | 推迟文件解析,以便在Controller中捕获文件大小异常 |
因为MultipartResolver接口的实现类CommonsMultipartResolver内部是引用multipartResolver字符串获取该实现类对象并完成文件解析的,所以在配置CommonsMultipartResolver时必须指定该Bean的id为multipartResolver
由于CommonsMultipartResolver是Spring MVC内部通过ApacheCommons FileUpload技术实现的,所以Spring MVC的文件上传还需要依赖Apache Commons FileUpload的组件
所依赖的jar包
- commons-fileupload-1.3.2.jar
- commons-io-2.5.jar
1.springmvc-config.xml
//常规配置省略,新填配置
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
</bean>
2.Controller类
上传到程序中的文件就是被封装在MultipartFile接口类型的参数中,此处用了一个List封装,用来实现批量上传。
MultipartFile接口的方法
@RequestMapping("/fileUpload")
public String handleFormUpload(@RequestParam("name") String name,
@RequestParam("file") List<MultipartFile> uploadFile,
HttpServletRequest request) {
if (!uploadFile.isEmpty() && uploadFile.size() > 0) {
for (MultipartFile multipartFile : uploadFile) {
//获取文件原名称
String originalFilename = multipartFile.getOriginalFilename();
String dirPath = request.getServletContext()
.getRealPath("/upload/");
File filePath = new File(dirPath);
// 路径不存在就新建路径
if (!filePath.exists()) {
filePath.mkdirs();
}
// 使用UUID重新命名上传的文件,UUID防止重名
String newFilename = name + "_" + UUID.randomUUID() + "_"
+ originalFilename;
try {
multipartFile.transferTo(new File(dirPath+newFilename));
} catch (Exception e) {
e.printStackTrace();
return "error";
}
}
return "success";
}else{
return "error";
}
}
3.jsp页面配置
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
function check() {
var name = document.getElementById("name").value;
var file = document.getElementById("file").value;
if (name == "") {
alert("请填写上传人");
return false;
}
if (file.length == 0 || file == "") {
alert("请选择上传文件");
return false;
}
return true;
}
</script>
<title>Insert title here</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/fileUpload"
method="post" enctype="multipart/form-data" onsubmit="return check">
上传人: <input type="text" id="name" name="name"/>
请选择文件: <input type="file" id="file" name="file" multiple="multiple"/>
<input type="submit" value="上传">
</form>
</body>
</html>
2. 文件下载
在Spring MVC环境中,实现文件下载大致可分为如下两个步骤
1)在客户端页面使用一个文件下载的超链接,该链接的href属性要指定后台文件下载的方法以及文件名
<a href="${pageContext.request.contextPath}/download?filename=1.jpg">文件下载</a>
2)在后台Controller类中,使用Spring MVC提供的文件下载方法进行文件下载
Spring MVC提供了一个ResponseEntity类型的对象,使用它可以很方便地定义返回的HttpHeaders对象和HttpStatus对象,通过对这两个对象的设置,即可完成下载文件时所需的配置信息
@RequestMapping("/download")
public ResponseEntity<byte[]> fileDownLoad(HttpServletRequest request,
String filename) throws IOException {
String path = request.getServletContext().getRealPath("/upload/");
// 创建文件对象
File file = new File(path + File.separator + filename);
// 防止中文乱码
filename = URLEncoder.encode(filename,"utf-8");
// 设置响应开头
HttpHeaders headers = new HttpHeaders();
// 通知浏览器以下载的方式打开文件
headers.setContentDispositionFormData("attachment", filename);
// 定义以流的形式下载返回文件数据
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
// 使用String MVC 框架的ResponseEntity对象封装返回下载数据
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),
headers, HttpStatus.OK);
}
防止中文乱码的jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.URLEncoder"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a
href="${pageContext.request.contextPath}/download?filename=<%=URLEncoder.encode("壁纸.jpg", "UTF-8")%>">文件下载</a>
</body>
</html>
3. SSM框架整合
所以Spring MVC与Spring之间不存在整合的问题,只要引入相应JAR包就可以直接使用。因此SSM框架的整合就只涉及Spring与MyBatis的整合,以及Spring MVC与MyBatis的整合
在10. Spring与Mybatis整合中已经整合了Spring和Mybatis,这里直接使用上次的项目,在此基础上整合mvc
注意:web项目不会识别lib下的子目录,因此,如果想对jar包分类,需要更改tomcat下的默认配置路径
整合配置
1. springmvc-config.xml新加
<context:component-scan
base-package="com.clarence.controller" />
2. web.xml中添加
<!-- 配置加载spring文件的监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
2.1 可选添加
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
整合时的dao层,使用mybatis用mapper映射形式注册,不必写Impl是实现类