我目前正在开发一个第三方REST。我正在为API返回的JSON对象创建对象。我正在跟踪他们的文档,其中说某些变量将是String。有时,当没有字符串时,它将返回False。有时,我期待一个URL,我得到假的。
我该怎么处理?
这是问题中的API https://developers.cannabisreports.com/docs/。
应变对象示例:https://ghostbin.com/paste/kgeau中的应变对象,我在执行搜索时得到一个异常。搜索的一些结果是布尔值,而不是注释掉的代码中的字符串/url。
有时候我会明白
"genetics": {
"names": false,
"ucpc": false,
"link": false
}有时候我能拿到这个
"genetics": {
"names": "Blueberry x Haze",
"ucpc": "W74AFGH22Z000000000000000 x 9XVU7WJQCD000000000000000",
"link": "https:\/\/www.cannabisreports.com\/api\/v1.0\/strains\/9XVU7PTG2P000000000000000\/genetics"
}发布于 2018-04-30 09:49:25
当您遇到设计不好的API时,Gson在反序列化由这样一个API生成的JSON文档时提供了一些灵活性。尽管您有很多方法来解决这个问题(比如JsonDeserializer,等等),但是您最喜欢面对的是我在这里已经看到的虚假为空的问题。您可以通过标记“错误”字段来帮助Gson:
final class Envelope {
final Genetics genetics = null;
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("genetics", genetics)
.toString();
}
}final class Genetics {
@JsonAdapter(FalseAsNullTypeAdapterFactory.class)
final String names = null;
@JsonAdapter(FalseAsNullTypeAdapterFactory.class)
final String ucpc = null;
@JsonAdapter(FalseAsNullTypeAdapterFactory.class)
final URL link = null;
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("names", names)
.add("ucpc", ucpc)
.add("link", link)
.toString();
}
}类型适配器工厂就是这样实现的:
final class FalseAsNullTypeAdapterFactory
implements TypeAdapterFactory {
// No worries, Gson will instantiate it itself
private FalseAsNullTypeAdapterFactory() {
}
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
final TypeAdapter<T> delegateAdapter = gson.getAdapter(typeToken);
return new TypeAdapter<T>() {
@Override
public void write(final JsonWriter out, final T value)
throws IOException {
delegateAdapter.write(out, value);
}
@Override
public T read(final JsonReader in)
throws IOException {
// If the next token is a boolean
if ( in.peek() == JsonToken.BOOLEAN ) {
// and it's true
if ( in.nextBoolean() ) {
// then just report an unexpected `true` literal
throw new MalformedJsonException("Expected a null value indicator as `false`. " + in);
}
// and it's false, then we assume it's a null
return null;
}
// Otherwise read the whole value as a usual
return delegateAdapter.read(in);
}
};
}
}一旦反序列化了问题中提供的JSON文档,toString-ed映射可能会产生如下内容:
Envelope{genetics=Genetics{names=null, ucpc=null, link=null}}
Envelope{genetics=Genetics{names=Blueberry x Haze, ucpc=W74AFGH22Z000000000000000 x 9XVU7WJQCD000000000000000, link=https://www.cannabisreports.com/api/v1.0/strains/9XVU7PTG2P000000000000000/genetics}} 发布于 2018-04-30 09:37:43
因为您已经知道您将拥有一个boolean或String,所以您可以直接获得一个JsonPrimitive。
原语值要么是字符串、Java原语,要么是Java原语包装器类型。
然后,从JsonPrimitive实例中,您可以检查它是否为isBoolean。
下面是如何在一个小片段中使用它
public static String getURL(JsonObject json, String value){
JsonPrimitive data = json.get(value).getAsJsonPrimitive();
if(data.isBoolean()){
return "Boolean : " + data.getAsBoolean();
} else {
return "String : " + data.getAsString();
}
}下面是一个验证此逻辑的快速示例
public static void main(String[] args) {
String data =
"{"
+ " \"element\" : {"
+ " \"a\":false,"
+ " \"b\":\"foobar\""
+ " }"
+ "}";
JsonObject json = new JsonParser().parse(data).getAsJsonObject();
JsonObject element = json.get("element").getAsJsonObject();
System.out.println(getURL(element, "a"));
System.out.println(getURL(element, "b"));
}布尔值:假 弦乐:狐尾
json说:
{
"element" :{
"a":false,
"b":"foobar"
}
}https://stackoverflow.com/questions/50097025
复制相似问题