Excluding certain fields from Serialization based on value in GSON

前端 未结 3 891
夕颜
夕颜 2020-12-28 23:01

I am using GSON for my serialization purposes, I am not finding a way of excluding certain fields from serialization based on ExclusionStrategy class provided by Gson based

相关标签:
3条回答
  • 2020-12-28 23:09

    The way to achieve this is by creating custom serializer for the class in question. After allowing Gson to create a JSON object in default fashion, remove the property that you want to exclude based on its value.

    public class SerializerForMyClass implements JsonSerializer<MyClass> {  
    
        @Override
        public JsonElement serialize(MyClass obj, Type type, JsonSerializationContext jsc) {
            Gson gson = new Gson();
            JsonObject jObj = (JsonObject)gson.toJsonTree(obj);   
            if(obj.getMyProperty()==0){
                jObj.remove("myProperty");
            }
            return jObj;
        }
    }
    

    And registering the new serializer in the Gson object that you use for serialization in the application for this class.

    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(MyClass.class, new SerializerForMyClass());
    Gson gson=gsonBuilder.create();
    gson.toJson(myObjectOfTypeMyClass);
    
    0 讨论(0)
  • 2020-12-28 23:25

    This is how I use a type adapter to avoid serializing boolean values that are false. It avoids creating an additional Gson instance and does not rely on specific field names.

    class MyClassTypeAdapter: JsonSerializer<MyClass>{
       override fun serialize(myObject: MyClass, type: Type, context: JsonSerializationContext): JsonElement {
          val jsonElement = context.serialize(myObject)
    
          jsonElement.asJsonObject.entrySet().removeAll { it.value is JsonPrimitive && (it.value as JsonPrimitive).isBoolean && !it.value.asBoolean }
    
          return jsonElement
       }
    }
    
    0 讨论(0)
  • 2020-12-28 23:27

    Here's a more in depth example of a class I wrote to remove all false booleans as well as all "false" strings. It was thrown together pretty quickly but seems to work ok. Let me know if there are any bugs you find.

    public class RemoveFalseJsonSerializer implements JsonSerializer<Object> {
    
    //~ Methods --------------------------------------------------------------------------------------------------------
    
    /**
     * serialize
     *
     * @param object in value
     * @param type in value
     * @param jsonSerializationContext in value
     *
     * @return out value
     */
    @Override
    public JsonElement serialize(Object object, Type type, JsonSerializationContext jsonSerializationContext) {
        Gson gson = new Gson();
        JsonElement jsonElement = gson.toJsonTree(object);
        trimJson(jsonElement);
        return jsonElement;
    }
    
    /**
     * We've finally made it to a primitive of some sort.  Should we trim it?
     *
     * @param jsonElement in value
     *
     * @return out value
     */
    private boolean shouldTrimElement(JsonElement jsonElement) {
        return jsonElement == null || jsonElement.isJsonNull()
                || (jsonElement.isJsonPrimitive()
                    && ((jsonElement.getAsJsonPrimitive().isBoolean() && !jsonElement.getAsBoolean()) // trim false
                        || (jsonElement.getAsJsonPrimitive().isString() // also trim the string "false"
                            && "false".equalsIgnoreCase(jsonElement.getAsString()))));
    }
    
    /**
     * trimJson
     *
     * @param jsonElement in value
     */
    private void trimJson(JsonElement jsonElement) {
        if (jsonElement == null || jsonElement.isJsonNull() || jsonElement.isJsonPrimitive()) {
            return;
        }
    
        if (jsonElement.isJsonObject()) {
            List<String> toRemove = new ArrayList<>();
            JsonObject asJsonObject = jsonElement.getAsJsonObject();
            for (Map.Entry<String, JsonElement> jsonElementEntry : asJsonObject.entrySet()) {
                if (jsonElementEntry.getValue().isJsonObject() || jsonElementEntry.getValue().isJsonArray()) {
                    trimJson(jsonElementEntry.getValue());
                } else if (shouldTrimElement(jsonElementEntry.getValue())) {
                    toRemove.add(jsonElementEntry.getKey());
                }
            }
            if (CollectionUtils.isNotEmpty(toRemove)) {
                for (String remove : toRemove) {
                    asJsonObject.remove(remove);
                }
            }
        } else if (jsonElement.isJsonArray()) {
            JsonArray asJsonArray = jsonElement.getAsJsonArray();
            for (JsonElement element : asJsonArray) {
                trimJson(element);
            }
        }
    }
    }
    
    0 讨论(0)
提交回复
热议问题