我得到了这个转义的JSON
"{\"UniqueId\":[],\"CustomerOffers\":{},\"Success\":false,\"ErrorMessages\":[\"Test Message\"],\"ErrorType\":\"GeneralError\"}"
,我需要使用Jackson将其转换为Java对象。
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.8'
我创建了课程:
public class Data {
private List<UUID> UniqueId;
private Map<Integer, List<Integer>> CustomerOffers;
private Boolean Success;
private List<String> ErrorMessages;
private String ErrorType;
// getter, setters
}
然后我创建了将其转换的方法
public class Deserializing {
public void processing(String input) {
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
String jsonInString = "\"{\"UniqueId\":[],\"CustomerOffers\":{},\"Success\":false,\"ErrorMessages\":[\"Test Message\"],\"ErrorType\":\"GeneralError\"}\"";
String newJSON = org.apache.commons.lang3.StringEscapeUtils.unescapeJava(jsonInString);
newJSON= newJSON.substring(1, jsonInString.length()-1);
try {
// JSON string to Java object
Data data = mapper.readValue(newJSON, Data.class);
System.out.println(data);
System.out.println("Get Success "+ data.getSuccess()); // return "false" if Data object is public ; null if private
System.out.println("Get UniqueID " + data.getUniqueId()); // return [] if Data object is public ; null if private
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果Data类中的任何变量设置为public,那么当我调用getter时,我都会得到the corresponding value
。
无论Data类中的哪个变量设置为private,那么我在调用getter时都会得到null
。
字母和二传手总是公开的。
我想知道,如果ObjectMapper设置为私有对象,为什么不能映射该对象?我可以将其设置为公开,但这不是最佳实践。
答案 0 :(得分:2)
问题在于,杰克逊将始终假设setSuccess()
和getSuccess()
将用于success
字段,而不是Success
。 @JsonProperty
需要支持以大写字母开头的JSON字段名称。 Java有一个约定,即类成员始终以小写字母开头,您可以使用此注释来实现这一点。
创建字段private
时,您迫使Jackson使用设置器,并且上述冲突使得无法正确反序列化Data
对象。
解决办法;
public class Data {
@JsonProperty("UniqueId")
private List<UUID> uniqueId;
@JsonProperty("CustomerOffers")
private Map<Integer, List<Integer>> customerOffers;
@JsonProperty("Success")
private Boolean success;
@JsonProperty("ErrorMessages")
private List<String> errorMessages;
@JsonProperty("ErrorType")
private String errorType;
// getter&setters
}
然后您将看到正确反序列化为Java对象的值;
Get success false
Get uniqueID []
答案 1 :(得分:1)
默认情况下,Jackson只会尝试序列化from_name(...)
类(或您要序列化/反序列化的任何类)上的公共字段。但是,您可以配置Data
以允许其对所有字段进行序列化,而不考虑可见性:
ObjectMapper
答案 2 :(得分:1)
在JavaBeans规范(构造Java类属性的通用指南)中,属性定义为以小写字母(errorMessages
)开头;访问器,因为它们有前缀,所以将其大写(getErrorMessages
)。杰克逊默认使用属性名称,因此,当您拥有方法getErrorMessages
时,它将查找具有键errorMessages
的JSON属性。
最好的方法是更改JSON;我见过样式errorMessages
和error_messages
,但从未见过ErrorMessages
。如果不能这样做,则可以将@JsonProperty
应用于属性,以告诉Jackson在JSON中使用其他名称。
答案 3 :(得分:0)
此外,还有一点要注意:在这种情况下,如果Data类包含任何带有参数的构造函数,并且不包含空构造函数。这样,对象映射器将无法映射相应的对象。因此,在这种情况下,它也会返回null。