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

文章目录

1.自定义转换器

1.代码实例
1.save.html
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
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
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 配置类来自定义转换器
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
    @Bean
    public WebMvcConfigurer webMvcConfigurer() {
        //1.使用匿名内部类来实现WebMvcConfigurer接口的方法,并返回对象
        return new WebMvcConfigurer() {
            @Override
            //2.实现addFormatters方法
            public void addFormatters(FormatterRegistry registry) {
                //3.调用addConverter方法,然后使用匿名内部类实现Converter接口的方法,里面的泛型就是从什么类型转换到什么类型
                registry.addConverter(new Converter<String , Car>() {
                    @Override
                    public 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;
                        }
                        //这里如果是空就返回一个null
                        return null;
                    }
                });
                //5.在这里还可以继续registry.addConverter()添加转换器
            }
        };
    }
}
4.测试
2.注意事项和细节
1.debug查看转换器总数
1.打断点
2.执行到断点后,选左边的192
3.可以看出,加上自定义的转换器一共125个
2.一次新增多个转换器
3.多个转换器的key重复的情况
  • 由于存储转换器的类型为ConcurrentHashMap,key不可以重复
  • 所以一旦定义了多个key相同的转换器则只会保留最后定义的,其余的会被替换

2.处理Json

1.需求分析
2.代码实现
java 复制代码
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.测试

3.内容协商

1.基本介绍
2.应用实例
首先在pom.xml引入可以处理xml的依赖
xml 复制代码
    <dependency>
      <groupId>com.fasterxml.jackson.dataformat</groupId>
      <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>
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.需求分析

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

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

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

2.开启基于内容协商的功能 application.yml
yaml 复制代码
spring:
  mvc:
    contentnegotiation:
      favor-parameter: true
3.具体使用
6.内容协商总结
  • 添加了**@ResponseBody**之后,该接口就可以与浏览器进行内容协商
  • 会根据浏览器的Accept的权重来决定优先返回什么类型的数据
  • 由于浏览器的Accept不够灵活,所以可以在SpringBoot中开启基于内容协商的功能,这样只需要在网址后面加上format参数即可决定要返回的类型
SpringBoot中如果只包含JSON相关的依赖(如Jackson),那么返回的数据默认是JSON格式
相关推荐
右耳朵猫AI6 分钟前
Go周刊2026W22 | GoReleaser 2.16、chi 5.3、tldx 1.4、wazero 1.12、Buf 1.70
开发语言·后端·golang
摇滚侠13 分钟前
Spring 零基础入门到进阶 基于 XML 管理 Bean 29-37
xml·java·数据库·后端·spring·intellij-idea
我登哥MVP26 分钟前
Spring Boot 从“会用”到“精通”:内容协商原理
java·spring boot·后端·spring·java-ee·maven·lua
宸津-代码粉碎机35 分钟前
Spring AI企业级实战|Agent长期记忆持久化落地,彻底解决多轮对话上下文丢失问题
java·开发语言·人工智能·后端·python·spring
Flittly1 小时前
【AgentScope Java新手村系列】(1)框架简介与环境搭建
java·spring boot·笔记·spring·ai
星辰徐哥9 小时前
Spring Boot 微服务架构设计与实现
spring boot·后端·微服务
星辰徐哥9 小时前
Spring Boot 数据导入导出与报表生成
spring boot·后端·ui
明夜之约9 小时前
Spring Boot 自动装配源码
java·spring boot·后端
Leaton Lee9 小时前
Spring Boot分层架构详解:从Controller到Service再到Mapper的完整流程
java·spring boot·后端·架构
Micro麦可乐9 小时前
Spring Boot 实战:从零设计一个短链系统(含完整代码与数据库设计)
数据库·spring boot·后端·哈希算法·雪花算法·短链系统