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格式
相关推荐
向前看-6 小时前
验证码机制
前端·后端
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭7 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
超爱吃士力架8 小时前
邀请逻辑
java·linux·后端
AskHarries10 小时前
Spring Cloud OpenFeign快速入门demo
spring boot·后端
isolusion11 小时前
Springboot的创建方式
java·spring boot·后端
Yvemil711 小时前
《开启微服务之旅:Spring Boot Web开发举例》(一)
前端·spring boot·微服务
zjw_rp11 小时前
Spring-AOP
java·后端·spring·spring-aop
TodoCoder11 小时前
【编程思想】CopyOnWrite是如何解决高并发场景中的读写瓶颈?
java·后端·面试
凌虚12 小时前
Kubernetes APF(API 优先级和公平调度)简介
后端·程序员·kubernetes
星河梦瑾12 小时前
SpringBoot相关漏洞学习资料
java·经验分享·spring boot·安全