You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Gson序列化/反序列化含非字符串类型枚举的POJO

Solution to Flatten Enum Properties in Gson Serialization

Got it, let's fix this to get the exact JSON structure you're aiming for. The problem with your current approach is that you're customizing how the ErrorCode enum is serialized, but Gson still wraps that result under the code field of your ApplicationError object. What you need is to flatten the enum's properties directly into the top-level JSON object alongside the description field.

Here's how to do it:

1. Implement Custom Serializer for ApplicationError

Instead of targeting the ErrorCode enum, create a serializer that handles the entire ApplicationError object. This lets you manually build the JSON structure exactly how you want it:

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import java.lang.reflect.Type;
import java.net.URL;

public class ApplicationErrorSerializer implements JsonSerializer<ApplicationError> {
    @Override
    public JsonElement serialize(ApplicationError src, Type typeOfSrc, JsonSerializationContext context) {
        JsonObject jsonObject = new JsonObject();
        
        // Add the error code value from the enum
        jsonObject.addProperty("code", src.getCode().getCode());
        // Add the error message from the enum
        jsonObject.addProperty("message", src.getCode().getMessage());
        // Add the description from ApplicationError
        jsonObject.addProperty("description", src.getDescription());
        
        // Optional: Handle the infoURL field if it exists
        if (src.getInfoURL() != null) {
            jsonObject.addProperty("infoURL", src.getInfoURL().toString());
        }
        
        return jsonObject;
    }
}

2. Implement Corresponding Deserializer (for round-tripping)

If you need to deserialize the JSON back into an ApplicationError object, you'll also need a custom deserializer that maps the top-level fields back to your POJO and enum:

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;

public class ApplicationErrorDeserializer implements JsonDeserializer<ApplicationError> {
    @Override
    public ApplicationError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonObject jsonObject = json.getAsJsonObject();
        
        // Find the matching ErrorCode using the top-level code value
        int errorCodeValue = jsonObject.get("code").getAsInt();
        ErrorCode errorCode = null;
        for (ErrorCode code : ErrorCode.values()) {
            if (code.getCode() == errorCodeValue) {
                errorCode = code;
                break;
            }
        }
        
        if (errorCode == null) {
            throw new JsonParseException("Unknown error code: " + errorCodeValue);
        }
        
        // Extract description
        String description = jsonObject.get("description").getAsString();
        
        // Optional: Handle infoURL if present
        URL infoURL = null;
        if (jsonObject.has("infoURL")) {
            try {
                infoURL = new URL(jsonObject.get("infoURL").getAsString());
            } catch (MalformedURLException e) {
                throw new JsonParseException("Invalid infoURL format", e);
            }
        }
        
        // Build and return the ApplicationError object
        return new ApplicationError(errorCode, description, infoURL);
    }
}

3. Register the Adapters with GsonBuilder

Now register both the serializer and deserializer when creating your Gson instance:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class Main {
    public static void main(String[] args) {
        ApplicationError applicationError = new ApplicationError(
            ErrorCode.INVALID_URL_PARAMETER, 
            "Application identifier is missing"
        );
        
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(ApplicationError.class, new ApplicationErrorSerializer());
        gsonBuilder.registerTypeAdapter(ApplicationError.class, new ApplicationErrorDeserializer());
        Gson gson = gsonBuilder.create();
        
        // Serialize to JSON
        String jsonOutput = gson.toJson(applicationError);
        System.out.println(jsonOutput);
        // Output: {"code":20,"message":"Invalid URL parameter value","description":"Application identifier is missing"}
        
        // Deserialize back to object
        ApplicationError deserializedError = gson.fromJson(jsonOutput, ApplicationError.class);
    }
}

Why Your Previous Approaches Didn't Work

  • Edit 1 serialized ErrorCode as an array, but it was still nested under the code field of ApplicationError.
  • Edit 2 serialized ErrorCode as an object, again nested under code.

By targeting the entire ApplicationError object instead of just the enum, we can flatten the enum's properties into the top-level JSON structure exactly as you requested.

内容的提问来源于stack exchange,提问作者Stéphane GRILLON

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:14:39