SDe*_*kov 2 java json jackson deserialization
如果你有一个班级User:
class User {
private String firstName;
private String lastName;
private Address address; //object
}
Run Code Online (Sandbox Code Playgroud)
和一个类Address分别:
class Address {
private String streetName;
private String postCode;
private AddressType addressType; //enum
}
Run Code Online (Sandbox Code Playgroud)
以及为两者定制的 Jackson 反序列化器,是否有链接它们的好方法?例如
class UserDeserialiser extends JsonDeserializer<User> {
public User deserialize(JsonParser jp, DeserializationContext ctxt) {
ObjectNode node = jp.getCodec().readTree(jp);
User user = fetchUser();
user.setFirstName(node.get("firstName").asText());
user.setFirstName(node.get("lastName").asText());
user.setAddress(???); // delegate to AddressDeserialiser here
}
}
Run Code Online (Sandbox Code Playgroud)
同样在地址反序列化器中,是否可以委托默认的来处理枚举(因为它可能具有自定义映射)?
class AddressDeserialiser extends JsonDeserializer<Address> {
public User deserialize(JsonParser jp, DeserializationContext ctxt) {
ObjectNode node = jp.getCodec().readTree(jp);
Address user = fetchAddress();
user.setStreetName(node.get("streetName").asText());
user.setAddressType(???); // delegate to jackson default object mapper?
}
}
Run Code Online (Sandbox Code Playgroud)
不久前我也有同样的需求,并想出了一个解决方案。我不认为这是一个“不错”的解决方案,因为它有点笨拙,但也许这会鼓励某人写出更好的答案。那很好啊。
正如评论中提到的,这通常可以通过使用注释来解决。具体来说,@JacksonDeserialize注释。
但是,如果(无论出于何种原因 - 并且有很多可能的原因)不希望使用注释,则有必要为 JSON 树的相关子树显式创建解析器。这将选择默认解串器或已在对象映射器模块中为相应类型注册的自定义解串器。
参考您的示例的相关部分/模式,即包含???问号的点,是这样的:
JsonNode addressNode = node.get("address");
if (addressNode != null)
{
JsonParser parser = addressNode.traverse();
parser.setCodec(jp.getCodec());
Address address = parser.readValueAs(Address.class);
user.setAddress(address);
}
Run Code Online (Sandbox Code Playgroud)
这是一个MCVE,显示了这种方法的实际效果:
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ObjectNode;
class UserDeserialiser extends JsonDeserializer<User>
{
@Override
public User deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
System.out.println("Deserializing User...");
ObjectNode node = jp.getCodec().readTree(jp);
User user = new User();
user.setFirstName(node.get("firstName").asText());
user.setLastName(node.get("lastName").asText());
JsonNode addressNode = node.get("address");
if (addressNode != null)
{
JsonParser parser = addressNode.traverse();
parser.setCodec(jp.getCodec());
Address address = parser.readValueAs(Address.class);
user.setAddress(address);
}
return user;
}
}
class AddressDeserialiser extends JsonDeserializer<Address>
{
@Override
public Address deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
System.out.println("Deserializing Address...");
ObjectNode node = jp.getCodec().readTree(jp);
Address address = new Address();
address.setStreetName(node.get("streetName").asText());
address.setPostCode(node.get("postCode").asText());
JsonNode addressTypeNode = node.get("addressType");
if (addressTypeNode != null)
{
JsonParser parser = addressTypeNode.traverse();
parser.setCodec(jp.getCodec());
Address.AddressType addressType =
parser.readValueAs(Address.AddressType.class);
address.setAddressType(addressType);
}
return address;
}
}
public class NestedDeserializers
{
public static void main(String[] args) throws IOException
{
User user = new User();
user.setFirstName("A");
user.setLastName("B");
Address address = new Address();
address.setStreetName("C");
address.setPostCode("D");
address.setAddressType(Address.AddressType.X);
user.setAddress(address);
ObjectMapper mapper = createObjectMapper();
String jsonString = mapper.writeValueAsString(user);
System.out.println("JSON string representation:\n" + jsonString);
User readUser = mapper.readValue(jsonString, User.class);
System.out.println("User : " + user);
System.out.println("Read user: " + readUser);
}
private static ObjectMapper createObjectMapper()
{
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
SimpleModule module = new SimpleModule();
module.addDeserializer(User.class, new UserDeserialiser());
module.addDeserializer(Address.class, new AddressDeserialiser());
mapper.registerModule(module);
return mapper;
}
}
//=============================================================================
// Dummy User/Address classes below
class User
{
private String firstName;
private String lastName;
private Address address;
public String getFirstName()
{
return firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public String getLastName()
{
return lastName;
}
public void setLastName(String lastName)
{
this.lastName = lastName;
}
public Address getAddress()
{
return address;
}
public void setAddress(Address address)
{
this.address = address;
}
@Override
public String toString()
{
return "User [firstName=" + getFirstName() + ", lastName="
+ getLastName() + ", address=" + getAddress() + "]";
}
}
class Address
{
enum AddressType
{
X, Y;
}
private String streetName;
private String postCode;
private AddressType addressType;
public String getStreetName()
{
return streetName;
}
public void setStreetName(String streetName)
{
this.streetName = streetName;
}
public String getPostCode()
{
return postCode;
}
public void setPostCode(String postCode)
{
this.postCode = postCode;
}
public AddressType getAddressType()
{
return addressType;
}
public void setAddressType(AddressType addressType)
{
this.addressType = addressType;
}
@Override
public String toString()
{
return "Address [streetName=" + getStreetName() + ", postCode="
+ getPostCode() + ", addressType=" + getAddressType() + "]";
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
614 次 |
| 最近记录: |