【问题标题】:Why does com.google.gson.Gson::toJson return an empty object?为什么 com.google.gson.Gson::toJson 返回一个空对象?
【发布时间】:2021-08-10 07:13:51
【问题描述】:

我正在处理的视图模型具有如下方法:

public String getModelJson() {
    final ItemModel model = this.getModel();
    if (model == null) {
        return StringUtils.EMPTY;
    }

    final GsonBuilder gsonBuilder = new GsonBuilder();
    final Gson gson = gsonBuilder.create();
    return gson.toJson(model);
}

此方法依赖 com.google.gson.Gson::toJson 将 POJO 模型序列化为我认为可以使用的 JSON 字符串。这是模型代码:

public final class ItemModel extends ContentFragmentModel {
    
    @Expose
    private String error;

    @Expose
    private String id;

    @Expose
    private String name;

    public ItemModel(final ContentFragment fragment) {
        super(fragment);
    }

    public String id() {
        return this.id;
    }

    public String name() {
        return this.name;
    }

    @Override
    protected String getModelPath() {
        return "/path/to/model";
    }
}

当我从我的角度调用getModelJson 时,该方法总是返回{},即使我可以证明模型正在正确加载;如果我这样重写方法:

public String getModelJson() {
    final ItemModel model = this.getModel();
    return model != null ? "{\"name\": \"" + model.getName() + "\"}";
}

...它返回预期的输出:{"name": "item name"},其中item name 是从片段正确加载的名称。

如何让模型正确序列化?

【问题讨论】:

    标签: java json model-view-controller gson


    【解决方案1】:

    我意识到了问题所在。下面是基础模型类的代码:

    public abstract class ContentFragmentModel {
    
      protected String error;
    
      private boolean isValid = false;
    
      public ContentFragmentModel(@NotNull final ContentFragment fragment) {
        final String className = this.getClass().getSimpleName();
        if (fragment == null) {
          this.error = "No content fragment passed to " + className + ".";
          return;
        }
    
        final String fragmentModelPath = FragmentUtil.getFragmentModelPath(
          fragment
        );
        if (!fragmentModelPath.equals(this.getModelPath())) {
          this.error = "Invalid content fragment passed to " + className + ".";
          return;
        }
    
        this.loadElements(fragment);
    
        this.isValid = true;
      }
    
      public @NotNull String getError() {
        return StringUtils.defaultIfBlank(this.error, StringUtils.EMPTY);
      }
    
      public boolean isValid() {
        return this.isValid;
      }
    
      protected abstract String getModelPath();
    }
    

    请注意,基础模型类和模型类有一个名为error 的成员。在基类中,该成员是protected。在扩展类中,它是private。这显然在 Java 中有效——子类中的成员隐藏了父成员——但这种奇怪的类继承用法似乎破坏了com.google.gson.Gson::toJsonthe docs 中没有针对该方法提及这一点,所以我在这里添加一个帖子,希望如果他们遇到与我遇到的相同问题,他们可以在几个小时内拯救一些可怜的灵魂。

    对我来说,解决方法就是从扩展类中删除 error 成员。我发现它甚至没有真正用于任何东西,所以我只是删除了它。如果您遇到无法简单删除的成员的情况,您可以尝试重命名它,使其不会与基类中的成员发生冲突。

    【讨论】:

      猜你喜欢
      • 2020-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-23
      • 2016-06-04
      • 2018-12-17
      • 2019-11-25
      • 1970-01-01
      相关资源
      最近更新 更多