我需要将某些属性设置为子对象的平面JSON对象反序列化为Java对象。
{
"name": "abcd",
"addressLine1": "123",
"addressLine2": "1111"
}
Class Student {
String name;
Address address;
}
Class Address {
String line1;
String line2;
}
如何使用Jackson将我的JSON反序列化为Student
对象?
我无法映射addressLine1 to Student.Address.line1
和addressLine2 to Student.Address.line2
答案 0 :(得分:3)
您可以通过以下方式定义数据类:
spring.datasource.url=jdbc:mysql://localhost:3306/db_name
spring.datasource.username=root
spring.datasource.password=
spring.datasource.testWhileIdle=true
spring.datasource.validationQuery = SELECT 1
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialact=org.hibernate.dialact.MySQL5Dialact
然后,您可以按通常的方式使用 public static class Student {
String name;
@JsonUnwrapped
Address address;
}
public static class Address {
@JsonProperty("addressLine1")
String line1;
@JsonProperty("addressLine2")
String line2;
}
-无需任何其他技巧或解决方法:
Objectmapper
如果传入的json字符串确实是您提供的格式(不带引号),则还要添加:
Student student = mapper.readValue(json, Student.class);
答案 1 :(得分:1)
编辑:当我的解决方案有效时,塞林德克的答案是最好的
根据https://jsonlint.com/,您的Json无效,原因有两个:
我将使用带有未引用字段名称的JSON:
{
name: "abcd",
addressLine1: "123",
addressLine2: "1111"
}
我可以想到2种方法:
1-简单的地图处理
// Create your mapper, and configure it to allow unquoted field names
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// Parse the JSON to a Map
TypeReference<HashMap<String, String>> typeRef
= new TypeReference<HashMap<String, String>>() {};
Map<String, String> jsonAsMap = null;
try {
jsonAsMap = mapper.readValue(yourJsonString, typeRef);
} catch (Exception e) {
System.out.println("Something went wrong:" + e.getMessage());
}
// Read the data from the map and build your objects
Student student = null;
if(jsonAsMap != null) {
Address address = new Address();
address.setLine1(jsonAsMap.get("addressLine1"));
address.setLine2(jsonAsMap.get("addressLine2"));
student = new Student();
student.setName(jsonAsMap.get("name"));
student.setAddress(address);
System.out.println(student.getName());
System.out.println(student.getAddress().getLine1());
System.out.println(student.getAddress().getLine2());
}
2-使用代理对象(我希望使用该对象)
另一种方法是拥有一个代理类,您可以在其中反序列化JSON并由此构建您的学生:
class RawStudent {
private String name, addressLine1, addressLine2;
public Student toStudent() {
Address address = new Address();
address.setLine1(addressLine1);
address.setLine2(addressLine2);
Student student = new Student();
student.setName(name);
student.setAddress(address);
return student;
}
// GETTERS / SETTERS
}
并以这种方式使用它:
// Create your mapper, and configure it to allow unquoted field names
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
// Parse the JSON to a RawStudent object
RawStudent rawStudent = null;
try {
rawStudent = mapper.readValue(jsonUnquoted, RawStudent.class);
} catch (Exception e) {
System.out.println("Something went wrong:" + e.getMessage());
}
// Read the data from the map and build your objects
Student student = null;
if (rawStudent != null) {
student = rawStudent.toStudent();
System.out.println(student.getName());
System.out.println(student.getAddress().getLine1());
System.out.println(student.getAddress().getLine2());
}
注意
如果您输入错误并且确实有带引号的字段,即:
{
"name": "abcd",
"addressLine1": "123",
"addressLine2": "1111"
}
那你就不需要那一行
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
答案 2 :(得分:0)
在进行所有操作之前,请确保您的依赖项或库中有jackson-databind。
这是您可以做的:
String jsonInput = // You JSON String here;
TypeReference<HashMap<String, String>> typeRef
= new TypeReference<HashMap<String, String>>() {};
Map<String, String> map = mapper.readValue(jsonInput, typeRef);
Student student = new Student();
Address address = new Address();
for (Map.Entry<String, String> entry : map.entrySet())
{
if(((String)entry.getKey()).equals("addressLine1")){
student.setName(map.get("name"));
student.setAddress(map.get("addressLine1"));
}
if(((String)entry.getKey()).equals("addressLine2")){
address.setLine1(map.get("addressLine1"));
address.setLine2(map.get("addressLine2"));
}
//System.out.println(entry.getKey() + "/" + entry.getValue());
}
在类对象中直接反序列化将意味着Class和Json字符串具有完全相同的属性。这里不是cas。因此,for的循环和变量的利用。
阅读this了解更多详细信息
答案 3 :(得分:0)
您可以像这样使用ObjectMapper:
ObjectMapper objectMapper = new ObjectMapper();
Student student = objectMapper.readValue(json, Student.class);
但是您还必须按如下所示修改Student类,并实现所有的getter和setter方法:
Class Student{
String name;
String addressLine1;
String addressLine2;
}
然后,如果需要,可以根据需要将其重构为新类。希望能帮助到你。