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
                                      Title
                                    编号:
                                    姓名:
                                    年龄:
                                    婚否:
                                    生日:
                                    坐骑:
                                    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
                                        @Bean
                                        public WebMvcConfigurer webMvcConfigurer() { //1.使用匿名内部类来实现WebMvcConfigurer接口的方法,并返回对象
                                            return new WebMvcConfigurer() { @Override
                                                //2.实现addFormatters方法
                                                public void addFormatters(FormatterRegistry registry) { //3.调用addConverter方法,然后使用匿名内部类实现Converter接口的方法,里面的泛型就是从什么类型转换到什么类型
                                                    registry.addConverter(new Converter() { @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.代码实现
                                      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的依赖
                                        com.fasterxml.jackson.dataformat jackson-dataformat-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.需求分析

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

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

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

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