首页 > 其他分享 >放弃fastjson拥抱jackson

放弃fastjson拥抱jackson

时间:2024-08-19 10:37:49浏览次数:12  
标签:fastjson jackson converter JSON import 序列化 拥抱 ObjectMapper

放弃fastjson 拥抱jackson

背景

  • 功能强大 好用;不亏是国人更懂国人;但是安全漏洞频发;生产项目总是告警 勒令修改 放弃使用。
  • 坑爹玩意fastjson 漏洞太多 直接搞了fastjson2;虽然大部分兼容 远古项目还需要升级谁敢动呀。动了引发一些未知BUG那岂不是背锅侠(玩笑 该干还得干 挣得就是这个钱)

安全漏洞

  • 产生原因:序列化和反序列化;无非就是反序列化的时候能够注入调用一些非法函数。攻击者可以构造特殊的序列化数据包,当目标系统尝试反序列化这些数据时,恶意代码就会被执行

替代方案

  • 都是JSON 序列化框架 跟着spring大腿学习使用springboot 默认序列化框架jackson
  • jackson 运行是占用内存较低 性能较好

jackjson 模块

  • jackson-databind数据绑定
  • jackson-core用于JSON解析和生成
  • jackson-annotations 用于注解支持

1. 核心类

  • ObjectMapper

2.JackJson 序列化API

普通对象

复杂对象

List

Map

以上序列化使用writeValueAsString方法均可以 暂无特别之处

日期处理

  • 默认Date类型序列化成时间戳
  • 代用ObjectMapper setDateFormat 方法设置日期序列化转换格式 (SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");)

4.Jackjson 反序列化API

  1. jackson通过将JSON字段的名称与Java对象中的getter和setter方法进行匹配,将JSON对象的字段映射到Java对象中的属性。
  2. Jackson删除了getter和setter方法名称的“ get”和“ set”部分,并将其余名称的第一个字符转换为小写。

4.1 普通字符串反序列化(都有现成api暂不提供示例)

Jackjson 支持输入json字符串反序列化

Jackjson 支持输入文件反序列化

Jackjson 支持输入字节流反序列化

Jackjson 支持输入url反序列化

Jackjson 支持输入字节数组反序列化

4.2 JSON 数组字符串反序列化(反序列化的时候需要提供TypeReference类型)

JSON 数组字符串 -> Map集合

JSON 数组字符串 -> List集合

JSON 数组字符串 -> 对象数组

5. 支持自定义序列化反序列化示例

5.1 自定义序列化

  SimpleModule version1Module = new SimpleModule();
  //自定义序列化
  version1Module.addSerializer(User.class, new JsonSerializer<User>() {
        @Override
        public void serialize(User user, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            jsonGenerator.writeStartObject();
            jsonGenerator.writeStringField("username", user.getName());
            jsonGenerator.writeNumberField("userage", user.getAge());
            jsonGenerator.writeEndObject();
        }
    });
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.registerModule(version1Module);

5.2 自定义反序列化

public class UserDeserializer extends StdDeserializer<User> {

    public UserDeserializer() {
        this(null);
    }

    public UserDeserializer(Class<?> vc) {
        super(vc);
    }

    @Override
    public User deserialize(JsonParser jp, DeserializationContext ctxt)
        throws IOException {
        JsonNode node = jp.getCodec().readTree(jp);
        String name = node.get("name").asText();
        int age = (Integer) ((IntNode) node.get("age")).numberValue();

        return new User(name, age);
    }
}

6. 树模型(JsonNode)

JsonNode 子类实现

  • ObjectNode:对应JSON对象,包含一组键值对,可以通过.put(key, value)添加或更新属性。
  • ArrayNode:对应JSON数组,包含一系列元素,可通过.add(value)插入新元素。
  • TextNode、IntNode、LongNode、DoubleNode等:分别对应JSON中的字符串、整数、长整数、浮点数等基本类型值。
  • BooleanNode、NullNode:分别对应JSON中的布尔值和null值。

7.Jackson注解使用

  1. @JsonIgnore 用于在序列化或反序列化过程中忽略某个属性
  2. @JsonIgnoreProperties (类级别注解) 用于批量指定在序列化或反序列化过程中应忽略的属性列表,特别适用于应对不明确或动态变化的输入 JSON 中可能存在但不应处理的额外字段 ignoreUnknown 为true 会自动忽略Java类型中没有对应的未知属性
  3. @JsonIgnoreType (类级别注解) 忽略某个类都不进行序列化
  4. @JsonProperty 用于指定类的属性在序列化和反序列化成 JSON 时所对应的键名
  5. @JsonFormat 用于指定日期、时间、日期时间以及其他数值类型在序列化和反序列化为 JSON 时的格式
  6. @JsonInclude
    • VALUE_DEFAULT:这是默认策略,意味着所有字段都会被序列化,无论其值是否为 null
    • NON_NULL:只有非 null 的字段会被序列化。这是最常用的策略,可以减少 JSON 输出的大小,尤其是在字段可能经常为 null 的情况下
    • NON_ABSENT:除了 null 值,还会忽略那些未设置(未初始化)的字段。在 Java 中,这意味着除了 null,还会忽略默认值(如 0、false 或空字符串)
    • NON_EMPTY:除了 null 和未初始化的值,还会忽略那些被认为是“空”的值,如空字符串、空集合或空数组
  7. @JsonAnyGetter 用于标记一个方法,获取除已知属性外的所有其他键值对。这些键值对通常存储在一个 Map 结构中,以便将它们作为一个附加的对象进行序列化。
    • 动态属性支持:通过在返回 Map 的方法上使用 @JsonAnyGetter,您可以将一个对象的动态属性集合序列化为 JSON 对象的多个键值对。这些属性可能是在运行时添加的,或者基于某些条件动态生成的。
    • 简化结构:避免为每个可能的动态属性单独声明字段和 getter/setter。只需维护一个 Map,即可处理任意数量和类型的额外属性。
    • 兼容性与灵活性:当需要与未知或未来可能变化的数据结构交互时,@JsonAnyGetter 可确保 JSON 表示能够容纳未预定义的属性,从而提高系统的兼容性和适应性。
  8. @JsonSerialize 指定字段使用特定序列化策略
  9. @JsonDeserialize 指定字段使用特定反序列化策略
  10. @JsonAnySetter 用于处理反序列化过程中遇到的未知或额外的 JSON 键值对。当一个对象的JSON表示中包含无法直接映射到已声明属性的键时,这个注解可以帮助捕获并存储这些额外的数据 反序列化字段是Map类型未明确具体类型
  11. @JsonRawValue 指示Jackson在序列化时应将其原始值视为未经转义的 JSON 字符串,并直接嵌入到输出的 JSON 文档中

8. SpringBoot 如何不覆盖默认的Jackson而是拓展?

  1. 实现WebMvcConfigurer接口并覆盖extendMessageConverters方法
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    import java.text.SimpleDateFormat;
    import java.util.List;
    @Configuration
    public class JacksonConfig implements WebMvcConfigurer {
        @Override
        public void extendMessageConverters(List<HttpMessageConverter`<?>> converters) {
            for (HttpMessageConverter<?>` converter : converters) {
                if (converter instanceof MappingJackson2HttpMessageConverter) {
                    ObjectMapper objectMapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
                    // 在这里配置你的 ObjectMapper
                    // 例如设置日期格式
                    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
                }
            }
        }
    }
  1. 使用Customizer接口扩展Jackson行为
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    import java.text.SimpleDateFormat;
    import java.util.List;

    @Configuration
    public class JacksonConfig implements WebMvcConfigurer {
        @Override
        public void extendMessageConverters(List<HttpMessageConverter`<?>> converters) {
            for (HttpMessageConverter<?>` converter : converters) {
                if (converter instanceof MappingJackson2HttpMessageConverter) {
                    ObjectMapper objectMapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
                    // 在这里配置你的 ObjectMapper
                    // 例如设置日期格式
                    objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
                }
            }
        }
    }

标签:fastjson,jackson,converter,JSON,import,序列化,拥抱,ObjectMapper
From: https://www.cnblogs.com/heyanfeng/p/18348092

相关文章

  • 第17天 信息打点-语言框架&开发组件&FastJson&Shiro&Log4j&SpringBoot等
    时间轴演示案例指纹识别—本地工具—GotoScanPython—开发框架—Django&FlaskPHP—开发框架—ThinkPHP&Laravel&YiiJava—框架组件—FastJson&Shiro&Solr&Spring知识点1.CMS指纹识别—不出网程序识别解决:CMS识别到后前期漏洞利用和代码审计一般PHP开发居多,利用源码......
  • 思考-----程序员们在这个日新月异的变化中,如何拥抱世界的变化之快
    在这个日新月异的时代,确实每个人都在面临着前所未有的挑战与变化,如何适应并引领这种变化成为了每个人都需要思考的问题。您提到的策略非常中肯且实用,以下是对您观点的一些进一步阐述和补充:1.打好基础,强化内功持续学习:在快速发展的时代,知识更新速度极快,持续学习新技能、新知识是......
  • 电商平台:告别价格战,拥抱品质与体验
    原文链接:https://tecdat.cn/?p=37270“用低价换来一时的流量并不能换来长线的店铺良性发展。”最近,各大电商平台都修改了运营规则。618大促结束后,淘天集团召开了一场商家闭门会,并决定从下半年开始,弱化以“五星价格力”为核心的搜索权重分配体系,改回按GMV(商品交易总额)分配。7月初,......
  • com.alibaba.fastjson 将object装jsonObject两次字段顺序会出现不一致
    Objectentity=params.get("entity");JSONObjectjsonObject=(JSONObject)JSONObject.toJSON(entity);//遍历JSONObjectfor(Map.Entry<String,Object>entry:jsonObject.entrySet())以上代码,在同一个object,两次经过的到时候,遍历J......
  • 爬虫“拥抱大模型”,有没有搞头?
    前言大模型是当前最热门的研究方向之一,千行百业加速“拥抱大模型”。如今,越来越多的研究机构和企业选择开放大模型的源代码和训练数据,促进了学术界和工业界的合作与交流,推动了技术进步,相关生态越来越好。这也使得,无论体量大小,各公司都有参与的机会,越来越多的大模型开始支持多模......
  • fastjson反序列化漏洞原理及<=1.2.24&<=1.2.47&Fastjson v1.2.80简单利用&不出网判断&修
    1、什么是fastjsonfastjson是一个有阿里开发的一个开源Java类库,可以将Java对象转换为JSON格式(序列化),当然它也可以将JSON字符串转换为Java对象(反序列化)。2、漏洞原理FastJson在解析json的过程中,⽀持使⽤autoType来实例化某⼀个具体的类,并调⽤该类的set/get⽅法......
  • fastJson对jsonPath的支持
    使用场景很多时候我们调用上游接口拿到的返回值是json字符串,如果不存在上游共享的公用返回值类,那么下游可能会直接使用JsonObject之类的动态对象类承接这份数据。这时候对于很深的的属性取值是非常复杂的我们大概会这样写Stringgetvalue(StringjsonStr){JSONObjectjson......
  • jackson序列化(jackson codec)
    Jackson是一个用于Java平台的开源JSON库,它提供了灵活且高效的方式来处理JSON数据的序列化(Java对象→JSON字符串)和反序列化(JSON字符串→Java对象)。以下是Jackson的一些主要特点和功能:高性能:Jackson通过使用基于流的处理模型和性能优化技术,提供了出色的性能。它支......
  • 2024.7 #3 我从不怕摔倒 拼命向前跑 把每一天过好 和大家拥抱
    我从不怕摔倒拼命向前跑把每一天过好和大家拥抱----乐正绫《万圣街》T1.P5572[CmdOI2019]简单的数论题和毒瘤之神的考验类似的毒瘤题。首先先化简原式:\[\begin{array}{l}\sum^n_{i=1}\sum^m_{j=1}\varphi(\dfrac{{\rmlcm}(i,j)}{\gcd(i,j)})=\sum^n_{i=1}\s......
  • com.alibaba.fastjson.JSONObject cannot be cast to xxx
    问题描述:通过redis读取的缓存对象用Object去接,因为我们已经知道他具体是什么类型了,所以接来的对象直接转换,报了上述错误。这里其实我们已经对该实体类完成了序列化与反序列化。 publicclassLoginUserimplementsSerializableLoginUserloginUser=redisCache.getCache......