问题描述
[
{
"key": "firstName","value": "John"
},{
"key": "lastName","value": "Smith"
}
]
我想反序列化数组,以便每个键都是一个属性名称,并分配适当的值。
public class Customer {
private String firstName;
private String lastName;
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
我曾想过创建一个自定义反序列化器来接受一组客户属性,并根据属性名称手动设置每个属性。我担心的是,随着添加更多属性,这种方法可能会变得脆弱,并且无法长期维护。
有谁知道我可能忽略的任何有助于反序列化的 Jackson 注释?
解决方法
只需用 @JsonProperty
注释属性
public class Customer {
@JsonProperty("key")
private String firstName;
@JsonProperty("value")
private String lastName;
....
}
如果你想在序列化过程中保留名称,你应该注释 setter 和 getter 而不是字段。
这是一个例子:Different names of JSON property during serialization and deserialization
,这可以通过 Jackson 以一种非常通用的方式解决。
首先,您需要一个小的 Java 类来表示任何
键/值对(例如 {"key":"firstName","value":"John"}
)
来自您的 JSON 输入。我们称之为Entry
。
public class Entry {
private String key;
private Object value;
// getters and setters (omitted here for brevity)
}
使用上面的类可以反序列化 JSON 输入
(如您的问题中给出的)到一组 Entry
对象。
ObjectMpper objectMapper = new ObjectMapper();
File file = new File("example.json");
Entry[] entries = objectMapper.readValue(file,Entry[].class);
然后你可以把这个Entry[]
数组转换成一个Map<String,Object>
,
并进一步到 Customer
对象
(使用您的问题中给出的 Customer
类)。
Map<String,Object> map = Arrays.stream(entries)
.collect(Collectors.toMap(Entry::getKey,Entry::getValue));
Customer customer = objectMapper.convertValue(map,Customer.class);
,
Jackson
将能够从 POJO
或 JSON Object
反序列化 Map
。您有一个 mini-Map 列表,其中每个 mini-Map 只包含一个属性。您需要:
- 将输入负载反序列化为
List<Map<String,Object>>
- 将其转换为单个
Map
对象 - 转换为
Customer
实例
简单例子:
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class JsonMiniMapsApp {
public static void main(String[] args) throws IOException {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
// read as list of maps
List<Map<String,Object>> entries = mapper.readValue(jsonFile,new TypeReference<List<Map<String,Object>>>() {
});
// collect all values to single map
Map<Object,Object> map = entries.stream().collect(Collectors.toMap(e -> e.get("key"),e -> e.get("value")));
// convert to POJO
Customer customer = mapper.convertValue(map,Customer.class);
System.out.println(customer);
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
class Customer {
private String firstName;
private String lastName;
}
以上代码打印:
Customer(firstName=John,lastName=Smith)