Jackson自定義序列化:為枚舉類型添加文本字段

在使用Jackson進行JSON序列化時,有時我們需要在序列化枚舉類型時,不僅輸出枚舉值,還需要輸出其對應(yīng)的文本描述。本文將介紹如何通過自定義序列化器來實現(xiàn)這個功能。

1. 定義枚舉接口

首先,我們定義一個通用的枚舉接口,用于規(guī)范枚舉類型:

public interface ValueEnum {
    String getCode();
    String getText();
}

2. 實現(xiàn)示例枚舉

創(chuàng)建一個示例枚舉類實現(xiàn)上述接口:

public enum StatusEnum implements ValueEnum {
    ACTIVE("1", "激活"),
    INACTIVE("0", "未激活");

    private final String code;
    private final String text;

    StatusEnum(String code, String text) {
        this.code = code;
        this.text = text;
    }

    @Override
    public String getCode() {
        return code;
    }

    @Override
    public String getText() {
        return text;
    }
}

3. 自定義序列化器

實現(xiàn)自定義序列化器,用于在序列化時同時輸出枚舉值和文本描述:

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.util.Objects;

/**
 * 自定義枚舉序列化器,用于在序列化時添加文本字段
 * @JsonSerialize(using = AddFieldJsonSerializer.class, nullsUsing = AddFieldJsonSerializer.class)
 */
public class AddFieldJsonSerializer extends JsonSerializer<ValueEnum> {
    @Override
    public void serialize(ValueEnum valueEnum, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
        // 獲取當(dāng)前字段名稱
        String fieldName = gen.getOutputContext().getCurrentName();

        if (Objects.nonNull(valueEnum)) {
            // 寫入原始字段的值
            gen.writeString(String.valueOf(valueEnum.getCode()));
        } else {
            gen.writeNull();
        }

        // 寫入新增的文本字段
        gen.writeFieldName(fieldName.concat("Text"));
        if (Objects.nonNull(valueEnum)) {
            gen.writeString(valueEnum.getText());
        } else {
            gen.writeNull();
        }
    }
}

4. 創(chuàng)建測試實體類

import com.fasterxml.jackson.databind.annotation.JsonSerialize;

public class User {
    private String id;
    
    @JsonSerialize(using = AddFieldJsonSerializer.class, nullsUsing = AddFieldJsonSerializer.class)
    private StatusEnum status;

    // getter和setter方法
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public StatusEnum getStatus() {
        return status;
    }

    public void setStatus(StatusEnum status) {
        this.status = status;
    }
}
  1. 編寫測試用例
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AddFieldJsonSerializerTest {

    @Test
    public void testSerializeEnum() throws Exception {
        // 準備測試數(shù)據(jù)
        User user = new User();
        user.setId("1");
        user.setStatus(StatusEnum.ACTIVE);

        // 序列化
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(user);

        // 驗證結(jié)果
        String expectedJson = "{\"id\":\"1\",\"status\":\"1\",\"statusText\":\"激活\"}";
        assertEquals(expectedJson, json);

        // 測試空值情況
        user.setStatus(null);
        json = mapper.writeValueAsString(user);
        expectedJson = "{\"id\":\"1\",\"status\":null,\"statusText\":null}";
        assertEquals(expectedJson, json);
    }
}

6. 添加Maven依賴

<dependencies>
    <!-- Jackson依賴 -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.15.2</version>
    </dependency>
    
    <!-- 測試依賴 -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.9.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

序列化結(jié)果說明
當(dāng)我們使用這個自定義序列化器后,JSON輸出將包含兩個字段:

  1. 原始字段:包含枚舉的code值
  2. 文本字段:字段名為原始字段名+"Text"后綴,包含枚舉的文本描述
    例如,對于上面的測試用例,輸出結(jié)果為:
{
    "id": "1",
    "status": "1",
    "statusText": "激活"
}

地址:https://gitee.com/ChaiYe/jackson-serial

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容