首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当期望GSON中的字符串时,如何处理布尔值?

当期望GSON中的字符串时,如何处理布尔值?
EN

Stack Overflow用户
提问于 2018-04-30 08:51:25
回答 2查看 729关注 0票数 0

我目前正在开发一个第三方REST。我正在为API返回的JSON对象创建对象。我正在跟踪他们的文档,其中说某些变量将是String。有时,当没有字符串时,它将返回False。有时,我期待一个URL,我得到假的。

我该怎么处理?

这是问题中的API https://developers.cannabisreports.com/docs/

应变对象示例:https://ghostbin.com/paste/kgeau中的应变对象,我在执行搜索时得到一个异常。搜索的一些结果是布尔值,而不是注释掉的代码中的字符串/url。

有时候我会明白

代码语言:javascript
复制
"genetics": {
            "names": false,
            "ucpc": false,
            "link": false
        }

有时候我能拿到这个

代码语言:javascript
复制
"genetics": {
            "names": "Blueberry x Haze",
            "ucpc": "W74AFGH22Z000000000000000 x 9XVU7WJQCD000000000000000",
            "link": "https:\/\/www.cannabisreports.com\/api\/v1.0\/strains\/9XVU7PTG2P000000000000000\/genetics"
        }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-04-30 09:49:25

当您遇到设计不好的API时,Gson在反序列化由这样一个API生成的JSON文档时提供了一些灵活性。尽管您有很多方法来解决这个问题(比如JsonDeserializer,等等),但是您最喜欢面对的是我在这里已经看到的虚假为空的问题。您可以通过标记“错误”字段来帮助Gson:

代码语言:javascript
复制
final class Envelope {

    final Genetics genetics = null;

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("genetics", genetics)
                .toString();
    }

}
代码语言:javascript
复制
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();
    }

}

类型适配器工厂就是这样实现的:

代码语言:javascript
复制
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映射可能会产生如下内容:

代码语言:javascript
复制
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}}  
票数 2
EN

Stack Overflow用户

发布于 2018-04-30 09:37:43

因为您已经知道您将拥有一个booleanString,所以您可以直接获得一个JsonPrimitive

原语值要么是字符串、Java原语,要么是Java原语包装器类型。

然后,从JsonPrimitive实例中,您可以检查它是否为isBoolean

下面是如何在一个小片段中使用它

代码语言:javascript
复制
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();
    }
}

下面是一个验证此逻辑的快速示例

代码语言:javascript
复制
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说:

代码语言:javascript
复制
{
    "element" :{
        "a":false,
        "b":"foobar"
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50097025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档