检查json属性是否存在,是否为字符串,且值是否正确

时间:2017-01-31 08:52:45

标签: java json gson

使用gson,我使用这种繁琐的方法来确保所需的属性具有所需的值:

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class ScratchSpace {

    public static void main(String[] args) {

        // create json object from source data - in my real code, this is sourced externally
        JsonObject json = new JsonParser().parse("{  \"product\": \"foobar\"}").getAsJsonObject();

        // does this object have a key called product, which is a string, and equal to our expected value?
        boolean correctProduct = false;
        if (json.has("product")) {
            JsonElement productElement = json.get("product");
            if (productElement.isJsonPrimitive()) {
                String product = productElement.getAsString();
                if ("foobar".equals(product)) {
                    correctProduct = true;
                }

            }
        }
        System.out.println("correctProduct = " + correctProduct);
    }

}

我几乎可以肯定我这样做不是很理想。是否有一个简单,可读,简短的单线程来实现相同的目标?

编辑:如果可能的话,我想继续使用gson。

3 个答案:

答案 0 :(得分:1)

使用java.util.Optional,以下作品:

final boolean correctProduct = Optional.ofNullable(json.get("product"))
            .filter(JsonPrimitive.class::isInstance)
            .map(JsonPrimitive.class::cast)
            .map(JsonPrimitive::getAsString)
            .filter("foobar"::equals)
            .isPresent();

答案 1 :(得分:0)

您可以编写自定义反序列化器,如this,注册它,并使用fromJson方法直接从json字符串获取对象。这样,如果json字符串不是预期的格式,您可以返回null或在反序列化器中抛出异常。

请注意,您不必单独设置每个字段。执行自定义检查后,您可以使用context中的默认反序列化。

编辑:如果您只想获得true / false而不是完整的对象,那么您可以编写一个MyBoolean类, boolean值并使用fromJson方法反序列化为MyBoolean类。自定义反序列化器将仅执行所需的检查并适当地设置MyBoolean实例的内容。此外,(我猜)如果从布尔值扩展此MyBoolean,您也可以将其用作boolean

编辑2:我之前没有时间包含示例代码。以下是我的建议:

package io.ram.ram;

import java.lang.reflect.Type;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

public class Tester {

    public static class MyBoolean {
        private boolean value;

        public void set(boolean value) {
            this.value = value;
        }

        public boolean get() {
            return value;
        }
    }

    public static class MyAdapter implements JsonDeserializer<MyBoolean> {

        public MyBoolean deserialize(JsonElement json, Type type, JsonDeserializationContext context)
                throws JsonParseException {
            MyBoolean result = new MyBoolean();
            result.set(false);

            try {
                result.set(json.getAsJsonObject().get("product").getAsString().equals("foobar"));
            } catch (Exception e) {

            }
            return result;
        }

    }

    public static void main(String[] args) {
        Gson gson = new GsonBuilder().registerTypeAdapter(MyBoolean.class, new MyAdapter()).create();

        System.out.println(gson.fromJson("{\"product\": \"foobar\"}", MyBoolean.class).get());
        System.out.println(gson.fromJson("{\"product\": \"foobaz\"}", MyBoolean.class).get());
    }

}

正如我所说,在为自定义序列化注册类型适配器后,您可以通过一行实现所需的功能。 (注意:布尔类是最终的,所以我们不能扩展它。抱歉这个错误的信息。)

当然,您可以为字符串MyAdapter"product"参数化"foobar",因此您不必为每种可能的情况创建此类。

答案 2 :(得分:0)

我知道你说GSON,但杰克逊提供的基于pojo的方法让你想做的事情太方便而不发布:

简单的pojo:

public class FooPojo {
    @JsonProperty
    private String product;

    public String getProduct() {
        return product;
    }

    public void setProduct(String product) {
        this.product = product;
    }

    public boolean isProductEqualTo(String check) {
        return product.equals(check);
    }
}

解析并检查:

public static void main(String[] args) throws IOException {
    ObjectMapper objectMapper = new ObjectMapper();
    FooPojo fooPojo = objectMapper.readValue("{  \"product\": \"foobar\"}", FooPojo.class);
    System.out.println(fooPojo.isProductEqualTo("foobar"));
}