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

SpringMVC框架学习笔记(七):处理 json 和 HttpMessageConverter 以及文件的下载和上传

处理 JSON-@ResponseBody

说明: 项目开发中,我们往往需要服务器返回的数据格式是按照 json 来返回的

 下面通过一个案例来演示SpringMVC 是如何处理的

(1) 在web/WEB-INF/lib 目录下引入处理 json 需要的 jar 包,注意 spring5.x 需要使用 jackson-2.9.x.jar 的包(所需jar包以附在文章顶部)

(2) 创建json.jsp,在前端发送一个ajax请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>json提交</title><!-- 引入jquery --><script type="text/javascript" src="script/jquery-3.6.0.min.js"></script><!-- 编写jquery代码和ajax请求 --><script type="text/javascript">$(function () {//给id="getJson"绑定点击事件$("#getJson").click(function () {//console.log("ok ....")var url = this.href;var args = {"time": new Date};//这是要发送数据,为了防止页面缓存$.post(url,args,function (data) {//data 就是返回的数据,是json格式=>如果是多个json数据,可以遍历console.log("dataa= ", data);console.log("dog.name=", data.name)console.log("dog.addresss=", data.address)},"json");return false;//这里我们返回false,就不使用href默认机制,即不会跳转}) })</script></head>
<body>
<h1>请求一个json数据</h1>
<%--
1.当用户点击超链接时,我们发出一个ajax请求
2. 接收到请求后,我们查看这个数据
--%>
<a href="<%=request.getContextPath()%>/json/dog" id="getJson">点击获取json数据</a></body>
</html>

 (3)创建JavaBean类 Dog.java

package com.web.json.entity;public class Dog {private String name;private String address;public Dog(String name, String address) {this.name = name;this.address = address;}public Dog() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "Dog{" +"name='" + name + '\'' +", address='" + address + '\'' +'}';}
}

(4)创建 JsonHandler.java 

package com.web.json;import com.web.json.entity.Dog;
import com.web.json.entity.User;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;@Controller
public class JsonHandler {/*** 1. 目标方法 @ResponseBody,表示返回的数据是json格式* 2. springmvc底层根据目标方法上的注解@ResponseBody, 返回指定格式, 根据的http请求来进行处理* 3. 这里springmvc底层使用的是转换器HttpMessageConverter*/@RequestMapping(value = "/json/dog")@ResponseBodypublic Dog getJson() {//返回对象//springmvc会根据你的设置,转成json格式数据返回Dog dog = new Dog();dog.setName("大黄狗");dog.setAddress("小新的家");return dog;}
}

 (5)测试

也可以通过列表返回多个 Json 数据,在 JsonHandler.java 类中添加如下方法

//编写方法,以json格式返回多个Dog
@RequestMapping(value = "/json/dogs")
@ResponseBody
public List<Dog> getJsons() {List<Dog> dogs = new ArrayList<>();dogs.add(new Dog("大黄狗", "小新的家"));dogs.add(new Dog("大黄狗2", "小新2的家"));dogs.add(new Dog("大黄狗3", "小新3的家"));return dogs;
}

 使用postman测试:

 2 处理 JSON-@RequestBody

说明:客户端发送 json 字符串数据给后端, 这时候可以使用 SpringMVC 的 @RequestBody 将客户端提交的 json 数据,封装成 JavaBean 对象

使用案例:

(1)创建javabean类 User.java

package com.web.json.entity;public class User {private String userName;private Integer age;public User(String userName, Integer age) {this.userName = userName;this.age = age;}public User() {}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "User{" +"userName='" + userName + '\'' +", age=" + age +'}';}
}

 (2)在 JsonHandler.java 类中添加如下方法

/*** 1. @RequestBody User user 在形参指定了 @RequestBody* 2. springmvc就会将提交的json字符串数据填充给指定Javabean*/
@RequestMapping(value = "/save2")
@ResponseBody
public User save2(@RequestBody User user) {//将前台传过来的数据 以json的格式返回浏览器System.out.println("user~= " + user);return user;
}

 (3)创建jsp页面发送请求,发送json数据

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>json提交</title><!-- 引入jquery --><script type="text/javascript" src="script/jquery-3.6.0.min.js"></script><!-- 编写jquery代码和ajax请求 --><script type="text/javascript">$(function () {//绑定按钮点击事件, 提交json数据//springmvc 可以在在台将json数据转成对象$("button[name='butt1']").click(function () {//目标:将userName 和 age 封装成json字符串,发送给目标方法var url = "/springmvc/save2";var userName = $("#userName").val();var age = $("#age").val();//将json对象转成json格式字符串var args = JSON.stringify({"userName": userName, "age": age});$.ajax({url: url,data: args,type: "POST",success: function (data) {console.log("返回的data= ", data);},//下面这个contentType参数,是指定发送数据的编码和格式contentType: "application/json;charset=utf-8"})})})</script></head>
<body>
<h1>发出一个json数据</h1>
u:<input id="userName" type="text"><br/>
a:<input id="age" type="text"><br/>
<button name="butt1">添加用户</button></body>
</html>

(4)测试效果

处理 JSON-注意事项和细节

(1)@ResponseBody 可以直接写在 controller 上 即hanler类上,这样对所有方法生效 ,相当于所有方法都添加了这个注解

(2)@ResponseBody + @Controller 可以直接写成 @RestController。这里看一下@RestController注解的源码就知道了,源码如下

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {@AliasFor(annotation = Controller.class)String value() default "";
}

HttpMessageConverter<T>

基本说明:SpringMVC 处理 JSON 底层实现是依靠 HttpMessageConverter<T>来进行转换的 

工作机制简图

 

处理 JSON-底层实现(HttpMessageConverter<T>)
(1)使用 HttpMessageConverter<T> 将请求信息转化并绑定到处理方法的入参中 , 或将响应结果转为对应类型的响应信息,Spring 提供了两种途径:
  • 使用 @RequestBody / @ResponseBody 对目标方法进行标注
  • 使用 HttpEntity<T> / ResponseEntity<T> 作为目标方法的入参或返回值
(2) 当 控 制 器 处 理 方 法 使 用 到 @RequestBody/@ResponseBody 或 HttpEntity<T>/ResponseEntity<T> 时 , Spring 首先根据请求头或响应头的 Accept 属性选择

匹配 的 HttpMessageConverter, 进而根据参数类型或泛型类型的过滤得到匹配的 HttpMessageConverter, 若找不到可用的 HttpMessageConverter 将报错

文件下载-ResponseEntity<T> 

说明: SpringMVC 中,通过返回 ResponseEntity<T>的类型,可以实现文件下载的功能

应用案例: 

 (1)编写前端页面发送请求

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>json提交</title>
</head>
<body>
<h1>下载文件的测试 </h1>
<a href="<%=request.getContextPath()%>/downFile">点击下载文件</a>
</body>
</html>

 (2)把图片复制到web/img目录下

 (3)在 JsonHandler.java 类中添加如下方法

//响应用户下载文件的请求
@RequestMapping(value = "/downFile")
public ResponseEntity<byte[]> downFile(HttpSession session)throws Exception {//1. 先获取到下载文件的inputStreamInputStream resourceAsStream =session.getServletContext().getResourceAsStream("/img/2.png");//2. 开辟一个存放文件的byte数组, 这里使用byte[] 是为了可以支持二进制数据(图片,视频。)byte[] bytes = new byte[resourceAsStream.available()];//3. 将下载文件的数据,读入到byte[]resourceAsStream.read(bytes);// ResponseEntity构造器//public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status) {}//4. 创建返回的HttpStatusHttpStatus httpStatus = HttpStatus.OK;//5. 创建 headersHttpHeaders headers = new HttpHeaders();//指定返回的数据,客户端应当以附件形式处理headers.add("Content-Disposition", "attchment;filename=2.png");//构建一个ResponseEntity 对象 1. http响应头headers 2. http响应状态 3. 下载的文件数据ResponseEntity<byte[]> responseEntity =new ResponseEntity<>(bytes, headers, httpStatus);//如果出现找不到文件,解决方法 rebuild project -> 重启tomcatreturn responseEntity;
}

文件下载响应头的设置 :

content-type 指示响应内容的格式

content-disposition 指示如何处理响应内容。

content-disposition一般有两种方式:

inline:直接在页面显示

attchment:以附件形式下载 

(4)启动服务器,测试效果如下

 

6 文件上传

6.1 基本介绍

(1)Spring MVC 为 文 件 上 传 提 供 了 直 接 的 支 持 , 这 种 支 持 是 通 过 即 插 即 用 的 MultipartResolver 实 现 的 。 Spring 用 Jakarta Commons FileUpload 技 术 实 现 了 一 个 MultipartResolver 实现类:CommonsMultipartResovler

(2)Spring MVC 上下文中默认没有装配 MultipartResovler,因此默认情况下不能处理文件的 上传工作,如果想使用 Spring 的文件上传功能,需要在上下文中配置 MultipartResolver

<!--配置文件上传需要的bean-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver"id="multipartResolver"/>

6.2 应用实例

(1)引入 springmvc 文件上传需要的 jar 包(已附在文章顶部)


 

(2)创建前端页面 fileUpload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>文件上传</title>
</head>
<body>
<h1>文件上传的演示</h1>
<%--
1.enctype编码类型,默认是application/x-www-irlencoded 即url编码 这种编码不适用二进制文件数据的提交
一般适用于文本
2.如果要进行二进制文件的提交 enctype 要指定 multipart/form-data 表示提交的数据是由多个部分组成,
也就是可以提交二进制数据和文本数据
--%>
<form action="<%=request.getContextPath()%>/fileUpload" method="post" enctype="multipart/form-data">文件介绍:<input type="text" name="introduce"><br>选择文件:<input type="file" name="file"><br><input type="submit" value="上传文件">
</form>
</body>
</html>

 (3) 在spring配置文件xml文件中配置文件上传解析器

<!--配置文件上传需要的bean-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver"id="multipartResolver"/>

 (4)创建 FileUploadHandler.java 类

package com.web.fileupload;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;@Controller
public class FileUploadHandler {//编写方法,处理文件上传的请求@RequestMapping(value = "/fileUpload")public String fileUpload(@RequestParam(value = "file") MultipartFile file,HttpServletRequest request, String introduce) throws IOException {//接收到提交的文件名String originalFilename = file.getOriginalFilename();System.out.println("你上传的文件名= " + originalFilename);System.out.println("introduce=" + introduce);//得到要把上传文件保存到哪个路径[全路径:包括文件名]String fileFullPath =request.getServletContext().getRealPath("/img/" + originalFilename);//创建文件File saveToFile = new File(fileFullPath);//将上传的文件,转存到saveToFilefile.transferTo(saveToFile);return "success";}
}

 (5)启动服务器,测试效果

文件上传成功! 

相关文章:

SpringMVC框架学习笔记(七):处理 json 和 HttpMessageConverter 以及文件的下载和上传

1 处理 JSON-ResponseBody 说明: 项目开发中&#xff0c;我们往往需要服务器返回的数据格式是按照 json 来返回的 下面通过一个案例来演示SpringMVC 是如何处理的 &#xff08;1&#xff09; 在web/WEB-INF/lib 目录下引入处理 json 需要的 jar 包&#xff0c;注意 spring5.x…...

八、BGP

目录 一、为何需要BGP&#xff1f; 二、BGP 2.1、BGP邻居 2.2、BGP报文 2.3、BGP路由 2.4、BGP通告遵循原则 2.5、BGP实验 第一步&#xff1a;建立邻居 第二步&#xff1a;引入路由 BGP路由黑洞 路由黑洞解决方案 1、IBGP全互联 2、路由引入 3、MPLS 多协…...

有监督学习——支持向量机、朴素贝叶斯分类

1. 支持向量机 支持向量机&#xff08;Support Vector Machine, SVM&#xff09;最初被用来解决线性问题&#xff0c;加入核函数后能够解决非线性问题。主要优点是能适应小样本数量 高维度特征的数据集&#xff0c;甚至是特征维度数高于训练样本数的情况。 先介绍几个概念&am…...

自动化测试文档

自动化测试文档的类型 自动化测试方案&#xff1a; 目的&#xff1a;描述自动化测试的目标、范围、方法、资源等。内容&#xff1a;通常包含测试计划、测试用例设计、测试环境配置、测试执行策略、预期结果、风险评估等。自动化测试脚本&#xff1a; 目的&#xff1a;用于执行…...

vue-i18n使用步骤详解(含完整操作步骤)

开篇 下面是从创建vue项目开始&#xff0c;完整使用i18n实现国际化功能的步骤&#xff0c;希望对您有所帮助。 完整步骤 创建项目 创建项目&#xff0c;并在创建项目的时候选择vuex,router 选择3.x版本 后面随意选即可&#xff0c;下面是完整的代码结构 安装vue-i18n,并封装…...

XXE漏洞修补:保护您的系统免受XML外部实体攻击

引言 XML外部实体&#xff08;XXE&#xff09;漏洞是一种常见的网络安全问题&#xff0c;它允许攻击者通过XML文档中的实体引用读取服务器上的文件或发起远程服务器请求。这种漏洞可能被用于数据泄露、拒绝服务攻击&#xff08;DoS&#xff09;甚至远程代码执行。本文将探讨XX…...

去除upload的抖动效果

title: 去除upload的抖动效果 date: 2024-06-15 20:16:51 tags: vue3 在使用vue3element-plus框架的时候&#xff0c;常常会使用到el-upload方法。其中如果做了翻页效果可以发现图片过度方式是集中到左上角进行的翻页&#xff0c;这种效果不是很好&#xff0c;我们还是想让这中…...

什么是 Linux ?(Linux)

系列文章目录 第一章 什么是Linux&#xff1f; 文章目录 系列文章目录一、什么是 Linux &#xff1f;二、Linux 的发行版本总结 一、什么是 Linux &#xff1f; Linux&#xff08;Linux Is Not UniX&#xff09;&#xff0c;是一种免费使用和自由传播的类UNIX操作系统&#x…...

uni-app 怎么在tabbar使用阿里图标库

提示&#xff1a;微信小图标不支持使用字体图标的方式&#xff0c;只能下载png 方法一&#xff1a;直接下载png图片 我们首选打开阿里矢量图标库 链接在下方 &#x1f447; iconfont-阿里巴巴矢量图标库iconfont-国内功能很强大且图标内容很丰富的矢量图标库&#xff0c;提供矢…...

勒索病毒剖析

2016年不自己勒索了 卖病毒 让别人勒索 傻瓜式勒索 黑客用的是非对称加密 全世界只有黑客有那把私钥 反向解密不了 传统爆破容易被检测&#xff0c;黑客慢速爆破&#xff0c;利用超级多的僵尸进行试错&#xff0c;慢慢试出来账号密码 因为一般运维设备在防火墙的白名单里&…...

【C++11】第一部分(一万六千多字)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 C11简介 统一的列表初始化 &#xff5b;&#xff5d;初始化 std::initializer_list 声明 auto decltype 右值引用和移动语义 左值引用和右值引用 左值引…...

FPGA专项课程即将开课,颁发AMD官方证书

社区成立以来&#xff0c;一直致力于为广大工程师提供优质的技术培训和资源&#xff0c;得到了众多用户的喜爱与支持。为了满足用户需求&#xff0c;我们特别推出了“基于Vitis HLS的高层次综合及图像处理开发”课程。 本次课程旨在帮助企业工程师掌握前沿的FPGA技术&#xff…...

C++ shared_ptr

shared_ptr共享它指向的对象&#xff0c;多个shared_ptr可以指向&#xff08;关联&#xff09;相同的对象&#xff0c;在内部采用计数机制来实现。 当新的shared_ptr与对象关联时&#xff0c;引用计数增加1。 当shared_ptr超出作用域时&#xff0c;引用计数减1。当引用计数变为…...

2024.6.15

2024.6.15 【夜幽幽&#xff0c;月优优&#xff0c;曲悠悠&#xff0c;吾忧忧。】 Saturday 五月初十 <theme oi-“DP”> 看几道DP基础题&#xff0c; 巩固一下DP思路和基础 Coin Combinations I //2024.6.15 //by white_ice //Coin Combinations I CSES - 1635 #i…...

堆栈溢出的攻击 -fno-stack-protector stack smash 检测

在程序返回的一条语句堆栈项目处&#xff0c;用新函数的起始地址覆盖&#xff0c;将会跳转到执行新函数。 现在系统对这个行为做了判断&#xff0c;已经无法实施这类攻击或技巧。 1&#xff0c;测试代码 #include <stdio.h> void cc() {printf("I am cc( )\n"…...

掌握特劳特定位理论核心,明晰企业战略定位之重

在当今瞬息万变的市场环境中&#xff0c;企业战略定位的重要性日益凸显。它不仅是企业在激烈竞争中保持优势的关键&#xff0c;更是企业实现长期可持续发展的基石。 哈佛大学战略学教授迈克尔波特&#xff08;Michael Porter&#xff09;指出战略就是形成一套独具的运营活动&a…...

RAGFlow 学习笔记

RAGFlow 学习笔记 0. 引言1. RAGFlow 支持的文档格式2. 嵌入模型选择后不再允许改变3. 干预文件解析​4. RAGFlow 与其他 RAG 产品有何不同&#xff1f; ​5. RAGFlow 支持哪些语言&#xff1f; ​6. 哪些嵌入模型可以本地部署&#xff1f; ​7. 为什么RAGFlow解析文档的时间比…...

使用Docker-Java监听Docker容器的信息

使用Docker-Java监听Docker容器的信息 Docker作为一种轻量级的容器化平台&#xff0c;极大地方便了应用的部署与管理。然而&#xff0c;在实际使用过程中&#xff0c;我们常常需要对运行中的容器进行监控&#xff0c;以确保其健康状态&#xff0c;并能及时响应各种异常情况。本…...

Spring Boot + Mybatis Plus实现登录注册

Spring Boot 实现登录注册 1. 注册 业务逻辑 客户端输入注册时需要的用户参数&#xff0c;比如&#xff1a;账户名、密码、确认密码、其他服务端接收到客户端的请求参数进行校验&#xff0c;然后判断是否有误&#xff0c;有误的地方就将错误信息抛出将密码进行加密之后存储到…...

IDEA创建web项目

IDEA创建web项目 第一步&#xff1a;创建一个空项目 第二步&#xff1a;在刚刚创建的项目下创建一个子模块 第三步&#xff1a;在子模块中引入web 创建结果如下&#xff1a; 这里我们需要把这个目录移到main目录下&#xff0c;并改名为webapp&#xff0c;结果如下 将pom文件…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

dedecms 织梦自定义表单留言增加ajax验证码功能

增加ajax功能模块&#xff0c;用户不点击提交按钮&#xff0c;只要输入框失去焦点&#xff0c;就会提前提示验证码是否正确。 一&#xff0c;模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...