FastJson 转换自定义枚举类详解

在 Java 开发中,枚举类是一种非常有用的数据类型,它可以定义一组固定的常量值。而 FastJson 是一个高性能的 JSON 处理库,在实际项目中经常会用到将自定义枚举类与 JSON 格式进行相互转换的操作。本文将详细介绍如何使用 FastJson 进行自定义枚举类的转换,包括常见的转换方式、最佳实践以及示例代码。

目录#

  1. 自定义枚举类的定义
  2. FastJson 基本转换方法
  3. 自定义序列化和反序列化
  4. 常见问题及解决
  5. 最佳实践
  6. 示例代码
  7. 参考

1. 自定义枚举类的定义#

首先,我们需要定义一个自定义的枚举类。例如,我们定义一个表示星期几的枚举类:

public enum WeekDay {
    MONDAY("星期一"),
    TUESDAY("星期二"),
    WEDNESDAY("星期三"),
    THURSDAY("星期四"),
    FRIDAY("星期五"),
    SATURDAY("星期六"),
    SUNDAY("星期日");
 
    private String value;
 
    WeekDay(String value) {
        this.value = value;
    }
 
    public String getValue() {
        return value;
    }
}

2. FastJson 基本转换方法#

2.1 序列化(枚举类转 JSON)#

FastJson 可以很方便地将枚举类对象转换为 JSON 字符串。

import com.alibaba.fastjson.JSON;
 
public class Main {
    public static void main(String[] args) {
        WeekDay weekDay = WeekDay.MONDAY;
        String jsonString = JSON.toJSONString(weekDay);
        System.out.println(jsonString);
    }
}

默认情况下,FastJson 会将枚举类的名称(如 "MONDAY")转换为 JSON 字符串。

2.2 反序列化(JSON 转枚举类)#

import com.alibaba.fastjson.JSON;
 
public class Main {
    public static void main(String[] args) {
        String jsonString = "\"MONDAY\"";
        WeekDay weekDay = JSON.parseObject(jsonString, WeekDay.class);
        System.out.println(weekDay.getValue());
    }
}

这里需要注意 JSON 字符串的格式要与枚举类的名称匹配。

3. 自定义序列化和反序列化#

3.1 自定义序列化#

如果我们希望在序列化时使用枚举类的 value(如 "星期一")而不是名称,可以自定义序列化。

import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.ObjectSerializer;
 
import java.io.IOException;
import java.lang.reflect.Type;
 
public class WeekDaySerializer implements ObjectSerializer {
    @Override
    public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
        WeekDay weekDay = (WeekDay) object;
        serializer.write(weekDay.getValue());
    }
}

然后在使用时指定序列化器:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
 
public class Main {
    public static void main(String[] args) {
        WeekDay weekDay = WeekDay.MONDAY;
        String jsonString = JSON.toJSONString(weekDay, new WeekDaySerializer(), SerializerFeature.WriteEnumUsingName);
        System.out.println(jsonString);
    }
}

3.2 自定义反序列化#

同样,自定义反序列化可以根据 value 来创建枚举类对象。

import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONLexer;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
 
import java.lang.reflect.Type;
 
public class WeekDayDeserializer implements ObjectDeserializer {
    @Override
    public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
        JSONLexer lexer = parser.getLexer();
        if (lexer.token() == JSONToken.LITERAL_STRING) {
            String value = lexer.stringVal();
            for (WeekDay weekDay : WeekDay.values()) {
                if (weekDay.getValue().equals(value)) {
                    return (T) weekDay;
                }
            }
        }
        return null;
    }
 
    @Override
    public int getFastMatchToken() {
        return JSONToken.LITERAL_STRING;
    }
}

使用时指定反序列化器:

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.parser.ParserConfig;
 
public class Main {
    public static void main(String[] args) {
        String jsonString = "\"星期一\"";
        ParserConfig.getGlobalInstance().putDeserializer(WeekDay.class, new WeekDayDeserializer());
        WeekDay weekDay = JSON.parseObject(jsonString, WeekDay.class);
        System.out.println(weekDay);
    }
}

4. 常见问题及解决#

4.1 枚举类值不匹配#

如果 JSON 字符串中的值与枚举类的 value 不匹配,反序列化会失败。解决方法是在自定义反序列化中添加更友好的错误处理,或者在前端保证传输的 JSON 数据正确。

4.2 序列化器和反序列化器未正确注册#

确保自定义的序列化器和反序列化器在使用前正确注册到 FastJson 的配置中。

5. 最佳实践#

  • 在项目中统一枚举类的转换规则,避免不同模块使用不同的转换方式导致混乱。
  • 对于复杂的枚举类转换,优先使用自定义序列化和反序列化,提高代码的可读性和可维护性。
  • 对转换过程进行单元测试,确保在各种输入情况下都能正确转换。

6. 示例代码#

完整的示例代码可以在 GitHub 上获取(假设你有一个示例代码仓库)。

7. 参考#

通过以上介绍,相信你对 FastJson 转换自定义枚举类有了更深入的了解,可以在实际项目中灵活运用。