SpringMVC —— 9、文件上传和下载

目录

1、文件下载

 2、文件上传

3、文件上传的文件名重复问题


这次的笔记使用的模块是 SpringMVC-demo4

1、文件下载

使用 ResponseEntity 实现文件下载的功能

① 在 src/main/webapp/static/img 下放一张图片,名字就叫 a.jpg 吧

② 由于往项目中添加了静态资源,需要重新在 Maven 中重新打包,服务器才会有相关资源

③ 在 src/main/webapp/WEB-INF/templates 下新建 file.html,用作存放下载和上传链接的页面

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>测试文件上传和下载</title>
</head>
<body>
    <a th:href="@{/testDown}">下载a.jpg</a>
</body>
</html>

④ 为了能够跳转到 file.html 页面,在 springMVC.xml 中添加视图控制器

<mvc:view-controller path="/file" view-name="file"></mvc:view-controller>

⑤ 创建 FileUpAndDownController 控制器类,用来存放上传和下载所需的控制器方法,并添加下载所需的方法

@Controller
public class FileUpAndDownController {

    @RequestMapping("/testDown")
    public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
        //获取ServletContext对象
        ServletContext servletContext = session.getServletContext();
        //获取服务器中文件的真实路径,这里的真实路径是target文件夹下的路径
        String realPath = servletContext.getRealPath("/static/img/a.jpg");
        System.out.println(realPath); //这里输出真实路径用作测试
        //创建输入流
        InputStream is = new FileInputStream(realPath);
        //创建字节数组
        //is.available()返回对应输入流的所有字节数
        byte[] bytes = new byte[is.available()];
        //将流读到字节数组中
        is.read(bytes);
        //创建HttpHeaders对象设置响应头信息
        MultiValueMap<String, String> headers = new HttpHeaders();
        //设置要下载方式以及下载文件的名字,这里只有文件名filename的值可以根据需要更改,其他不用更改,attachment表示以附件的方式下载
        headers.add("Content-Disposition", "attachment;filename=a.jpg");
        //设置响应状态码,就是 200
        HttpStatus statusCode = HttpStatus.OK;
        //创建ResponseEntity对象
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
        //关闭输入流
        is.close();
        return responseEntity;
    }

}

⑥ 运行测试,打开 http://localhost:8080/SpringMVC_demo4/file 页面,点击测试链接进行测试,可以看到浏览器直接新建了一个下载任务,下载后就可以在对应目录找到资源

 2、文件上传

文件上传要求 form 表单的请求方式必须为 post并且添加属性enctype="multipart/form-data"

SpringMVC中将上传的文件封装到 MultipartFile 对象中,通过此对象可以获取文件相关信息

① 首先在 file.html 页面添加测试的表单

    <!-- 文件上传 -->
    <!--
        enctype属性规定在发送到服务器之前应该如何对表单数据进行编码的
        默认值是application/x-www-form-urlencoded,就是说,在发送到服务器之前,所有字符都会进行编码(空格转换为 "+" 加号,特殊符号转换为 ASCII HEX 值)。
        multipart/form-data:不对字符编码(也就是二进制)。在使用包含文件上传控件的表单时,必须使用该值。
    -->
    <form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
        头像:<input type="file" name="photo"><br>
        <input type="submit" value="上传">
    </form>

② 在 pom.xml 添加依赖

        <!-- 文件上传的依赖 https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>

③ 在 springMVC.xml 配置文件中添加配置

    <!-- 配置文件上传解析器,将上传的文件封装为MultipartFile -->
    <!-- id必须为multipartResolver -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

④ 在 FileUpAndDownController 类中添加方法

    //文件上传
    @RequestMapping("/testUp")
    public String testUp(MultipartFile photo){
        System.out.println("getName = " + photo.getName());
        System.out.println("getOriginalFilename = " + photo.getOriginalFilename());
        return "success";
    }

⑤ 运行测试,发现页面成功跳转,查看控制台的输出

 从而得知 getName() 是获取 MultipartFile 类型的属性名,getOriginalFilename() 是获取上传的文件的文件名

⑥ 修改文件上传的控制器方法

    //文件上传
    @RequestMapping("/testUp")
    public String testUp(MultipartFile photo, HttpSession session) throws IOException {
        //System.out.println("getName = " + photo.getName()); //getName = photo
        //System.out.println("getOriginalFilename = " + photo.getOriginalFilename()); //getOriginalFilename = a.jpg

        // 获取文件名
        String fileName = photo.getOriginalFilename();
        // 获取文件存放路径
        ServletContext servletContext = session.getServletContext();
        String photoPath = servletContext.getRealPath("photo");
        File file = new File(photoPath);
        // 判断photoPath对应路径是否存在
        if(!file.exists()){
            // 若不存在,则创建目录
            file.mkdir();
        }
        // 将photoPath对应路径加上分隔符加上文件名形参最终路径。File.separator就是分隔符
        String finalPath = photoPath + File.separator + fileName;
        // 传输文件到指定路径下
        photo.transferTo(new File(finalPath));
        return "success";
    }

⑦ 运行测试,在 target 目录下会生成 photo 目录,存放上传的照片

3、文件上传的文件名重复问题

使用 UUID 为文件命名

    //文件上传
    @RequestMapping("/testUp")
    public String testUp(MultipartFile photo, HttpSession session) throws IOException {
        //System.out.println("getName = " + photo.getName()); //getName = photo
        //System.out.println("getOriginalFilename = " + photo.getOriginalFilename()); //getOriginalFilename = a.jpg

        // 获取上传的文件名
        String fileName = photo.getOriginalFilename();
        // 获取上传的文件的后缀名
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        // 将UUID作为文件名
        String uuid = UUID.randomUUID().toString();
        // 将uuid和后缀名拼接后的结果作为最终文件名
        fileName = uuid + suffixName;
        // 获取文件存放路径
        ServletContext servletContext = session.getServletContext();
        String photoPath = servletContext.getRealPath("photo");
        File file = new File(photoPath);
        // 判断photoPath对应路径是否存在
        if(!file.exists()){
            // 若不存在,则创建目录
            file.mkdir();
        }
        // 将photoPath对应路径加上分隔符加上文件名形参最终路径。File.separator就是分隔符
        String finalPath = photoPath + File.separator + fileName;
        // 传输文件到指定路径下
        photo.transferTo(new File(finalPath));
        return "success";
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值