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

fastson与jackson重点笔记(包入门)

一,简介

json: JavaScript Object Notation, JS对象简谱。

官网:JSON官网

二,使用场景

  • 网络传输

​ 描述同样的信息,json相比xml占用更少的空间,

<?xml version="1.0" encoding="uTF-8"?>
<person>
	<id>1</id>
	<name>张三</name>
	<age>30</age>
</person>
{
    "id":1,
    "name":"张三",
    "age": 30
}

三,java里面操作json有哪些技术?

  • 所谓的操作

把java里面的bean, map, collection等转为json字符串(序列化)或反向操作(反序列化)。

  • Java里操作json的技术一览

image-20240919091223461

四,fastjson(漏洞频发)

<!--https://mvnrepository.com/artifact/com.alibaba/fastjson-->
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.73</version>
</dependency>

4.1 序列化

  • 包含null
  • 日期时间格式化
  • 奇怪的"$ref"
  • SerializeFilter定制处理
    • 对属性或属性值在序列化前做定制化处理

4.2 反序列化

  • 泛型处理
    • fastjson对于json中多key默认的处理就是忽略
  • 美化输出

示例

package com.roadjava.json.fastjson;

import lombok.Data;
/**
* @author chengyixuan
* @see <a href="http://www.roadjava.com">乐之者Java</a>
*/
@Data
public class Person {
    /**
    * 用户id
    */
    private Long id;
    private String name;
    private String pwd;
    
    /**
    * 地址
    */ 
    private String addr;
    
    /**
    * 网站
    */
    private String websiteUrl;
    @JSONField(format = "yyyy-MM-dd HH:mm:ss");
    private Date registerDate;
    private LocalDateTime birthDay;
    
}
public class ResultVO<T> {
        private Boolean success = Boolean.TRUE;
        private T data;
        private ResultVO(){}
        public static <T> ResultVT<T> buildSuccess(T t) {
            ResultVO<T> resultVO = new ResultVO<>();
            resultVO.setData(t);
            return resultVO;
        }
}

public class FastJsonTest {
    
    /**
    * 测试反序列化
    * json字符串 --> bean
    */
    @Test
    public void testDeSerialize() {
        String jsonStr = "{\"addr\":\"河南\",\"birthDay\":\"2021-08-17 03:23:18\", \"id\":1}";
        // 反序列化为person对象
        Person person = JSON.parseObject(jsonStr, Person.class);
        System.out.println(person);
        //返回给调用端ResuLtVO
		ResultVo<Person> personResultVo = ResultVo.buiLdSuccess(person);
        String voJsonStr = JSON.toJSoNString(personResultVO);
        //调用端需要把voJsonStr反序列化为对象
//        ResultVO0 resultVO = JSoN.parseObject(voJsonStr, ResultVo.class);
//        System.out.println("resultvo"+resultvo);
 //       Object data = resultVO.getData();
        // 需要反序列化为什么类型,就给TypeReference传入什么类型就可以
          ResultVO<Person> deSerializedVo = JSON.parseObject(voJsonStr, new TypeReference<ResultVO<Person>>) {
              
          }
        System.out.println("deSerializedVo:"+deSerializedVo);
        Person data = deSerializedVo.getData();
        System.out.println("data:"+data);
    }
    /**
    * SerializeFilter定制处理.要求
    * 输出的json字符串的Key是大写的。
    */
    @Test
    public void testSerializeFilter() {
        Person person = new Person();
        person.setId(1L);
//        person.setName("乐之者java");
        person.setPwd("123");
        person.setAddr("河南");
        person.setWebsiteUrl("http://www.roadjava.com");
        person.setRegisterDate(new Date());
        person.setBirthDay(LocalDateTime.now());
        /*
        * object:person对象
        * name:属性
        * vaLue:name属性对应的值
        */
        NameFilter nameFilter = (object,name,value) -> name.toUpperCase();
        String string = JsoN.toJsoNString(person,nameFilter);
        System.out.println(string);
    }
    /**
    * 测试fastjson的引用探测
    * $ref: 象中多次引用了同一个其他对象的时候,序列化就会出现$ref
    */
    @Test
    public void test$Ref() {
        List<Person>listt = new ArrayList<>();
        Personpersonn= new Person();
        person.setId(33L);
        person.setName("乐之者java");|
        list.add(person);
        list.add(person);
        list.add(person);
        // DisableCircularReferenceDetect 禁用引用探测功能
        String string = JSON.toJSONString(list, SerializerFeature.DisableCircuLarReferenceDetect); 
        System.out.println(string);
    }
    /**
    * 测试序列化
    * 把bean转为json字符串
    */
    @Test
    public void test1(){
        Person person = new Person();
        person.setId(1L);
        person.setPwd("123");
        person.setAddr("河南");
        person.setWebsiteUrl("http://www.roadjava.com");
        person.setRegisterDate(new Date());
        person.setBirthDay(LocalDateTime.now());
        // 序列化
        /*
        * WriteMapNullValue:指定序列化时包含null
        */
        String string = JSON.toJSONString(person, SerializerFeature.WriteMapNullValue);
        // 美化格式输出
        // String string = JSON.toJSONString(person, true);
        System.out.println(string);
        
    }
    
}

4.3 通用配置

  • 指定属性名和json字符串key的对应关系
  • 忽略指定属性

五,jackson

<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>${jackson.version}</version>
</dependency>
<!--对Loca1DateTime等jdk8时间目期api的转化支持-->
<dependency>
	<groupId>com.fasterxml.jackson.datatype</groupId>
	<artifactId>jackson-datatype-jsr310</artifactId>
	<version>${jackson.version}</version>
</dependency>

5.1 序列化

  • 只包含非null属性
    • 全局配置
    • 单个的bean配置
  • 日期时间格式化
    • 全局配置
    • 单个的bean配置

5.2 反序列化

  • 忽略不存在的key
  • 泛型处理

示例


public class User {
    /**
    * 用户id
    */ 
    private Long id;
    private String name;
    @Jsonignore
    private String pwd;
    /**
    * 地址
    */
    @JsonProperty("address")
    private String addr;
    /**
    * 网站
    */
    private String websiteUrl;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone="GMT+8")
    private Date registerDate;
    private LocalDateTime birthDay;
}
public class JacksonTest {
    
    private static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    private static ObjectMapper objectMapper = new ObjectMapper();
    
    static {
        /**
        * 序列化的配置
        */
        // 特殊配置: 配置序列化时只包含非空属性
        // 对Data进行配置, SimpleDateFormat是线程不安全的
		objectMapper.setDateFormat(new SimpLeDateFormat(DATE_TIME_FORMAT));
        // 美化输出
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true);
        
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        // 驼峰转下划线 userName -- user_name
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        /**
        * 反序列的配置
        */
        // 两种写法是一样的
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PEOPERTIES);
        
        /**
        * 全局的配置
        */
        // 自动通过spi发现jackson的module并注册生效
     //   objectMapper.findAndRegisterModules();

        // 手动配置JavaTimeModule并注册。
        JavaTimeModule javaTimeModule = new JavaTimeMOdule();
        javaTimeMOdule.addDeserializer(LocalDateTime.class, LocalDateTimeDeserializer.INSTANCE);
        objectMapper.registerModule(javaTimeModule);
	}
    /**
    * 对象更新, 对象的合并,如果有后者的属性有值,则用后者,否则前者的值不变
    */
    @Test
    public void test3() throws Exception {
        User originaluser = new User();
        originalUser.setId(1L);
        user.setName("乐之者java");
        user.setWebsiteUrl("http://www.roadjava.com");
        
        User newUser = new User();
        newUser.setId(2L);
        newUser.setName("乐之者java");
        newUser.setWebsiteUrl("http://www.roadjava.com”);
        
        User updateUser = objectMapper.updateValue(originalUser, newUser);
        // id:2 name: 乐之者 java websiteUrl:
        System.out.println(updatedUser);                      
    }
    /**
    *泛型的处理
    */
    @Test
    public void test3() throws Exception {
        User user = new User();
        user.setName("乐之者java");
        user.setWebsiteUrl("http:www.roadjava.com");
        ResultDTO<User> userResultDTO = ResultDTo.buiLdSuccess(user);
		String dtoSerializationResult = objectMapper.writeValueAsString(userResultDTO);
        // 反序列化为ResultDTO<User>
        ResultDTO<User> deSerializationResult = objectMapper.readValue(dtoSerializationResult, new TypeReference<Object>() {
           });
		System.out.println("data:", ResultDTD.getData());
    }
    /**
    *反序列化
    */
    @Test
    public void test2() throws Exception {
        String str = "{\"id\":1, \"age\":88, \"pwd\":\"123\", \"addr\":\"河南\", \"websiteUr1\":}"
        
        User user = objectMapper.readValue(str, User.class);
        System.out.println(user);
    }
    /**
    * 序列化
    */
    @Test
    public void testl() {
        User user = new User();
        user.setId(1L);
 //       user.setName ("乐之者java");
        user.setPwd("123");
        user.setAddr("河南");
        user.setWebsiteUrl("http://www.roadjava.com");
        user.setRegisterDate(new Date());
        user.setBirthDay(LocalDateTime.now());
        String string = ObjectMapper.writeValueAsString(user);
        System.out.println(string);
    }
    
}

5.3 通用配置

  • 序列化: 驼峰转下划线/反序列化: 下划线转驼峰
  • 指定属性名和json字符串key的对应关系
  • 忽略指定属性

5.4 其他应用

  • 对象更新

http://www.kler.cn/a/318339.html

相关文章:

  • makefile 设置动态库路径参数
  • 缓存与数据库不一致的解决方案:深入理解与实践
  • HP G10服务器ESXI6.7告警提示ramdisk tmp已满
  • sol机器人pump机器人如何实现盈利的?什么是Pump 扫链机器人?
  • flutter 发版的时候设置版本号
  • Golang | Leetcode Golang题解之第559题N叉树的最大深度
  • Cilium + ebpf 系列文章- XDP (eXpress data Path)(四)
  • 基于jsonpath的JSON数据查找
  • golang学习笔记1-go程序执行流程
  • element-plus表格操作
  • C++之哈希 --- 哈希的应用(位图布隆过滤器)
  • 【鸿蒙】HarmonyOS NEXT开发快速入门教程之ArkTS语法装饰器(上)
  • 【软件测试】详解测试中常用的几种测试方法
  • 从更底层的角度理解网站的访问过程
  • 算法打卡:第十一章 图论part05
  • 关于Python升级以后脚本不能运行的问题
  • MongoDB-aggregate流式计算:去重操作
  • Linux下go环境安装、环境配置并执行第一个go程序
  • python多继承 - 子类指定父类
  • 【教程】鸿蒙ARKTS 打造数据驾驶舱---前序
  • 两数之和、三数之和、四数之和
  • 在mac中如何使python3作为默认版本
  • 用canvas画一个验证码
  • 从 Oracle 集群到单节点环境(详细记录一次数据迁移过程)之一:生产环境与目标服务器详情
  • 基于物联网的火灾报警器设计与实现(论文+源码)
  • 高维数据和超高维数据