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

news2025/1/19 14:11:29

目录

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.coloradmin.cn/o/469553.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++STL】map

文章目录 一. map的介绍二. map的使用结束语 一. map的介绍 map是关联容器&#xff0c;它按照特定的次序&#xff08;按照key来比较&#xff09;存储由键值key和值value组合而成的元素在map中&#xff0c;键值key通常用于排序和唯一地标识元素&#xff0c;而value中存储与此键值…

OSI七层模型、TCP/IP四层模型

OSI七层模型和TCP/IP四层模型 OSI七层模型 物理层&#xff1a;底层数据传输&#xff0c;如网线、网卡标准数据链路层&#xff1a;定义数据基本格式&#xff0c;如何传输如何标识&#xff1b;如网卡MAC地址网络层&#xff1a;定义IP地址&#xff0c;定义路由功能&#xff1b;如…

【中级软件设计师】—(针对上午题)二十三种设计模式(三十九)

【中级软件设计师】—&#xff08;针对上午题&#xff09;二十三种设计模式&#xff08;三十九&#xff09; 一、设计模式的分类 背背背 1 二、创建型设计模式&#xff08;5种&#xff09; 三、简单工厂模式 简单工厂模式代码实现如下&#xff1a; /*** author&#xff1a;Ca…

CentOS分区挂载 fdisk、parted方式解析

1 介绍 在linux中&#xff0c;通常会将持久化数据保存到硬盘当中&#xff0c;但是硬盘一把会比较大&#xff0c;因此我们为了方便管理&#xff0c;会将一个硬盘分成多个逻辑硬盘&#xff0c;称之为分区。 为了能够让分区中的文件使得能让操作系统处理&#xff0c;则需要对分区…

Java阶段二Day11

Java阶段二Day11 文章目录 Java阶段二Day11DQL主键与外键外键约束多对多关系内连接外连接自连接 JDBC核心接口JDBC连接的基本流程 教师总结主键与外键外键约束结论:关联关系中通常不适用外键约束。 多对多关系多对多关联查询例 练习题干答案 内连接语法例 外连接例 自连接定义场…

研报精选230427

目录 【行业230427东方金诚】有色金属行业信用风险回顾与2023年展望 【行业230427头豹研究院】2023年中国汽车安全气囊行业词条报告 【行业230427头豹研究院】2023年中国钠离子负极材料行业词条报告 【个股230427开源证券_佳禾食品】公司首次覆盖报告&#xff1a;植脂末龙头再启…

小匠物联出席宁波第五届家电产业数字化对接会助推家电产业数智化

宁波的家电资源与市场充足&#xff0c;特别是小家电&#xff0c;涉及20多个细分行业、近千个品种&#xff0c;其中10多个细分行业小家电产量一直位居全国或全球首列。但受原材料上涨等多重因素的影响&#xff0c;作为宁波市传统优势产业的家电产业也未能避免&#xff0c;产业数…

ldif 数据转成正确的组织结构再探

上次文章最后有说到按照之前的思路来转化组织结构是有坑的&#xff0c;我们现在还只是对接 AD域&#xff0c;ldap 协议的其他产品在细节上还会有些许不同 我们是不能直接粗暴的认为 cn 就是对应标识一个用户&#xff0c; cn 是 common name 的意思&#xff0c;他也可以表示我们…

【LeetCode】(力扣) c/c++刷题-145. 二叉树的后序遍历

题目&#xff1a; 给你一棵二叉树的根节点 root &#xff0c;返回其节点值的 后序遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[3,2,1] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&a…

线性表的链式存储结构与操作 题目编号:455

题目描述 评论 请你定义一个链表&#xff0c;可以对链表进行“在某个元素之前插入一些元素”、“删除某个位置的元素”、“查找某元素”、“获取某个位置的元素”、“遍历输出所有元素”、“求链表的长度”等操作。键盘输入一些命令&#xff0c;可以执行上述操作。本题中&…

电控针阀和手动可变泄漏阀组合在超高真空度精密PID控制中的应用

摘要&#xff1a;超高真空度的控制普遍采用具有极小开度的可变泄漏阀对进气流量进行微小调节。目前常用的手动可变泄漏阀无法进行超高真空度的自动控制且不准确&#xff0c;电控可变泄漏阀尽管可以实现自动控制但价格昂贵。为了实现自动控制且降低成本&#xff0c;本文提出了手…

线性表的顺序存储结构与操作 题目编号:454

题目描述 请你定义一个顺序表&#xff0c;可以对顺序表进行如下操作&#xff1a; 在某个元素之前插入一些元素 删除某个位置的元素 查找某元素 获取某个位置的元素 遍历输出所有元素 键盘输入一些命令&#xff0c;可以执行上述操作。本题中&#xff0c;顺序表元素为整数&…

【BIM+GIS】Supernap加载实景三维倾斜摄影模型

OSGB是常见的倾斜模型格式,本文讲述如何在Supernap中加载实景三维倾斜摄影模型OSGB。 文章目录 一、生成配置文件二、加载倾斜模型1. 新建场景2. 添加模型3. 高程调整一、生成配置文件 点击【三维数据】→【数据管理】→【生成配置文件】。 参数设置如下: 源路径:选择倾斜模…

荔枝派Zero(全志V3S)开启mplayer,播放音视频

文章目录 前言一、buildroot 配置及编译1、开启 ALSA 和 MPLAY2、编译 二、拷贝到到 SD 卡1、将 rootfs.tar 解压缩到 SD 卡 rootfs 分区②、将 mp4 文件和 mp3 文件拷贝到 SD 卡 rootfs 分区 三、测试1、mplayer 使用2、mplayer 播放音频3、mplayer 播放视频 前言 mplayer 是…

华为在软件工具生态埋下多颗“种子”,静候国产软件产业萌芽

文丨智能相对论 作者丨沈浪 当代的数字经济大厦由各种各样的软件一块一块地搭建起来。然而&#xff0c;站在国内软件行业的中心&#xff0c;热闹的大多是来自上层的软件应用&#xff0c;而沉寂的却总是底层又难又基础的领域&#xff0c;比如软件开发。 软件开发&#xff0c;…

初始新能源汽车

文章目录 电动汽车的三级模块体系VCU&#xff08;整车控制器&#xff09;MCU&#xff08;电机控制器&#xff09;电池包和BMS&#xff08;电池管理系统&#xff09;电动汽车的大三电电动汽车的小三电电动汽车的模块组成 电动汽车的三级模块体系 总体上讲&#xff0c;整个新能源…

牛客刷题篇:客似云来 和 剪花布条(Java)

目录 题目一&#xff1a;客似云来 输入描述 输出描述 解题思路 代码 题目二&#xff1a;剪花布条 输入描述 输出描述 解题思路 代码 题目一&#xff1a;客似云来 链接&#xff1a;客似云来 NowCoder开了一家早餐店&#xff0c;这家店的客人都有个奇怪的癖好&#xff…

算法刷题|1143.最长公共子序列、1035.不相交的线、53.最大子数组和

最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&a…

跨子网通信【路由通信。配置路由】

路由通信条件是&#xff1a;服务器多网卡 or 单网卡多IP 查看路由表 route -n设置一网卡多IP 进行网络配置 进入setup中&#xff0c;选择网络配置 setup选择设备配置 去除DHCP动态协议 进来后&#xff0c;可能会发现无法对静态IP和子网掩码进行编辑&#xff0c;是因为你开启…

Qt - 从零到壹的 打地鼠 游戏

❤️‍&#x1f525;欢迎收看西北风的blog&#xff0c;好男人就是我&#xff0c;我就是西北风。✨ 目录 &#x1f7e5;一&#xff1a;创建一个主窗体 &#x1f7e3;二.&#xff1a;添加主窗口背景图片以及相关部件 &#x1f538;2.1 添加资源文件 2.1.1 添加资源文件 2.1…