在GSON中期望字符串时如何处理布尔值? [英] How to handle a Boolean when expecting a String in GSON?
问题描述
我目前正在使用第三方REST API进行开发.我正在为API返回的JSON对象创建对象.我正在关注他们的文档,其中说某些变量将是字符串.有时,当没有String时,它将返回False.有时我期待一个URL,但我得到False.
I am currently developing with a 3rd party REST API. I am creating objects for their JSON objects being returned by the API. I am following their documentation where it says certain variables will be Strings. Sometimes when there is no String, it will return False. Sometimes I'm expecting a URL and I get False.
我该如何处理?
这是有问题的API, https://developers.cannabisreports.com/docs/
This is the API in question https://developers.cannabisreports.com/docs/
应变对象示例: https://ghostbin.com/paste/kgeau 在应变对象"中,执行搜索时出现异常.搜索的某些结果在注释掉的代码位中使用布尔值而不是字符串/url.
Strain Object EXAMPLE: https://ghostbin.com/paste/kgeau In the Strain Object, I get an exception when performing a search. Some of the results of the search have booleans instead of strings/url in the bits of code that are commented out.
有时候我明白了
"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"
}
推荐答案
当您遇到一个设计得不太好的API的麻烦时,Gson在反序列化由该API生成的JSON文档时会为您提供一些灵活性.尽管您有许多解决此问题的方法(例如JsonDeserializer
等),但您大多数还是喜欢面对我似乎遇到过的 false-as-null 问题已经看到这里了.您可以通过标记错误"字段来帮助Gson:
When you're in trouble with not a very well designed API, Gson gives you some flexibility while deserializing JSON documents produced by such an API. Despite you have numerous ways to work around this issue (like JsonDeserializer
, etc), you mostly like are faced with the false-as-null issue I seem to have seen here already. You can help Gson by marking "wrong" fields:
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();
}
}
这是类型适配器工厂的实现方式:
And this is how the type adapter factory implemented:
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映射可能会产生以下内容:
Once you deserialize the JSON documents you provided in the question, a toString
-ed mapping might produce something like this:
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}}
这篇关于在GSON中期望字符串时如何处理布尔值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!