我正在为JSON API编写一个SDK,我遇到了一个看似奇怪的问题。API在POST数据验证方面非常严格,并且在更新资源时不允许出现某些参数,例如id
。出于这个原因,我添加了@Expose(serialize = false)
作为资源类的ID字段。然而,它似乎仍然序列化这个字段,导致请求被拒绝。资源类大致如下:
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拒绝更新。测试代码如下。注意代码中的注解。
@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值的事实有关,但如果我明确告诉它不要序列化它,那就没关系了,对吗?
先谢谢你的帮助。
EDIT:在this.MySDK.organisation.update(this.newOrganisation.getId(), this.newOrganisation);
中,不会编辑组织示例。给定的ID只是添加到SDK将POST到的URL(POST /organisation/{id}
)
4条答案
按热度按时间55ooxyrt1#
感谢@peitek指出
@Expose
被忽略,除非.excludeFieldsWithoutExposeAnnotation()
被添加到GsonBuilder()
。然而,我选择不走这条路,因为它需要我将@Expose
添加到我的模型类的每个参数中,只是为了忽略序列化时的一个字段。相反,我编写了一个ExclusionStrategy
来检查参数上是否存在自定义的SkipSerialisation
注解。我实现了如下:完整的
GsonBuilder
策略:注解:
现在我只能
而且很有效!
5n0oy7gb2#
正如您在评论中提到的,
@Expose
应该是比transient
更好的选择。需要注意的是,默认Gson示例不考虑@Expose
注解!不管你设置了什么选项,它都会忽略它。如果你想激活
@Expose
选项,你需要自定义Gson。根据上面的代码,将其更改为:您的
@Expose(serialize = false)
应处于活动状态,并在序列化期间被排除。nhjlsmyf3#
我只是想在这里补充一下,你可以像这样以所需的方式使用Expose:
s5a0g9ez4#