Java 在反序列化过程中强制Jackson/Gson在属性执行';不存在
我有Java 在反序列化过程中强制Jackson/Gson在属性执行';不存在,java,jackson,gson,json-deserialization,jackson2,Java,Jackson,Gson,Json Deserialization,Jackson2,我有JSON: {"name": "testname"} 和具有数千个属性的java类: public class Ui { public String name; public String title; } class Ui { private String name; private String title; @JsonCreator public Ui(@JsonProperty(required = true, value = "
JSON
:
{"name": "testname"}
和具有数千个属性的java类:
public class Ui {
public String name;
public String title;
}
class Ui {
private String name;
private String title;
@JsonCreator
public Ui(@JsonProperty(required = true, value = "name") String name, @JsonProperty(required = true, value = "title") String title) {
this.name = name;
this.title = title;
}
//....
}
在反序列化过程中,Jackson
或Gson
应返回null
或引发异常,因为给定的JSON
中不存在title属性。如何强迫这种行为
杰克逊的例子:
ObjectMapper objectMapper = new ObjectMapper();
Ui ui = objectMapper.readValue("{\"name": "testname\"}", Ui.class);
System.out.println(ui == null); // should be true
使用gson,它不会出现任何问题,只会设置name的值
public class SO_50688866 {
public static void main(String ... args) {
String json = "{\"name\": \"testname\"}";
Ui ui = new Gson().fromJson(json, Ui.class);
System.out.println(ui.name);
}
public static class Ui {
public String name;
public String title;
}
}
编辑I
我看你想要的正好相反:)
我不认为gson在本机上支持这一点,但我发现这个答案可以满足您的需求:
我还提出了这个类,它可以在反序列化json字符串后检查字段。
它有一些警告,比如如果缺少一个原语,比如int,它将被初始化为零,这样它就不会为null。或者如果字段在json中为空,则有效。
但也许您可以根据自己的需要对其进行调整,比如添加一个方法,该方法采用要检查的字段的名称
public static class CheckNullFields<T>{
@SuppressWarnings("unchecked")
public void check(T obj) throws IllegalAccessException{
Class<T> clazz = (Class<T>) obj.getClass();
Field [] fields = clazz.getDeclaredFields();
for(Field field : fields) {
if(field.get(obj) == null) {
throw new RuntimeException("Null value in field " + field.getName());
}
}
}
}
公共静态类CheckNullFields{
@抑制警告(“未选中”)
公共无效检查(T obj)引发非法访问异常{
类clazz=(类)obj.getClass();
Field[]fields=clazz.getDeclaredFields();
用于(字段:字段){
if(field.get(obj)==null){
抛出新的RuntimeException(“field中的Null值”+field.getName());
}
}
}
}
您可以这样使用它:
String json = "{\"name\": \"testname\"}";
try {
Ui ui = new Gson().fromJson(json, Ui.class);
new CheckNullFields<Ui>().check(ui);
System.out.println(ui.name);
System.out.println(ui.title);
}catch(Exception e) {
e.printStackTrace();
}
String json=“{\“name\”:\“testname\”}”;
试一试{
Ui=new Gson().fromJson(json,Ui.class);
新建CheckNullFields()。检查(ui);
System.out.println(ui.name);
System.out.println(ui.title);
}捕获(例外e){
e、 printStackTrace();
}
您必须创建一个需要所有必需属性的构造函数:
public class Ui {
public String name;
public String title;
}
class Ui {
private String name;
private String title;
@JsonCreator
public Ui(@JsonProperty(required = true, value = "name") String name, @JsonProperty(required = true, value = "title") String title) {
this.name = name;
this.title = title;
}
//....
}
同样的例子给出:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Missing required creator property 'title' (index 1)
at [Source: {"name": "name"}; line: 1, column: 16]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
另外,请查看以下问题和答案:
编辑如果您有数千个属性(这很奇怪,但也有可能),简单的解决方案是将
JSON
反序列化为Map
,并检查其大小。如果大小与预期不同,则可以抛出新异常或返回null
我认为最好的方法是为您的
JSON
生成JSON模式
,并首先尝试验证它 Ui类没有constructors@elronsmith,如果您无法创建构造函数,则必须手动编写该检查或创建JSON模式
。如果JSON没有标题参数,则Gson应将null返回到Ui。怎么做?