我正在使用GSON和Retrofit。我想禁用空数组字段反序列化。
DTO:
public class Entity implements Serializable {
@SerializedName("body")
@Expose
private BodyObject body;
我使用rest API
。如果正文字段为空,则会发送空Array
:
{
"body": []
}
例外:
java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 443 path $.body
如果身体被填满,那么他们会发送正确的对象。
{
"body": {
"und": [
{
"value": "Test ....",
"summary": "",
"format": "filtered_html",
"safe_value": "<p>Test ....</p>\n",
"safe_summary": ""
}
]
}
}
-
Gson gson = new GsonBuilder()
.setLenient()
.create();
如何删除或禁用这些空数组反序列化?
答案 0 :(得分:2)
正如Alrama暗示,你可以通过创建自己的JsonDeserializer
来避免这种情况。
像
这样的东西public class BodyObjectDeserializer implements JsonDeserializer<BodyObject> {
@Override
public BodyObject deserialize(JsonElement json, Type typeOfT
,JsonDeserializationContext context)
throws JsonParseException {
try {
return new Gson().fromJson(json, typeOfT);
} catch (JsonSyntaxException e) {
log.warn("Body seems empty: {}",e.getMessage());
}
return null;
}
}
并将其注册到您用于反序列化的GSON
。
Gson gson = new GsonBuilder()
.setLenient() // maybe you do not need this
.registerTypeAdapter(BodyObject.class, new BodyObjectDeserializer())
.create();
答案 1 :(得分:0)
rest API应该尊重Object定义。对象永远不可能是一个数组。如果您无法更正rest API,则可以使用自定义反序列化器管理此对象,首先检查JSON是否包含空数组。 GSON custom deserializer
答案 2 :(得分:0)
这是我在GSON反序列化中跳过/清除空JSON数组的方式:
class MyResponseDeserializer implements JsonDeserializer<MyResponse>
{
@Override
public MyResponse deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
JsonObject obj = je.getAsJsonObject();
if (obj.get("payload").isJsonArray())
{
obj.remove("payload");
}
return new Gson().fromJson(obj, MyResponse.class );
}
}
...
或
class MyResponseDeserializer implements JsonDeserializer<MyResponse>
{
private void recScan( JsonObject obj )
{
Iterator<Map.Entry<String, JsonElement>> iter = obj.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, JsonElement> entry = iter.next();
JsonElement el = entry.getValue();
if (el.isJsonArray() && (el.getAsJsonArray().size() == 0)) {
iter.remove();
obj.remove(entry.getKey());
} else
if (el.isJsonObject()) {
recScan(el.getAsJsonObject());
}
}
}
@Override
public MyResponse deserialize(JsonElement je, Type type,
JsonDeserializationContext jdc)
throws JsonParseException
{
JsonObject obj = je.getAsJsonObject();
recScan(obj);
return new Gson().fromJson(obj, MyResponse.class );
}
}
当然还要将此附加到Gson Builder
Gson gson = new GsonBuilder()
.registerTypeAdapter(MyResponse.class, new MyResponseDeserializer())
.setLenient()
.create();