【发布时间】:2017-03-27 13:29:24
【问题描述】:
我正在为 JSON API 编写 SDK,但遇到了一个看似奇怪的问题。 API 在 POST 数据验证方面非常严格,并且在更新资源时不允许出现某些参数,例如 id。为此,我在资源类的 ID 字段中添加了@Expose(serialize = false)。然而,它似乎仍然序列化这个字段,导致请求被拒绝。资源类大致如下:
public class Organisation extends BaseObject
{
public static final Gson PRETTY_PRINT_JSON = new GsonBuilder()
.setPrettyPrinting()
.create();
@Expose(serialize = false)
@SerializedName("_id")
private String id;
@SerializedName("email")
private String email;
@SerializedName("name")
private String name;
@SerializedName("parent_id")
private String parentId;
public String toJson()
{
return PRETTY_PRINT_JSON.toJson(this);
}
}
我的单元测试通过 API 创建了一个 Organisation 的实例,将新创建的实例作为类参数保存到测试类中,并调用一个更新方法,该方法将通过更新新资源来测试 SDK 的更新实现。这就是它出错的地方。即使在新的 Organisation 上调用 toJson() 方法以将其序列化为 JSON 以用于更新请求,_id 字段仍然存在,导致 API 拒绝更新。测试代码如下。注意代码中的 cmets。
@Test
public void testCreateUpdateAndDeleteOrganisation() throws RequestException
{
Organisation organisation = new Organisation();
organisation.setParentId(this.ORGANISATION_ID);
organisation.setName("Java Test Organisation");
Organisation newOrganisation = this.MySDK.organisation.create(organisation);
this.testOrganisation(newOrganisation);
this.newOrganisation = newOrganisation;
this.testUpdateOrganisation();
}
public void testUpdateOrganisation() throws RequestException
{
// I tried setting ID to null, but that doesn't work either
// even though I've set Gson to not serialise null values
this.newOrganisation.setId(null);
this.newOrganisation.setName(this.newName);
// For debugging
System.out.println(this.newOrganisation.toJson());
Organisation updatedOrganisation = this.MySDK.organisation.update(this.newOrganisation.getId(), this.newOrganisation);
this.testOrganisation(updatedOrganisation);
assertEquals(newOrganisation.getName(), this.newName);
this.testDeleteOrganisation();
}
谁能发现我做错了什么?我觉得这与实例已经具有/具有 ID 值的事实有关,但如果我明确告诉它不要序列化它,这应该没关系吧?
提前感谢您的帮助。
编辑:在this.MySDK.organisation.update(this.newOrganisation.getId(), this.newOrganisation);,不编辑组织实例。给定 ID 仅添加到 SDK 将发布到的 URL (POST /organisation/{id})
【问题讨论】:
-
尝试改为
transient -
@cricket_007 我之前做过,但在反序列化时它被忽略了。我使用
@Expose对其进行了更多控制 -
看到这个了吗? futurestud.io/tutorials/…
-
@cricket_007 是的,我知道。你建议我从那个教程中改变什么?引用:“使用 \@Expose 的替代方法是将字段声明为瞬态。瞬态字段也不会(反)序列化。但是,您没有像使用 \@Expose 那样完全控制。您不能停用一个方向,transient 将始终完全关闭该属性的转换。”