Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 检查json属性是否存在、是否为字符串以及值是否正确_Java_Json_Gson - Fatal编程技术网

Java 检查json属性是否存在、是否为字符串以及值是否正确

Java 检查json属性是否存在、是否为字符串以及值是否正确,java,json,gson,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

使用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。

使用
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();

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

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

编辑:如果只想获得
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());
    }

}
包io.ram.ram;
导入java.lang.reflect.Type;
导入com.google.gson.gson;
导入com.google.gson.GsonBuilder;
导入com.google.gson.JsonDeserializationContext;
导入com.google.gson.JsonDeserializer;
导入com.google.gson.JsonElement;
导入com.google.gson.JsonParseException;
公共类测试员{
公共静态类MyBoolean{
私有布尔值;
公共无效集(布尔值){
这个值=值;
}
公共布尔get(){
返回值;
}
}
公共静态类MyAdapter实现JsonDeserializer{
公共MyBoolean反序列化(JsonElement json,类型类型,JsonDeserializationContext)
抛出JsonParseException{
MyBoolean结果=新的MyBoolean();
result.set(假);
试一试{
set(json.getAsJsonObject().get(“product”).getAsString().equals(“foobar”));
}捕获(例外e){
}
返回结果;
}
}
公共静态void main(字符串[]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());
}
}
正如我所说,在为自定义序列化注册类型适配器之后,您可以通过一行代码实现所需的功能。(注意:布尔类是最终类,因此我们无法扩展它。对于此错误信息,我们深表歉意。)


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

我知道您说过GSON,但jackson提供的基于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"));
}

使用流是一种有趣的方法;我希望gson也能有一些方便的方法来实现这一点。实际上,
javax.json.JsonObject
有一个
getString
方法,如果该值不是
String
,则可能会有一个默认值,但显然,谷歌创建了自己的数据模型…;-)注:如果更多的开发人员从“出错时返回null”转向“返回可选”方案,我将表示欢迎。@Smutje AFAIR,JSON处理在Java 7之前就已经引入Java 8及其可选项,而Gson最初是在2008年发布的,大约十年前,所以我认为javax.json的作者只是重新考虑了现有的库,比如Gson或Jackson。返回
null
更便宜,但是如果您更喜欢使用OneLiner,那么这种情况下就不太方便了……好吧,这可以解释Java中JSON表示的差异。您是否查看过类似的查询库?我最近在
gson
中查找了相同的功能,但没有找到它