SpringMVC文件上传及查看的示例代码

 更新时间:2018年01月11日 10:25:13   作者:fanyank  
本篇文章主要介绍了SpringMVC文件上传及查看的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

写在前面

谈到文件上传,首先要说业务逻辑,如果上传的文件大家都可以看(比如广告或者首页的banner)等,那么我们就把图片放在静态资源区(与css,js一样的位置)中,如果文件是受保护的(像用户只能查看自己上传的照片),那么我们就把它存放在服务器中的某个专门存放图片的位置。

本例分别展示了存放在两个位置的上传文件的方法,上传之后,作为延伸,还添加了查看上传的文件以及下载已经上传的文件的功能。

准备工作

配置SpringMVC,导入commons包

在mvc-servlet.xml中配置文件上传解析器

<!--文件上传解析器-->
 <bean id="multipartResolver"
  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="maxUploadSize" value="1000000"/>
  <property name="defaultEncoding" value="UTF-8" />
 </bean>

存放在静态资源区

1、存放位置:

存放在项目中,所以路径为相对项目的路径。

/{yourproject}/webapp/static/img

2、配置响应的handler

@Controller
public class UploadController {
 @GetMapping("/upload")
 public String UploadHandler() {
 return "upload";
 }

 @PostMapping("/upload/static")
 public void wriToStatic(HttpServletRequest request,
       RedirectAttributes redirectAttributes,
       @RequestParam("fileName") MultipartFile file) {
 if(!file.isEmpty()) {
  //获取目标文件夹
  String path = request.getServletContext().getRealPath("/") + "static/img/";
  //获取用户上传的源文件名
  String fileName = file.getOriginalFileName();
  //新建文件
  File file1 = new File(path, fileName);
  //将文件写入
  file.transferTo(file1);

  redirectAttributes.addFlashAttribute("message","upload to static success");
  return "redirect:/upload";
 } else {
  redirectAttributes.addFlashAttribute("message","upload file can not be empty");
  return "redirect:/upload";
 }

 }
}

存放在服务器

1、本例存放位置:

存放在服务器某个位置,与项目无关,所以地址为绝对路径。

/Users/mac/Desktop/imgtemp/, 为目录的绝对路径。

2、配置响应的handler

...
@PostMapping("/upload/disk")
public String writeToDisk(HttpServletRequest request,
       @RequestParam("fileName") MultipartFile file,
       RedirectAttributes redirectAttributes) {
 if(!file.isEmpty()) {
 //获取源文件名
 String fileName = file.getOriginalFileName();
 //获取保存文件文件夹路径
 String path = "/Users/mac/Desktop/imgtemp/";
 //新建文件
 File file1 = new File(path,fileName);
 //写入文件
 file.transferTo(file1);
 }

}
...

延伸部分(文件的查看及下载)

由于响应是要以流的形式传递文件,我们需要正确的设置响应的MIMIE类型才能被浏览器正确的解析,应用程序文件的默认MIMIE类型为 application/octet-stream,MIME设置为该值后,浏览器不会自动执行或询问执行这类文件,会以对待附件的形式直接将文件下载至本地。

更多关于MIMIE的解读请查看这篇文章

如果我们如果想自定义下载文件的名字,那么就需要设置Content-Disposition消息。
Content-Disposition 消息头指示回复的内容该以何种形式展示,是以内联的形式(即网页或者页面的一部分),还是以附件的形式下载并保存到本地。

更过关于Content-Disposition的解读请查看这篇文章

...
@GetMapping("/download/byDefault")
public void getImgByDefault(@RequestParam String fileName,
       @RequestParam(required=false,defaultValue="") String saveName),
       HttpServletResponse response {
 if(StringUtils.isEmpty(fileName)) {
  response.sendError(404);
  return;
 }
 //文件存放的路径
 String path = "/Users/mac/Desktop/imgtemp/";
 //新建文件
 File file = new File(path,fileName);

 if(!file.exists()) {
  response.sendError(404);
  return;
 }
 //如果请求参数saveName不为空,进行文件的下载
 if(!StringUtils.isEmpty(saveName)) {
  //设置响应长度
  response.setContentLength((int)file.length());
  //设置响应的MIME类型为application/octet-stream
  response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

  saveName = new String(saveName.getBytes("UTF-8"),"ISO8859-1");
  //设置content-disposition为attachment;fileName=saveName
  response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""+saveName+"\"");
 }
 //读取文件
 InputStream is = new FileInputStream(file);
 OutputStream os = response.getOutputStream();
 //将文件以流的形式输出
 IOUtils.copy(is,os);
 os.flush();
 os.close();
 is.close();

}

我们还可以使用SpringMVC自带的 ByteArrayHttpMessageConverter 转化器来将文件输出,该转换器实现 HttpMessageConverter 接口。可读取所有MIME的请求信息,响应信息的MIME为 application/octet-stream

...
@GetMapping("/download/byConvert")
public HttpEntity<byte[]> getImgByConvert(@RequestParam String fileName,
           @RequestParam(required=false,defaultValue="") String saveName) {
 if(StringUtils.isEmpty(fileName)) {
  return new ResponseEntity<>(HttpStatus.NOT_FOUND);
 }

 String path = "/Users/mac/Desktop/imgtemp/";
 File file = new File(path,fileName);

 if(!file.exists()) {
  return new ResponseEntity<>(HttpStatus.NOT_FOUND);
 }

 HttpHeaders headers = new HttpHeaders();
 if(!StringUtils.isEmpty(saveName)) {
  headers.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
  headers.setContentLength(file.length());

  saveName = new Sting(saveName.getBytes("UTF-8"),"ISO8859-1");
  headers.add(HttpHeaders.CONTENT_DISPOSITION,"attachment;fileName=\"" + saveName + "\"");
 } else {
  headers.setContentType(MediaType.IMAGE_PNG);
 }

 return new HttpEntity<>(FileCopyUtils.copyToByteArray(file),headers);

}

upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html>
<head>
 <meta charset="UTF-8">
 <meta name="viewport"
   content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>Document</title>
 <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.css" rel="external nofollow" >
</head>
<body>
<div class="container">
 <h1 class="text-center">上传文件撒</h1>
 <c:if test="${not empty message}">
  <h2>${message}</h2>
 </c:if>


 <form:form enctype="multipart/form-data" action="/upload/static">
  <p class="text-info">上传至/web/static</p>
  <label for="">上传文件:</label>
  <input type="file" name="uploadFile">

  <button class="btn btn-default">提交</button>
 </form:form>



 <form:form enctype="multipart/form-data" action="/upload/disk">
  <p class="text-info">上传至Disk</p>
  <label for="">上传文件</label>
  <input type="file" name="uploadFile">

  <button class="btn btn-default">提交</button>
 </form:form>

 <div class="container">
  <button class="btn btn-default">
   <a href="/download/byDefault?fileName=dubbo.png" rel="external nofollow" target="_blank">使用默认方式查看上传至Disk的dubbo图片</a>
  </button>
  <button class="btn btn-default">
   <a href="/download/byDefault?fileName=dubbo.png&saveName=dubb.png" rel="external nofollow" >使用默认方式下载dubbo图片</a>
  </button>
 </div>

 <div class="container">
  <button class="btn btn-default">
   <a href="/download/byConvert?fileName=dubbo.png" rel="external nofollow" target="_blank">使用MVC转化器查看上传至Disk的dubbo图片</a>
  </button>
  <button class="btn btn-default">
   <a href="/download/byConvert?fileName=dubbo.png&saveName=dub.png" rel="external nofollow" >使用MVC转化器下载上传至Disk的dubbo图片</a>
  </button>

 </div>
</div>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • java 使用线程做的一个简单的ATM存取款实例代码

    java 使用线程做的一个简单的ATM存取款实例代码

    线程 Thread 类,和 Runable 接口 比较两者的特点和应用领域.可以,直接继承线程Thread类。该方法编写简单,可以直接操作线程,适用于单重继承情况,因而不能在继承其他类,下面我们来看一个实例
    2013-08-08
  • Guava自动加载缓存LoadingCache使用实战详解

    Guava自动加载缓存LoadingCache使用实战详解

    这篇文章主要为大家介绍了Guava自动加载缓存LoadingCache使用实战详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • springboot+vue项目从第一行代码到上线部署全流程

    springboot+vue项目从第一行代码到上线部署全流程

    本文详细介绍了如何从零开始搭建一个基于Spring Boot和Vue.js的前后端分离项目,并涵盖项目需求分析、技术选型、项目结构设计、前后端交互、部署上线等全过程,感兴趣的朋友跟随小编一起看看吧
    2024-11-11
  • Java ==,equals()与hashcode()的使用

    Java ==,equals()与hashcode()的使用

    本文主要介绍了Java ==,equals()与hashcode()的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-05-05
  • IDEA 如何控制编辑左侧的功能图标ICON(操作步骤)

    IDEA 如何控制编辑左侧的功能图标ICON(操作步骤)

    很多朋友被idea左侧的图标不见了这一问题搞的焦头烂额,不知道该怎么操作,今天小编就交大家如何控制编辑左侧的功能图标 ICON,文字内容不多,主要通过两张截图给大家说明,感兴趣的朋友一起看看吧
    2021-05-05
  • SpringBoot 钩子接口的实现代码

    SpringBoot 钩子接口的实现代码

    本文主要介绍了SpringBoot 钩子接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • Java中注解@Async实现异步及导致失效原因分析

    Java中注解@Async实现异步及导致失效原因分析

    Async注解用于声明一个方法是异步的,当在方法上加上这个注解时将会在一个新的线程中执行该方法,而不会阻塞原始线程,这篇文章主要给大家介绍了关于Java中注解@Async实现异步及导致失效原因分析的相关资料,需要的朋友可以参考下
    2024-07-07
  • 利用Jackson实现数据脱敏的示例详解

    利用Jackson实现数据脱敏的示例详解

    在我们的企业项目中,为了保护用户隐私,数据脱敏成了必不可少的操作,那么我们怎么优雅的利用Jackson实现数据脱敏呢,本文就来和大家详细聊聊,希望对大家有所帮助
    2023-05-05
  • SpringBoot使用JavaMailSender实现发送邮件

    SpringBoot使用JavaMailSender实现发送邮件

    JavaMailSender是Spring Framework中的一个接口,用于发送电子邮件,本文主要为大家详细介绍了SpringBoot如何使用JavaMailSender实现发送邮件,需要的可以参考下
    2023-12-12
  • Java使用Condition控制线程通信的方法实例详解

    Java使用Condition控制线程通信的方法实例详解

    这篇文章主要介绍了Java使用Condition控制线程通信的方法,结合实例形式分析了使用Condition类同步检测控制线程通信的相关操作技巧,需要的朋友可以参考下
    2019-09-09

最新评论