1.文件上传概述
-
form表单的method属性设置为post
-
form表单的enctype属性设置为multipart/form-data
-
提供<input type="file" name="filename"/>的文件上传输入框
文件上传表单的示例代码如下:
<form action="uploadUrl" method="post" enctype="multipart/form-data">
<input type="file" name="filename" multiple="multiple"/>
<input type="submit" value="文件上传"/>
</form>
当客户端form表单的enctype属性为multipart/form-data时,浏览器就会采用二进制流的方式来处理表单数据,服务器端就会对文件上传的请求进行解析处理.springmvc通过multipartResolver(多部件解析器)完成文件上传工作
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置请求编码格式,必须与JSP中的pageEncoding属性一致,默认为ISO-8859-1-->
<property name="defaultEncoding" value="UTF-8"/>
<!--设置允许上传文件的最大值(2MB),单位为字节-->
<property name="maxUploadSize" value="2097152"/>
...
</bean>
属性 | 描述 |
maxUploadSize | 上传文件最大长度(以字节为单位) |
maxInMemorySize | 缓存中的最大尺寸 |
defaultEncoding | 默认编码格式 |
resolveLazily | 推迟文件解析,以便在Controller中捕获文件大小异常 |
文件上传的代码:
@Controller
public class FileUploadController{
@RequestMapping("/fileUpload")
public String handleFormUpload(@RequestParam("name")String name,@RequestParam("filename")MultipartFile file,...){
if(!file.isEmpty()){
//具体的执行方法
...
return "uploadSuccess";
}
return "uploadFailure";
}
}
方法 | 说明 |
byte[]getBytes() | 以字节数组的形式返回文件的内容 |
String getContentType() | 返回文件的内容类型 |
InputStream getInputStream() | 读取文件内容,返回一个InputStream流 |
String getName() | 获取多部件form表单的参数名称 |
String getOriginalFilename() | 获取上传文件的初始化名 |
long getSize() | 获取上传文件的大小,单位是字节 |
boolean isEmpty() | 判断上传的文件是否为空 |
void transferTo(File file) | 将上传文件保存到目标目录下 |
2.案例:文件上传
(1)创建chapter16项目,导入相关jar包
(2)在web.xml中,配置springmvc的前端控制器等信息
(3)springmvc-config.xml
<!--定义组件扫描器,指定需要扫描的包-->
<context:component-scan base-package="com.itcast.controller"/>
<!--配置注解驱动-->
<mvc:annotation-driven/>
<!--定义视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<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="defaultEncoding" value="UTF-8"/>
</bean>
(4)创建一个用于上传页面的fileUpload.jsp
<title>文件上传</title>
<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>
</head>
<body>
<form action="${pageContext.request.contextpath}/fileUpload"
method="post" enctype="multipart/form-data" onsubmit="return check()">
上传人:<input id="name" type="text" name="name"/><br/>
请选择文件:<input id="file" type="file" name="uploadfile" multiple="multiple"/><br/>
<input type="submit" value="上传"/>
</form>
</body>
(5)在WEB-INF目录下,创建jsp文件夹,并在文件夹中创建success.jsp和error.jsp文件,分别在两个文件的<body>元素内编写显示上传成功的信息("文件上传成功")和显示上传失败的信息("文件上传失败,请重新上传")
(6)FileUploadController
/*
文件上传
*/
@Controller
public class FileUploadController{
//执行文件上传
@RequestMapping("/fileUpload")
public String handleFormUpload(@RequestParam("name")String name,@RequestParam("uploadfile") List<MultipartFile> uploadfile,HttpServletRequest request){
//判断所上传文件是否存在
if(!uploadfile.isEmpty()&&uploadfile.size()>0){
//循环输出上传的文件
for(MultipartFile file:uploadfile){
//获取上传文件的原始名称
String originalFilename=file.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接口的方法完成文件上传到指定位置
}catch(Exception e){
e.printStackTrace();
return "error";
}
}
//跳转到成功页面
return "success";
}else{
return "error";
}
}
}
3.案例:中文名称的文件下载
(1)download.jsp
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<%@page import="java.net.URLEncoder"%>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>下载页面</title>
</head>
<body>
<a href="${pageContext.request.contextpath}/download?filename=<%=URLEncoder.encode("壁纸.jpg","UTF-8")%>">中文名称文件下载
</a>
</body>
</html>
(2)FileUploadController
@RequestMapping("/download")
public ResponseEntity<byte[]>fileDownload(HttpServletRequest request,String filename)throws Exception{
//指定要下载的文件所在路径
String path=request.getServletContext().getRealPath("/upload/");
//创建该文件对象
File file=new File(path+File.separator+filename);
//对文件名编码,防止中文文件乱码
filename=this.getFilename(request,filename);
//设置响应头
HttpHeaders headers=new HttpHeaders();
//通知浏览器以下载的方式打开文件
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
//使用springmvc框架的ResponseEntity对象封装返回下载数据
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.OK);
}
//根据浏览器的不同进行编码设置,返回编码后的文件名
public String getFilename(HttpServletRequest request,String filename)throws Exception{
//IE不同版本User-Agent中出现的关键词
String[]IEBrowserKeyWords={"MSIE","Trident","Edge"};
//获取请求头代理信息
String userAgent=request.getHeader("User-Agent");
for(String keyword:IEBrowserKeyWords){
if(userAgent.contains(keywords)){
//IE内核浏览器同一位UTF-8编码显示
return URLEncoder.encode(filename,"UTF-8");
}
}
//火狐等其它浏览器统一为ISO-8859-1编码显示
return new String(filename.getBytes("UTF-8"),"ISO-8859-1");
}