SpringMVC:使用MultipartFile实现文件上传与下载
SpringMVC文件上传
1.什么是MutipartFile?
2.MutipartFile的源码分析:
3.使用的必备MultipartFile前提
3.1 文件上传客户端的三要素
3.2 导入fileupload和io坐标
4.文件上传实例
1.什么是MutipartFile?
MultipartFile是SpringMVC提供简化上传操作的工具类。
在不使用框架之前,都是使用原生的HttpServletRequest来接收上传的数据,文件是以二进制流传递到后端的,然后需要我们自己转换为File类。使用了MultipartFile工具类之后,我们对文件上传的操作就简便许多了。
2.MutipartFile的源码分析:
public interface MultipartFile extends InputStreamSource { String getName();//返回参数的名称 @Nullable String getOriginalFilename();//获取原始文件名 @Nullable String getContentType();//返回文件的内容类型 boolean isEmpty();//判断上传的文件是否有内容 long getSize();//返回文件大小,以字节为单位 byte[] getBytes() throws IOException;//将文件内容转换成一个byte[]返回 //getInputStream() 返回InputStream读取文件的内容 InputStream getInputStream() throws IOException; default Resource getResource() { return new MultipartFileResource(this); } //用来把MutipartFile转换成File void transferTo(File var1) throws IOException, IllegalStateException; default void transferTo(Path dest) throws IOException, IllegalStateException { FileCopyUtils.copy(this.getInputStream(), Files.newOutputStream(dest)); } }
public interface InputStreamSource { InputStream getInputStream() throws IOException; }
3.使用的必备MultipartFile前提
3.1 文件上传客户端的三要素
1)表单项type=“file”
2)表单的提交方式是POST
3)表单的enctype属性是多部分表单形式,即enctype=“multipart/form-data”
<form action="${pageContext.request.contextPath}/demo1" method="post" enctype="multipart/form-data"> 文件:<input type="file" name="file"><br> <input type="submit" value="提交">
3.2 导入fileupload和io坐标
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
4.文件上传实例
(1)前端上传功能代码说明
①获取form表单中input按钮的id,发送请求到控制层 users/change_avatar 把上传的图片保存到指定的磁盘路径下
②图片的显示是由图片的src属性决定的,把通过图片的id获取src属性的值,发送请求到/users/download ,从而在浏览器显示图
<form id="form-change-avatar"> <img id="img-avatar" src="../images/index/user.jpg" /> <input type="file" name="file"> <input id="btn-change-avatar" type="button" class="btn btn-primary" value="上传" /> </form> <script type="text/javascript"> $("#btn-change-avatar").click(function() { $.ajax({ url: "/users/change_avatar",//发送请求去上传图片到指定磁盘路径下 type: "POST", data: new FormData($("#form-change-avatar")[0]),//表单中可能有多个文件按钮,获得下标为0的文件 dataType: "JSON", processData: false, // processData处理数据 contentType: false, // contentType发送数据的格式 success: function(json) { if (json.state == 200) { $("#img-avatar").attr("src","/users/download?name="+json.data); } else { alert("修改失败!" + json.message); } }, error: function(xhr) { alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status); location.href = "login.html"; } }); }); </script> </body> </html>
(2)后端代码
@RestController @RequestMapping("/common") @Slf4j public class CommonController { @Value("${reggie.path}") private String basePath; //文件上传 @PostMapping("/upload") // MultipartFile类是org.springframework.web.multipart包下面的一个类, // 需要引入Spring框架。MultipartFile主要是用表单的形式进行文件上传 public R<String> upload(MultipartFile file){ //file是一个临时文件,需要转存到指定位置,否则本次请求完成后临时文件会删除 String originalFilename = file.getOriginalFilename();//原始文件名 String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//后缀 //使用UUID重新生成文件名,防止文件名称重复造成文件覆盖 String fileName = UUID.randomUUID().toString() + suffix;//dfsdfdfd.jpg //创建一个目录对象 File dir = new File(basePath); //判断当前目录是否存在 if(!dir.exists()){ //目录不存在,需要创建 dir.mkdirs(); } try { //将临时文件转存到指定位置 file.transferTo(new File(basePath + fileName)); } catch (IOException e) { e.printStackTrace(); } return R.success(fileName); } /** * 文件下载 * @param name * @param response */ @GetMapping("/download") public void download(String name, HttpServletResponse response){ try { //输入流,通过输入流读取文件内容 FileInputStream fileInputStream = new FileInputStream(new File(basePath + name)); //输出流,通过输出流将文件写回浏览器,在浏览器展示图片了 ServletOutputStream outputStream = response.getOutputStream(); response.setContentType("image/jpeg"); int len = 0; byte[] bytes = new byte[1024]; while ((len = fileInputStream.read(bytes)) != -1){ outputStream.write(bytes,0,len); outputStream.flush(); } //关闭资源 outputStream.close(); fileInputStream.close(); } catch (Exception e) { e.printStackTrace(); } } }