java:jackson 三:Jackson – Custom Serializer

java:jackson 三:Jackson – Custom Serializer

1 前言

jackson支持自定义序列化器,参考文档地址如下:

https://www.baeldung.com/jackson

https://www.baeldung.com/jackson-custom-serialization

依赖如下(这里使用jackson-databind的2.14.1版本):

<properties>
    <jackson.version>2.14.1</jackson.version>
</properties>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>

2 使用

2.1 Standard Serialization of an Object Graph

This will result in a full JSON representation for both entities:

package com.xiaoxu.test.jackson;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import lombok.Data;
import lombok.ToString;

/**
 * @author xiaoxu
 * @date 2022-12-23
 * spring_boot:com.xiaoxu.test.jackson.TestCustomizeSeriJackson
 */
public class TestCustomizeSeriJackson {
    private static final ObjectMapper objectMapper;
    static {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);

    }
    public static void buildDto() throws Exception{
        Complex complex = new Complex();
        complex.setComId(123L);
        complex.setValue("i am complex.");
        Feui feui = new Feui();
        feui.setId(1);
        feui.setName("xiaoxu");

        complex.setFeui(feui);
        System.out.println(objectMapper.writeValueAsString(complex));

    }

    public static void main(String[] args) throws Exception{
        buildDto();
    }
}

@ToString
@Data
class Feui{
    int id;
    String name;
}

@ToString
@Data
class Complex{
    long comId;
    String value;
    Feui feui;
}

执行结果:

{
  "comId" : 123,
  "value" : "i am complex.",
  "feui" : {
    "id" : 1,
    "name" : "xiaoxu"
  }
}

2.2 Custom Serializer on the ObjectMapper

package com.xiaoxu.test.jackson;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;
import java.util.HashMap;

/**
 * @author xiaoxu
 * @date 2022-12-26
 * spring_boot:com.xiaoxu.test.jackson.TestCustomizeSeriJackson2
 */
public class TestCustomizeSeriJackson2 {
    private static final ObjectMapper objectMapper;
    static {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);

        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Complex.class, new ComplexSerializer());

        objectMapper.registerModule(simpleModule);
    }

    public static void buildDto() throws Exception{
        Complex complex = new Complex();
        complex.setComId(123L);
        complex.setValue("i am complex.");
        Feui feui = new Feui();
        feui.setId(1);
        feui.setName("xiaoxu");

        complex.setFeui(feui);

        /* 使用自定义序列化器,将会覆盖上述的赋值,按照自定义的序列化器进行序列化 */
        System.out.println(objectMapper.writeValueAsString(complex));

    }

    public static void main(String[] args) throws Exception{
        buildDto();
    }
}


class ComplexSerializer extends StdSerializer<Complex>{

    protected ComplexSerializer(){
        this(null);
    }

    protected ComplexSerializer(Class<Complex> t) {
        super(t);
    }

    @Override
    public void serialize(Complex complex, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        /* writeStartObject 和 writeEndObject组合使用,相当于写入一个对象,即外层包裹一个花括号 */
        jsonGenerator.writeStartObject();
        jsonGenerator.writeNumberField("idNew",666);
        jsonGenerator.writeStringField("nameNew","xiaoxuNew");
        jsonGenerator.writeObjectField("ext",new HashMap<>());
        jsonGenerator.writeEndObject();
    }
}

执行结果:

{
  "idNew" : 666,
  "nameNew" : "xiaoxuNew",
  "ext" : { }
}

2.3 Custom Serializer on the Class

We can also register the serializer directly on the class, instead of on the ObjectMapper

在这里插入图片描述
在这里插入图片描述

再次执行,效果和上述全局配置一致:

{
  "idNew" : 666,
  "nameNew" : "xiaoxuNew",
  "ext" : { }
}

2.4 Custom Serializer

package com.xiaoxu.test.jackson;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.Data;
import lombok.ToString;

import java.io.IOException;

/**
 * @author xiaoxu
 * @date 2022-12-26
 * spring_boot:com.xiaoxu.test.jackson.TestCustomizeSeriJackson3
 */
public class TestCustomizeSeriJackson3 {
    private static final ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true);

        SimpleModule simpleModule = new SimpleModule();

        simpleModule.addSerializer(BEnum.class, new MySerializer());

        objectMapper.registerModule(simpleModule);
    }

    public static void main(String[] args) throws Exception{
        TestMy testMy = new TestMy();
        testMy.setId(145);
        testMy.setMyName("xiaoxu");
        testMy.setMy(My.Grape);

        System.out.println(objectMapper.writeValueAsString(testMy));
    }
}

@SuppressWarnings("rawtypes")
class MySerializer extends JsonSerializer implements ContextualSerializer{

    @Override
    public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        /* 1 */
        jsonGenerator.writeString(o.toString());
        jsonGenerator.writeStringField("fruitCode", ((BEnum<String>)o).getCode());
        jsonGenerator.writeStringField("fruitDesc", ((BEnum<String>)o).getDesc());

        /* 2 */
//        jsonGenerator.writeStartObject();
//        jsonGenerator.writeStringField("fruitCode", ((BEnum<String>)o).getCode());
//        jsonGenerator.writeStringField("fruitDesc", ((BEnum<String>)o).getDesc());
//        jsonGenerator.writeEndObject();
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        return this;
    }
}

@Data
@ToString
class TestMy{
    int id;
    My my;
    String myName;
}

enum My implements BEnum<String>{
    Apple("01","苹果"),
    Grape("02","葡萄");

    private String code;
    private String desc;

    My(String code, String desc){
        this.code = code;
        this.desc = desc;
    }
    @Override
    public String getCode() {
        return this.code;
    }

    @Override
    public String getDesc() {
        return this.desc;
    }

    @Override
    public void setCode(String code) {
        this.code = code;
    }

    @Override
    public void setDesc(String desc) {
        this.desc = desc;
    }
}

interface BEnum<T>{
    T getCode();
    T getDesc();

    void setCode(T code);
    void setDesc(T desc);
}

执行第一种方式:

{
  "id" : 145,
  "my" : "Grape",
  "fruitCode" : "02",
  "fruitDesc" : "葡萄",
  "myName" : "xiaoxu"
}

执行第二种方式:

在这里插入图片描述

{
  "id" : 145,
  "my" : {
    "fruitCode" : "02",
    "fruitDesc" : "葡萄"
  },
  "myName" : "xiaoxu"
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值