Java 使用Google严格解析JSON';是格森吗?

Java 使用Google严格解析JSON';是格森吗?,java,serialization,gson,json,Java,Serialization,Gson,Json,假设我使用Google的Gson库将JSON解析为Java数据结构 如果存在没有相应JSON的Java字段,是否有一种简单的方法来抛出异常?也就是说,我希望要求JSON具有Java结构中的所有字段。Gson没有JSON模式验证功能来指定必须存在特定元素,也没有方法指定必须填充Java成员。如果有这样一个功能可用,比如带有@Required注释,那就太好了。前往并提出增强请求 使用Gson,您可以强制指定的JSON元素与自定义反序列化器一起出现 // output: // [MyObject

假设我使用Google的Gson库将JSON解析为Java数据结构


如果存在没有相应JSON的Java字段,是否有一种简单的方法来抛出异常?也就是说,我希望要求JSON具有Java结构中的所有字段。

Gson没有JSON模式验证功能来指定必须存在特定元素,也没有方法指定必须填充Java成员。如果有这样一个功能可用,比如带有
@Required
注释,那就太好了。前往并提出增强请求

使用Gson,您可以强制指定的JSON元素与自定义反序列化器一起出现

// output: 
//   [MyObject: element1=value1, element2=value2, element3=value3]
//   [MyObject: element1=value1, element2=value2, element3=null]
//   Exception in thread "main" com.google.gson.JsonParseException: Required Field Not Found: element2

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

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.JsonObject;
import com.google.gson.JsonParseException;

public class Foo
{
  static String jsonInput1 = "{\"element1\":\"value1\",\"element2\":\"value2\",\"element3\":\"value3\"}";
  static String jsonInput2 = "{\"element1\":\"value1\",\"element2\":\"value2\"}";
  static String jsonInput3 = "{\"element1\":\"value1\",\"element3\":\"value3\"}";

  public static void main(String[] args)
  {
    GsonBuilder gsonBuilder = new GsonBuilder();
    MyDeserializer deserializer = new MyDeserializer();
    deserializer.registerRequiredField("element2");
    gsonBuilder.registerTypeAdapter(MyObject.class, deserializer);
    Gson gson = gsonBuilder.create();
    MyObject object1 = gson.fromJson(jsonInput1, MyObject.class);
    System.out.println(object1);
    MyObject object2 = gson.fromJson(jsonInput2, MyObject.class);
    System.out.println(object2);
    MyObject object3 = gson.fromJson(jsonInput3, MyObject.class);
    System.out.println(object3);
  }
}

class MyObject
{
  String element1;
  String element2;
  String element3;

  @Override
  public String toString()
  {
    return String.format(
        "[MyObject: element1=%s, element2=%s, element3=%s]",
        element1, element2, element3);
  }
}

class MyDeserializer implements JsonDeserializer<MyObject>
{
  List<String> requiredFields = new ArrayList<String>();

  void registerRequiredField(String fieldName)
  {
    requiredFields.add(fieldName);
  }

  @Override
  public MyObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
      throws JsonParseException
  {
    JsonObject jsonObject = (JsonObject) json;
    for (String fieldName : requiredFields)
    {
      if (jsonObject.get(fieldName) == null)
      {
        throw new JsonParseException("Required Field Not Found: " + fieldName);
      }
    }
    return new Gson().fromJson(json, MyObject.class);
  }
}
//输出:
//[MyObject:element1=value1,element2=value2,element3=value3]
//[MyObject:element1=value1,element2=value2,element3=null]
//线程“main”com.google.gson.JsonParseException中出现异常:未找到必需字段:element2
导入java.lang.reflect.Type;
导入java.util.ArrayList;
导入java.util.List;
导入com.google.gson.gson;
导入com.google.gson.GsonBuilder;
导入com.google.gson.JsonDeserializationContext;
导入com.google.gson.JsonDeserializer;
导入com.google.gson.JsonElement;
导入com.google.gson.JsonObject;
导入com.google.gson.JsonParseException;
公开课Foo
{
静态字符串jsonInput1=“{\'element1\':\'value1\',\'element2\':\'value2\',\'element3\':\'value3\'”;
静态字符串jsonInput2=“{\'element1\':\'value1\',\'element2\':\'value2\'”;
静态字符串jsonInput3=“{\'element1\':\'value1\',\'element3\':\'value3\'”;
公共静态void main(字符串[]args)
{
GsonBuilder GsonBuilder=新的GsonBuilder();
MyDeserializer反序列化程序=新建MyDeserializer();
registerRequiredField(“element2”);
registerTypeAdapter(MyObject.class,反序列化程序);
Gson-Gson=gsonBuilder.create();
MyObject object1=gson.fromJson(jsonInput1,MyObject.class);
System.out.println(object1);
MyObject object2=gson.fromJson(jsonInput2,MyObject.class);
System.out.println(object2);
MyObject object3=gson.fromJson(jsonInput3,MyObject.class);
System.out.println(object3);
}
}
类MyObject
{
字符串元素1;
字符串元素2;
弦元素3;
@凌驾
公共字符串toString()
{
返回字符串格式(
[MyObject:element1=%s,element2=%s,element3=%s],
要素1、要素2、要素3);
}
}
类MyDeserializer实现JsonDeserializer
{
List requiredFields=new ArrayList();
无效registerRequiredField(字符串字段名)
{
必填字段。添加(字段名);
}
@凌驾
公共MyObject反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)
抛出JsonParseException
{
JsonObject JsonObject=(JsonObject)json;
for(字符串字段名:requiredFields)
{
if(jsonObject.get(fieldName)==null)
{
抛出新的JsonParseException(“未找到必需字段:“+fieldName”);
}
}
返回新的Gson().fromJson(json,MyObject.class);
}
}
更好的方法可能是使用提供验证的API。看起来有一个更成熟的

这里有一个杰克逊的例子

// output: 
// Validating jsonInput1...
// Validating jsonInput2...
// Validating jsonInput3...
// $.element2: is missing and it is not optional
// [MyObject: element1=value1, element2=value2, element3=value3]
// [MyObject: element1=value1, element2=value2, element3=null]
// [MyObject: element1=value1, element2=null, element3=value3]

import java.util.List;

import org.codehaus.jackson.map.ObjectMapper;

import eu.vahlas.json.schema.JSONSchema;
import eu.vahlas.json.schema.JSONSchemaProvider;
import eu.vahlas.json.schema.impl.JacksonSchemaProvider;

public class Foo
{
  static String jsonSchema = 
    "{" + 
        "\"description\":\"Serialized MyObject Specification\"," + 
        "\"type\":[\"object\"]," + 
        "\"properties\":" + 
        "{" + 
            "\"element1\":{\"type\":\"string\"}," + 
            "\"element2\":{\"type\":\"string\",\"optional\":false}," + 
            "\"element3\":{\"type\":\"string\",\"optional\":true}" + 
        "}" + 
    "}";;

  static String jsonInput1 = "{\"element1\":\"value1\",\"element2\":\"value2\",\"element3\":\"value3\"}";
  static String jsonInput2 = "{\"element1\":\"value1\",\"element2\":\"value2\"}";
  static String jsonInput3 = "{\"element1\":\"value1\",\"element3\":\"value3\"}";

  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    JSONSchemaProvider schemaProvider = new JacksonSchemaProvider(mapper);
    JSONSchema schema = schemaProvider.getSchema(jsonSchema);

    System.out.println("Validating jsonInput1...");
    validateAndLogErrors(jsonInput1, schema);
    System.out.println("Validating jsonInput2...");
    validateAndLogErrors(jsonInput2, schema);
    System.out.println("Validating jsonInput3...");
    validateAndLogErrors(jsonInput3, schema);

    MyObject object1 = mapper.readValue(jsonInput1, MyObject.class);
    System.out.println(object1);
    MyObject object2 = mapper.readValue(jsonInput2, MyObject.class);
    System.out.println(object2);
    MyObject object3 = mapper.readValue(jsonInput3, MyObject.class);
    System.out.println(object3);
  }

  static void validateAndLogErrors(String jsonInput, JSONSchema schema)
  {
    List<String> errors = schema.validate(jsonInput);
    for (String error : errors)
    {
      System.out.println(error);
    }
  }
}

class MyObject
{
  String element1;
  String element2;
  String element3;

  void setElement1(String element1)
  {
    this.element1 = element1;
  }

  void setElement2(String element2)
  {
    this.element2 = element2;
  }

  void setElement3(String element3)
  {
    this.element3 = element3;
  }

  @Override
  public String toString()
  {
    return String.format(
        "[MyObject: element1=%s, element2=%s, element3=%s]",
        element1, element2, element3);
  }
}
//输出:
//正在验证jsonInput1。。。
//正在验证jsonInput2。。。
//正在验证jsonInput3。。。
//$.element2:缺少,它不是可选的
//[MyObject:element1=value1,element2=value2,element3=value3]
//[MyObject:element1=value1,element2=value2,element3=null]
//[MyObject:element1=value1,element2=null,element3=value3]
导入java.util.List;
导入org.codehaus.jackson.map.ObjectMapper;
导入eu.vahlas.json.schema.JSONSchema;
导入eu.vahlas.json.schema.JSONSchemaProvider;
导入eu.vahlas.json.schema.impl.JacksonSchemaProvider;
公开课Foo
{
静态字符串jsonSchema=
"{" + 
“\”说明\“:\”序列化MyObject规范\“,“+
“\”类型\“:[\”对象\“],“+
“\”属性\“:“+
"{" + 
“\'element1\':{\'type\':\'string\'},”+
“\'element2\':{\'type\':\'string\',\'optional\':false},”+
“\'element3\':{\'type\':\'string\',\'optional\':true}”+
"}" + 
"}";;
静态字符串jsonInput1=“{\'element1\':\'value1\',\'element2\':\'value2\',\'element3\':\'value3\'”;
静态字符串jsonInput2=“{\'element1\':\'value1\',\'element2\':\'value2\'”;
静态字符串jsonInput3=“{\'element1\':\'value1\',\'element3\':\'value3\'”;
公共静态void main(字符串[]args)引发异常
{
ObjectMapper mapper=新的ObjectMapper();
JSONSchemaProvider schemaProvider=新JacksonSchemaProvider(映射器);
JSONSchema schema=schemaProvider.getSchema(JSONSchema);
System.out.println(“正在验证jsonInput1…”);
验证数据日志(jsonInput1,模式);
System.out.println(“正在验证jsonInput2…”);
验证数据日志(jsonInput2,模式);
System.out.println(“正在验证jsonInput3…”);
验证数据日志(jsonInput3,模式);
MyObject object1=mapper.readValue(jsonInput1,MyObject.class);
System.out.println(object1);
MyObject object2=mapper.readValue(jsonInput2,MyObject.class);
System.out.println(object2);
MyObject object3=mapper.readValue(jsonInput3,MyObject.class);
System.out.println(object3);
}
静态void validateAndLogErrors(字符串jsonInput、JSONSchema模式)
{
List errors=schema.validate(jsonInput);
for(字符串错误:错误)
{
系统输出打印项次(错误);
}
}
}
类MyObject
{
字符串元素1;
字符串元素2;
弦元素3;
无效集合元素1(字符串元素1)
{
this.element1=element1;
}
无效集合元素2(字符串元素2)
{
this.element2=element2;
}
无效集合元素3(字符串元素3)
{
this.element3=element3;
}
@凌驾
公共字符串toString()
{
返回字符串格式(
 private static List<String> verifyElement(JsonObject element, Class klass) throws NoSuchFieldException, IllegalAccessException {
  List<String> unknownFields = new ArrayList<>();
  Set<String> classFields = new HashSet<>();

  for (Field field : klass.getDeclaredFields()) {
    if (!Modifier.isPublic(field.getModifiers())) {
      throw new IllegalArgumentException("All fields must be public. Please correct this field :" + field);
    }
  }

  for (Field field : klass.getFields()) {
    classFields.add(field.getName());
  }

  // Verify recursively that the class contains every
  for (Map.Entry<String, JsonElement> entry : element.entrySet()) {
    if (!classFields.contains(entry.getKey())) {
      unknownFields.add(klass.getCanonicalName() + "::" + entry.getKey() + "\n");
    } else {
      Field field = klass.getField(entry.getKey());
      Class fieldClass = field.getType();
      if (!fieldClass.isPrimitive() && entry.getValue().isJsonObject()) {
        List<String> elementErrors = verifyElement(entry.getValue().getAsJsonObject(), fieldClass);
        unknownFields.addAll(elementErrors);
      }
    }
  }
  return unknownFields;

}