当前位置: 首页 > article >正文

SpringMVC实现文件上传和下载和Json的简单实用

目录

SpringMVC实现文件上传和下载

1、文件下载

2、文件上传

(1)文件上传操作的分析

(2)实现步骤

  (3)解决文件重名覆盖问题

Json的简单使用

1、Json概述

2、Json的语法格式

3、Jackson的QuickStart


SpringMVC实现文件上传和下载

1、文件下载

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

步骤

  1. 控制器方法形参设置为session,用于获取session
  2. 通过session获取到servletContext,用于获取真实路径
  3. 创建输入流,流的源头是 要下载文件的真实路径, 流的去向是一个字节数组,可以指定字节数组的大小和流的字节数相等,省去循环的过程
  4. 创建responseEntity对象,请求体为填充好的字节数组,为其添加请求头和状态码
  5. 返回responseEntity对象即可。

响应头如何设置

先new一个HttpHeaders,它本质是一个map集合

下载时,需要为其指定headers.add("Content-Disposition", "attachment;filename=文件名"); 此处的文件名是你设置的默认名称,用户可以在下载时自行更改

不能修改,这是规定

响应状态码如何设置

HttpStatus statusCode = HttpStatus.OK;

完整示例

@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
    //获取ServletContext对象
    ServletContext servletContext = session.getServletContext();
    //获取服务器中,文件的真实路径
    String realPath = servletContext.getRealPath("/static/img/diamond.png");
    //创建输入流
    InputStream is = new FileInputStream(realPath);
    //创建字节数组,大小为输入流的所有字节总数
    byte[] bytes = new byte[is.available()];
    //将流读到字节数组中
    is.read(bytes);
    //创建HttpHeaders对象设置响应头信息
    MultiValueMap<String, String> headers = new HttpHeaders();
    //设置要下载方式以及下载文件的名字
    headers.add("Content-Disposition", "attachment;filename=diamond.png");
    //设置响应状态码
    HttpStatus statusCode = HttpStatus.OK;
    //创建ResponseEntity对象
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
    //关闭输入流
    is.close();
    return responseEntity;
}

2、文件上传

(1)文件上传操作的分析

1、前端页面,如何提供文件上传的入口?

form表单具备这样的功能。

在表单内容中,添加type为 file 的域:

头像:<input type="file" name="photo"/><br>

是这样的效果:

再给表单设置一个提交按钮,点击提交,文件的信息就能被上传到服务器。

可以看出,将文件的信息传递给服务器非常容易。那么文件上传的核心,其实是服务器对这段数据的处理。

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

多文件上传时,input中加一个multiple即可,否则上传时无法选中多个文件

2、为什么要添加属性enctype="multipart/form-data"

表单中,默认是通过键值对的形式传输到服务器。

进行这样的配置之后,会使用二进制的方式传输到服务器,才能接收到文件

3、服务器如何处理,浏览器提交的文件数据

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

4、服务器如何保存上传的文件

比如做一个头像上传的功能,就在服务器中创建一个photo目录,将每个上传的图片保存在其中。

需要考虑文件重名问题。

(2)实现步骤

1、添加依赖

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

2、配置SpringMVC的文件上传解析器

配置在SpringMVC核心配置中

<!--必须通过文件解析器的解析才能将文件转换为MultipartFile对象-->
<bean id="multipartResolver" 
      class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>

作用:将上传的文件封装成了一个MultipartFile对象

不需要手动访问,这个bean由SpringIOC容器自动访问,自动实现封装。

Spring如何知晓这个bean?

SpringMVC通过id获取这个文件上传解析器,所以id必须叫做multipartResolver

3、控制器方法

@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
    //获取上传的文件名称
    String fileName = photo.getOriginalFilename();

    /*
        获取服务器中photo目录的路径
         */
    //获取servletContext对象
    ServletContext servletContext = session.getServletContext();
    //获取文件保存目录的真实路径
    String photoPath = servletContext.getRealPath("photo");
    File file = new File(photoPath);
    //判断photoPath所对应路径是否存在
    if (!file.exists()){
        //如果目录不存在,则创建文件保存目录
        file.mkdir();
    }
    //拼接文件的最终存放路径
    String finalPath = photoPath + File.separator + fileName;

    /*
        保存文件
         */
    photo.transferTo(new File(finalPath));

    return "success";
}

(3)解决文件重名覆盖问题

文件重名覆盖问题的本质

如果不做处理,同名文件会发生覆盖的现象,原因是IO流默认不开启追加写入,将原有的文件中覆盖了新内容,所以本质并不是发生了文件覆盖,而是覆盖了文件中的内容

解决方法,在服务器写入数据时,保证文件名不重复

//获取上传的文件的文件名
String fileName = photo.getOriginalFilename();
//处理文件重名问题
String hzName = fileName.substring(fileName.lastIndexOf("."));
//处理后的文件名
fileName = UUID.randomUUID().toString() + hzName;

做法:保留了文件的后缀名,用一个随机的UUID作为文件名即可

Json的简单使用

1、Json概述

什么是json

JSON,全称是 JavaScript Object Notation,即 JavaScript对象标记法。

它是一种轻量级(Light-Meight)、基于文本的(Text-Based)、可读的(Human-Readable)格式。

名称中虽然带有JavaScript,但是指其语法规则是参考JavaScript对象的,而不是指只能用于JavaScript 语言。

json采用的是完全独立于编程语言的文本格式来存储和表示数据,因此可以被任何语言的交互阶段使用。而且因为非常流行,所以几乎所有编程语言都有用于解析JSON的库。

json的作用

是一种数据交换格式,用于前端页面与服务器后台的数据交互。

之前大规模使用的是XML,但它有两个问题:可读性差、文件较大。

而json的可读性好,文件更小,所以被广泛使用。

json可以用于传递对象和数组

为什么要使用json

业务中,经常遇到这种情况:服务器后台向前端页面发送了一些java对象,而前端需要解析这些对象,获取其中的属性并展示。

浏览器只能获取字符串,不能解析java对象。

所以就需要一种规范,能实现将java对象的属性写在字符串中,传递这个字符串,前端就能获取到字符串中包含的属性值,也就相当于是获取到了java对象的信息。

json就属于一种这个规范,可以用于将java对象转换成json字符串的形式

json实现前后端交互的流程

后端:java对象(或数组) 经过序列化 --> json字符串

前端:json字符串 经过解析 --> 获得java对象(或数组)的数据

2、Json的语法格式

格式

对象:键值对

数据:用逗号分隔,最后一个数据末尾不能加逗号

表示对象:{ }

表示数组:[ ]

3、Jackson的QuickStart

如何在Java中使用json

目前对于Java开源的JSON类库有很多种,常用的是Jackson。Spring MVC的默认json解析器便是Jackson

导入依赖

<!--Jackson包-->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.9.0</version>
</dependency>

创建实体类对象

public class User {
    private String username;
    private String password;
  	...
}

对象序列化成json

public static void main(String[] args) throws JsonProcessingException {
    User user = new User("admin", "123456");

    //使用ObjectMapper来序列化和反序列化
    ObjectMapper mapper = new ObjectMapper();

    //执行序列化
    String json = mapper.writeValueAsString(user);

    System.out.println("json = " + json);

}

输出:

json = {"username":"admin","password":"123456"}

json反序列化成java对象

public static void main(String[] args) throws JsonProcessingException {

    //使用ObjectMapper来序列化和反序列化
    ObjectMapper mapper = new ObjectMapper();

    //模拟获取到一个json
    String json = "{\"username\":\"admin\",\"password\":\"123456\"}";

    //执行反序列化
    User user = mapper.readValue(json, User.class);

    System.out.println("user = " + user);

}

输出:

user = User{username='admin', password='123456'}

 


http://www.kler.cn/a/15713.html

相关文章:

  • 环境贴图选用方式
  • FreeSWITCH chat 得到的是 Error! Message Not Sent
  • cmake生成器表达式
  • 谷歌AI进军教育,这将改变未来?
  • 解决部署RKE2或K3S-“docker.io/rancher/mirrored-pause:3.6\“: -无法拉取镜像办法
  • 用pandoc工具实现ipynb,md,word,pdf之间的转化
  • Promises对象
  • 西瓜书读书笔记整理(三)—— 第二章 模型评估与选择
  • 让你的ChatGPT更加强大——200+小白用来解锁ChatGPT高级功能的提示(Prompts)
  • C/C++的命名空间和调用函数的详细讲解
  • 【华为交换机配置命令大全】
  • 零售库存管理系统该如何选?这5款零售库存管理系统值得推荐!
  • 【C语言】#ifdef和#endif条件编译
  • pci总线协议学习笔记——PCI总线基本概念
  • 大数据好学么
  • Python学习10:计算三维空间某点距离原点的欧式距离(python123)
  • OSPF-MGRE综合实验
  • Microsoft Forms的應用(文行版)
  • 【VM服务管家】VM4.x算子SDK开发_3.3 模块工具类
  • 揭秘!我用AI写了一部精彩小说;搭建AI视频创作工作流;一键生成摘要工具清单;大模型创业生死5问 | ShowMeAI日报
  • 〔金融帝国实验室〕(Capitalism Lab)v9.0.00官方重大版本更新!
  • 如何保障网络安全
  • 【计算机网络】网络命令的使用
  • Mysql在大表中删除大量数据的优化
  • C++内存管理之拷贝memcpy、分配malloc 与释放free
  • 人工智能课程笔记(7)强化学习(基本概念 Q学习 深度强化学习 附有大量例题)