当前位置: 首页 > 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/news/310907.html

相关文章:

  • Windows本地制作java证书(与jeecgboot配置本地证书ssl问题)
  • 基于vue框架的宠物领养管理系统88v55(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • Python 数学建模——傅里叶变换时间序列分析
  • LeetCode 算法笔记-第 04 章 基础算法篇
  • Docker vs. containerd 深度剖析容器运行时
  • 【kafka-01】kafka安装和基本核心概念
  • CSP-J算法基础 树状结构与二叉树
  • C++笔记21•C++11•
  • PyRosetta Task介绍及示例代码
  • nginx基础篇(一)
  • 算法:双指针题目练习
  • MATLAB图像处理
  • CISP备考题库(八)
  • 术语“in law”(在分布上)
  • oracle表的类型
  • 当 PC 端和移动端共用一个域名时,避免 CDN 缓存页面混乱(nginx)
  • 基于MATLAB/Simulink的模型降阶方法介绍
  • Unity射击游戏开发教程:(36)敌人关卡生成器的设计和开发
  • 【STM32系统】基于STM32设计的DAC输出电压与ADC检测电压系统(简易万用表,检测电压电流)——文末工程资料下载
  • IP协议及相关特性
  • 理解AAC和Opus的编码与解码流程
  • 企业导师面对面,产教融合实训基地搭建人才成长快车道
  • 掌握RESTful API设计:构建高效、可扩展的Web服务
  • Android Studio报错: Could not find pub.devrel:easypermissions:0.3.0, 改用linux编译
  • 在线考试|基于java的模拟考试系统小程序(源码+数据库+文档)
  • Modbus_RTU和Modbus库
  • 1.Seata 1.5.2 seata-server搭建
  • 线程池的类型和状态
  • sqli-labs靶场自动化利用工具——第11关
  • 【深度学习】(2)--PyTorch框架认识