在JSON序列化中,如果Class1是Class2的字段,如何忽略一些Class1字段?

时间:2017-11-11 19:46:16

标签: java json serialization gson

我在stackoverflow和google上搜索了这个问题,我找不到任何正确的答案。

如何忽略对象中对象的字段?

我认为用一个例子来理解会更容易:

(编者注:标题:#a different attempt at plotting cod and mako data separately ggplot() + geom_line(data = mako.landings, aes(year, mako_catch, color = mako_catch)) + geom_line(data = cod.landings, aes(year, cod_catch, color = cod_catch)) = Class1 Engine = Class2的字段

Car

Car JSON应包含所有字段,但Car对象中的Engine对象应限制为class Car { Integer id; Integer numberOfWheels; Engine engine; } class Engine { Integer id; String name; String producer; Integer horsePower; Integer weight; }

id, name, producer

然而,引擎JSON应包含所有字段{ "id":1, "numberOfWheels":4, "engine": { "id":1, "name":"some engine" "producer":"some engine producer" } }

id, name, producer, horsePower, weight

只是澄清一下。字段{ "id":1, "name":"some engine" "producer":"some engine producer" "horsePower":250 "weight":500 } horsePower只能在Car。生成的JSON中忽略。

2 个答案:

答案 0 :(得分:1)

查看gson JsonSerializerExclusionStrategy。也许不是最简洁的方法 - 特别是与你自己的解决方案相比 - 但总的来说是个不错的选择。

要让Car进行一些特殊处理,请创建JsonSerializer

public class CarSerializer implements JsonSerializer<Car> {
    private final Gson gson = new GsonBuilder()
            .addSerializationExclusionStrategy(new FieldExclusionStrategy()).create();

    @Override
    public JsonElement serialize(Car arg0, Type arg1, JsonSerializationContext arg2) {
        return new JsonParser().parse(gson.toJson(arg0));
    }
}

上面有自己的gson来处理Car而不会弄乱任何其他序列化。前面提到将ExclusionStrategy注册到自己的私人用途,检查Car字段是否Engine,然后跳过Engine中的任何不需要的字段。

public class FieldExclusionStrategy  implements ExclusionStrategy {
    private Set<String> ignored = 
            new HashSet<String>(Arrays.asList( new String[]{"horsePower","weight"}));
    @Override
    public boolean shouldSkipField(FieldAttributes arg0) {
        if(arg0.getDeclaringClass().isAssignableFrom(Engine.class))
            if(ignored.contains(arg0.getName())) return true;
        return false;
    }       
    @Override
    public boolean shouldSkipClass(Class<?> arg0) { return false; }
}

它可以与gson一起使用,注册JsonSerializer作为Car.class的类型适配器:

Gson gson = new GsonBuilder().setPrettyPrinting()
      .registerTypeAdapter(Car.class, new CarSerializer()).create();

答案 1 :(得分:0)

我不耐烦并决定创建一个临时解决方案,直到找到更好的方法。这个解决方案可能是也可能不是最佳实践,但我没有更好的解决方案。

如果有人发现这个问题并且想知道解决方案,我已经决定发布我的临时解决方案。

我仍然在寻找类型安全和最佳实践解决方案,所以如果有人得到任何答案,请发布。无论您何时发布解决方案,我都会接受您的回答。

class Car {
    Integer id;
    Integer numberOfWheels;
    @JsonIgnore
    Engine engine;

    @JsonProperty("engine")
    public Map<String, Object> getEngineFormatted(){
        return engine == null ? null : engine.getFormatted();
    }
}   

class Engine {
    Integer id;
    String name;
    String producer;
    Integer horsePower;
    Integer weight; 

    public Map<String, Object> getFormatted(){
        Map<String, Object> map = new HashMap<>();

        map.put("id", id);
        map.put("name", name);
        map.put("producer", producer);

        return map;
    }
}

Car JSON:

{
  "id":1,
  "numberOfWheels":4,
  "engine": {
    "id":1,
    "name":"some engine"
    "producer":"some engine producer"
  }
}

引擎JSON

{
    "id":1,
    "name":"some engine"
    "producer":"some engine producer"
    "horsePower":250
    "weight":500
}