SpringBoot(自定义转换器+处理Json+内容协商)

文章目录

    • 1.自定义转换器
        • 1.代码实例
          • 1.save.html
          • 2.编写两个bean
            • 1.Car.java
            • 2.Monster.java
          • 3.WebConfig.java 配置类来自定义转换器
          • 4.测试
        • 2.注意事项和细节
          • 1.debug查看转换器总数
            • 1.打断点
            • 2.执行到断点后,选左边的192
            • 3.可以看出,加上自定义的转换器一共125个
          • 2.一次新增多个转换器
          • 3.多个转换器的key重复的情况
    • 2.处理Json
        • 1.需求分析
        • 2.代码实现
        • 3.测试
    • 3.内容协商
        • 1.基本介绍
        • 2.应用实例
          • 首先在pom.xml引入可以处理xml的依赖
          • 1.需求分析
          • 2.使用postman测试,修改Accept为application/xml
          • 3.返回的结果是xml类型
          • 4.如果换成原来的任意类型
          • 5.返回的结果是json类型
        • 3.debug当Accept是xml时的源码
          • 1.ctrl + n 找到AbstractJackson2HttpMessageConverter
          • 2.下断点
          • 3.debug启动
          • 4.直接跳到关键部分
          • 5.再跳一下
        • 4.使用浏览器发送请求分析
        • 5.SpringBoot开启基于内容协商的功能
          • 1.需求分析
          • 2.开启基于内容协商的功能 application.yml
          • 3.具体使用
        • 6.内容协商总结
            • SpringBoot中如果只包含JSON相关的依赖(如Jackson),那么返回的数据默认是JSON格式

1.自定义转换器

1.代码实例
1.save.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="/save" method="post">编号: <input name="id" value="100"><br/>姓名: <input name="name" value="牛魔王"/> <br/>年龄: <input name="age" value="120"/> <br/>婚否: <input name="isMarried" value="true"/> <br/>生日: <input name="birth" value="2000/11/11"/> <br/><!--使用自定义转换器来关联acr,字符串整体提交,使用,间隔-->坐骑: <input name="car" value="大白熊,666.6"><br><input type="submit" value="保存"/>
</form>
</body>
</html>
2.编写两个bean
1.Car.java
package com.sun.springboot.bean;import lombok.Data;/*** @author 孙显圣* @version 1.0*/
@Data
public class Car {private String name;private Double price;
}
2.Monster.java
package com.sun.springboot.bean;import lombok.Data;import java.util.Date;/*** @author 孙显圣* @version 1.0*/
@Data
public class Monster {private Integer id;private String name;private Integer age;private Boolean isMarried;private Date birth;private Car car;
}
3.WebConfig.java 配置类来自定义转换器
package com.sun.springboot.config;import com.sun.springboot.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.util.ObjectUtils;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @author 孙显圣* @version 1.0*/
@Configuration(proxyBeanMethods = false) //启动Lite模式,则注入的bean对象必须通过该配置类的bean对象来获取才能生效,所有的bean都是多例
public class WebConfig {//注入多例bean WebMvcConfigurer@Beanpublic WebMvcConfigurer webMvcConfigurer() {//1.使用匿名内部类来实现WebMvcConfigurer接口的方法,并返回对象return new WebMvcConfigurer() {@Override//2.实现addFormatters方法public void addFormatters(FormatterRegistry registry) {//3.调用addConverter方法,然后使用匿名内部类实现Converter接口的方法,里面的泛型就是从什么类型转换到什么类型registry.addConverter(new Converter<String , Car>() {@Overridepublic Car convert(String s) { //这个s就是传进来的数据String类型的//4.这里加入自定义的业务转换代码//判断是否为空if (!ObjectUtils.isEmpty(s)) {//分割字符串String[] split = s.split(",");//创建一个Car,并赋值Car car = new Car();car.setName(split[0]);car.setPrice(Double.parseDouble(split[1]));return car;}//这里如果是空就返回一个nullreturn null;}});//5.在这里还可以继续registry.addConverter()添加转换器}};}
}
4.测试

image-20240314183519606

image-20240314183550123

2.注意事项和细节
1.debug查看转换器总数
1.打断点

image-20240314184302880

2.执行到断点后,选左边的192

image-20240314184449540

3.可以看出,加上自定义的转换器一共125个

image-20240314184709199

2.一次新增多个转换器

image-20240314184909592

3.多个转换器的key重复的情况
  • 由于存储转换器的类型为ConcurrentHashMap,key不可以重复
  • 所以一旦定义了多个key相同的转换器则只会保留最后定义的,其余的会被替换

2.处理Json

1.需求分析

image-20240314185604008

2.代码实现
package com.sun.springboot.controller;import com.sun.springboot.bean.Monster;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;import java.util.Date;/*** @author 孙显圣* @version 1.0*/
@Controller
public class JsonController {//返回json类型的Monster对象@GetMapping("/getMonster")@ResponseBody //将结果转换为json字符串并返回public Monster monsterToJson() {Monster monster = new Monster();monster.setAge(1);monster.setName("sun");monster.setId(1);monster.setCar(null);monster.setBirth(new Date());return monster;}
}
3.测试

image-20240314191020292

3.内容协商

1.基本介绍

image-20240314192453044

2.应用实例
首先在pom.xml引入可以处理xml的依赖
    <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId></dependency>
1.需求分析

image-20240314192811893

2.使用postman测试,修改Accept为application/xml

image-20240314194203290

3.返回的结果是xml类型

image-20240314194228780

4.如果换成原来的任意类型

image-20240314194257446

5.返回的结果是json类型

image-20240314194316016

3.debug当Accept是xml时的源码
1.ctrl + n 找到AbstractJackson2HttpMessageConverter

image-20240314195651832

2.下断点

image-20240314195715255

3.debug启动

image-20240314195914546

4.直接跳到关键部分

image-20240314200214243

5.再跳一下

image-20240314200335605

4.使用浏览器发送请求分析

image-20240314201934172

5.SpringBoot开启基于内容协商的功能
1.需求分析

由于浏览器的Accept不能像postman一样修改,所以,只能根据浏览器默认的权重来决定数据的返回类型

比如:由于浏览器的Accept中xml的权重很高,那就意味着如果后端引用了可以处理xml的依赖,那么后端

就只能给前端返回xml类型的数据,非常不灵活

2.开启基于内容协商的功能 application.yml
spring:mvc:contentnegotiation:favor-parameter: true
3.具体使用

image-20240314203336681

6.内容协商总结
  • 添加了**@ResponseBody**之后,该接口就可以与浏览器进行内容协商
  • 会根据浏览器的Accept的权重来决定优先返回什么类型的数据
  • 由于浏览器的Accept不够灵活,所以可以在SpringBoot中开启基于内容协商的功能,这样只需要在网址后面加上format参数即可决定要返回的类型
SpringBoot中如果只包含JSON相关的依赖(如Jackson),那么返回的数据默认是JSON格式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/538652.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式方向还有希望吗?

我刚开始学习&#xff0c;也不知道我定位的是单片机工程师&#xff0c;嵌入式工程师职位的。 我只知道电子工程师&#xff0c;这个职位其实偏硬件&#xff0c;很多岗位需求是硬件设计&#xff0c;PCB设计&#xff0c;还要懂焊接、各种仪器仪表使用&#xff0c;还有些需要懂单片…

1千多条中医中药知识及问答ACCESS\EXCEL数据库

今天从一个中医相关的产品中获得了一些数据&#xff0c;比如&#xff1a;《1千多条中医中药知识及问答》、《1千多条中医方剂知识问答》、《690条中医疾病疾病知识问答》&#xff0c;数据库表结构基本相同的。不理解请勿选择&#xff0c;谢谢。 数据包含5个表&#xff08;A一级…

鸿蒙开发实战:【电话服务子系统】

简介 电话服务子系统&#xff0c;提供了一系列的API用于获取无线蜂窝网络和SIM卡相关的一些信息。应用可以通过调用API来获取当前注册网络名称、网络服务状态、信号强度以及SIM卡的相关信息。 各个模块主要作用如下&#xff1a; 核心服务模块&#xff1a;主要功能是初始化RI…

IDEA启动项目到一半后卡住但不报错的解决方法分享

问题现象&#xff1a; 今天在启动项目的时候&#xff0c;微服务启动到后&#xff0c;控制台日志打印到一半之后&#xff0c;就不在打印了&#xff0c;卡住不动&#xff0c;无任何异常日志&#xff0c;项目也无法启动成功&#xff0c;如下&#xff1a; 原因分析&#xff1a; I…

ArcGIS学习(十五)用地适宜性评价

ArcGIS学习(十五)用地适宜性评价 本任务给大家带来的内容是用地适宜性评价。 用地适宜性评价是大家在平时工作中最常接触到的分析场景之一。尤其是在国土空间规划的大背景下,用地适宜性评价变得越来越重要。 此外,我们之前的任务主要是使用矢量数据进行分析。本案例是主讲…

跨域问题解决方案

在Web开发的时候会遇见一个常见的问题&#xff0c;跨域问题&#xff0c;这也是前后端分离的场景常见的问题&#xff0c;下面来看看这个东西是啥&#xff0c;如何应用的吧&#xff1f; 技术派中的跨域问题&#xff0c;有两处&#xff0c;一处是加载CDN图片时&#xff1b;一处是a…

为什localhost被forbidden而127.0.0.1不被绊?

原因&#xff1a; 判段网关的时候判127.0.0.1&#xff0c;所以最好改localhost 其他参考&#xff1a; 【计算机网络】localhost不能访问&#xff0c;127.0.0.1可以访问&#xff1f;_ping localhost和ping 127.0.0.1-CSDN博客

CesiumJS 沙盒

CesiumJS 沙盒 通过CesiumJS 沙盒快速测试CesiumJS的一些功能&#xff0c;免去安装开发环境的困恼。 Hello World https://sandcastle.cesium.com/index.html 简单修改&#xff08;F8运行&#xff09;&#xff1a;去掉界面上UI const viewer new Cesium.Viewer("cesi…

Baumer工业相机堡盟工业相机如何通过NEOAPISDK实现双快门采集两张曝光时间非常短的图像(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPISDK实现双快门采集两张曝光时间非常短的图像&#xff08;C&#xff09; Baumer工业相机Baumer工业相机定序器功能的技术背景Baumer工业相机通过NEOAPI SDK使用定序器功能预期的相机动作技术限制定序器的工作原理 Baumer工业相机通过NE…

谁将主导未来AI市场?Claude3、Gemini、Sora与GPT-4的技术比拼

【最新增加Claude3、Gemini、Sora、GPTs讲解及AI领域中的集中大模型的最新技术】 2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚…

软件设计师:06-程序设计语言与语言处理程序基础

章节章节01-计算机组成原理与体系结构07 - 法律法规与标准化与多媒体基础02 - 操作系统基本原理08 - 设计模式03 - 数据库系统09 - 软件工程04 - 计算机网络10 - 面向对象05 - 数据结构与算法11 - 结构化开发与UML06 - 程序设计语言与语言处理程序基础12 - 下午题历年真题End -…