SpringMvc学习笔记(九)文件上传和下载
文件上传和下载,在上传的操作之后,跳转到下载页面
源码获取github
1.项目结构
2.上传操作
单文件的上传
- form表单传递数据
- 请求必须为POST请求
- 使用二进制流的方式传递数据 enctype=”multipart/form-data”
- 文件域 <input type=”file” name=”myfile”/>
- 上传的工具有两种:
- Servlet3.0
- Commons-FileUpload
- commons-fileupload.jar
- commons-io.jar
第一步:配置解析器
springmvc.xml加入
<!--5.使用上传的解析器,如果发现是上传操作,会自动使用该解析器帮我们完成相应的操作-->
<!--该ID为固定值-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--设置上传文件编码-->
<!--简写方式 标签p c注入 p:defaultEncoding = "UTF-8"-->
<property name="defaultEncoding" value="UTF-8"/>
<!--设置文件上传最大值024*200即200K-->
<property name="maxUploadSize" value="20971520"/>
<!--缓存,读取文件到内存中最大的字节数,可以不设置-->
<property name="maxInMemorySize" value="2048"/>
<!--延时提高上传效率,一个类似懒加载的属性-->
<property name="resolveLazily" value="true"/>
</bean>
如果是图片资源,还要配置静态资源排除,见之前的笔记
第二步:前端页面表单和前台验证
file.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h2>单文件上传</h2>
<form action="upload01" method="post" enctype="multipart/form-data" id="uploadForm">
标题:<input type="text" name="title">
文件:<input type="file" name="myfile" id="myfile"><br>
<button>文件上传</button>
</form>
<script type="text/javascript" src="resource/jquery.js"></script>
<script type="text/javascript"> $(function () { //元素选择器 $("button").click(function () { //1.获取上传文件的对象,是数组,获取的第一个 var myfile = $("#myfile").prop("files")[0]; //2.判断文件是否有 if (myfile) { //3.获取文件名称 var fileName = myfile.name; //4.获取文件的后缀名称 var ext = fileName.substring(fileName.lastIndexOf(".") + 1); //5.设置允许上传的文件后缀名称 var allowFileTypes = ["jpg", "png", "gif", "jpeg", "dmp", "rar"]; //6.设置一个标识,用来做判断 var flag = false; //循环判断上传格式是否正确 for (var i = 0; i < allowFileTypes.length; i++) { if (ext == allowFileTypes[i]) { flag = true; break; } } if (!flag) { alert("您上传的文件格式不正确,允许的格式为:" + allowFileTypes.join(" | ")); return false; } //7.判断文件的大小 if (myfile.size > 20 * 1024 * 1024) { alert("您上传的文件过大,请重新选择") } return false; //8.表单提交 ${"#uploadForm"}.submit(); } else { alert("请选择您要上传的文件"); return false; } }) }) </script>
</body>
</html>
第三步:后台处理
UploadDemoController.java
package com.hs.web;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Random;
/** * 文件上传操作 */
@Controller
public class UploadDemoController {
/** * 单文件上传_标准写法 * * @param title * @param myfile * @param request * @return */
@PostMapping("/upload01")
public ModelAndView test01(String title, MultipartFile myfile, HttpServletRequest request) throws IOException {
ModelAndView mav = new ModelAndView();
// System.out.println(title);
//1.获取上传文件的名称
String fileName = myfile.getOriginalFilename();
mav.addObject("fileName", fileName);
//2.判断文件名称是否有值,isEmpty是这个字符串的length=0为true
if (!fileName.isEmpty()) {
//3.获取服务器的绝对路径
String path = request.getServletContext().getRealPath("/upload");
//4.建立联系
File folder = new File(path);
//5.判断该文件是否存在,不存在则创建文件夹
if (!folder.exists()) {
folder.mkdirs(); //创建文件夹
}
//6,获取上传文件的后缀名称
String ext = FilenameUtils.getExtension(fileName);
//7.创建新的文件名称
//String newFileName = UUID.randomUUID().toString() + "." + ext;
//或者用时间戳创建名称
String newFileName = new Date().getTime() + "_" + new Random().nextInt(100000) + "." + ext;
mav.addObject("newFileName", newFileName);
// System.out.println(newFileName);
//8.文件上传,File.separator为斜线
myfile.transferTo(new File(path + File.separator + newFileName));
}
mav.addObject("hs", "和尚");
mav.setViewName("jsp/result");
/*System.out.println("测试是否可以获取正常的数据:"+title); System.out.println("====="); System.out.println("文件的MIME类型 :"+myfile.getContentType()); System.out.println("文件NAME属性对应的值 :"+myfile.getName()); System.out.println("上传文件的名称 :"+myfile.getOriginalFilename()); System.out.println("上传文件的大小 :"+myfile.getSize());*/
return mav;
}
}
3.下载操作
方式一:直接超链接方式显示
result.jsp
<h2>直接超链接方式显示</h2>
<a href="upload/${newFileName }">${fileName }</a>
方式二:HTML5 中的download属性
<h2>HTML5 中的download属性</h2>
<a href="upload/${newFileName }" download="${fileName }">${fileName }</a>
方式三:使用流的方法–到控制层处理
<h2>使用流的方法--到控制层处理,发送请求到控制器,download</h2>
<a href="download?newFileName=${newFileName}&fileName=${fileName}">${fileName }下载</a>
在springmvc.xml声明处理byte数组,在解决@ResponseBody在IE浏览器的BUG问题上面
<!--解决下载的时候转换问题,声明处理byte数组-->
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
DownloadDemoController.java处理流
package com.hs.web;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
/** * 文件下载操作 */
@Controller
public class DownloadDemoController {
/** * 文件下载,使用流的方法 * * @param newFileName * @param fileName * @param request * @return * @throws IOException */
@GetMapping("/download")
public ResponseEntity<byte[]> test02(String newFileName, String fileName, HttpServletRequest request) throws IOException {
//获取服务端的绝对路径
String path = request.getServletContext().getRealPath("/upload/");
HttpHeaders headers = new HttpHeaders();
//设置相应的内容为流
headers.setContentType(MediaType.TEXT_EVENT_STREAM);
//设置下载的名称--和中文乱码的问题
headers.setContentDispositionFormData("attachment",
new String(fileName.getBytes("UTF-8"), "ISO8859-1")
);
//找到文件
File file = new File(path + File.separator + newFileName);
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),/*将文件转换为byte数组*/
headers,
HttpStatus.CREATED);
}
}