Java 两个传入REST json的公共dto
我想创建一个通用dto,如下图所示,用于从REST服务接收传入的经理和员工详细信息Java 两个传入REST json的公共dto,java,json,jackson,marshalling,dto,Java,Json,Jackson,Marshalling,Dto,我想创建一个通用dto,如下图所示,用于从REST服务接收传入的经理和员工详细信息 public class Employee { @JsonProperty("name") public String name; @JsonProperty("designation") public String designation; @JsonProperty("item") public String item; @JsonPropert
public class Employee {
@JsonProperty("name")
public String name;
@JsonProperty("designation")
public String designation;
@JsonProperty("item")
public String item;
@JsonProperty("item")
public List<Item> items;
//setters and getters
}
员工入职json
{
"name": "Rohit",
"designation": "Manager",
"item": {"name": "ABC", "desc": "1234"}
}
{
"name": "Manu",
"designation": "Staff",
"item": "abc"
}
谁能告诉我一些解决方案吗?你可以创建一个客户反序列化程序。如果
“item”
字段的节点是数组,则将其反序列化为数组,否则将其反序列化为字符串。比如说
public static class EmployeeDeserializer extends JsonDeserializer<Employee> {
@Override
public Employee deserialize(JsonParser jp,
DeserializationContext dc)
throws IOException, JsonProcessingException {
Employee emp = new Employee();
JsonNode root = jp.getCodec().readTree(jp);
emp.name = root.get("name").asText();
emp.designation = root.get("designation").asText();
JsonNode itemNode = root.get("item");
if (itemNode.isArray()) {
ArrayNode itemsNode = (ArrayNode) itemNode;
List<Item> items = new ArrayList<>();
for (JsonNode iNode : itemsNode) {
Item item = new Item();
item.name = iNode.get("name").asText();
item.desc = iNode.get("desc").asText();
items.add(item);
}
emp.items = items;
} else if (itemNode.isObject()) {
List<Item> items = new ArrayList<>();
Item item = new Item();
item.name = itemNode.get("name").asText();
item.desc = itemNode.get("desc").asText();
items.add(item);
emp.items = items;
} else {
String item = root.get("item").asText();
emp.item = item;
}
return emp;
}
}
您可以让Manager和Staff扩展抽象类Employee,然后使用“designation”JSON属性来区分它们:
// note hashCode(), equals() and toString() methods left out for brevity!
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "designation")
@JsonSubTypes({ @JsonSubTypes.Type(Staff.class), @JsonSubTypes.Type(Manager.class) })
public static abstract class Employee {
@JsonProperty("name")
public String name;
public Employee(String name) {
this.name = name;
}
public Employee() {
}
}
@JsonTypeName("Manager")
public static final class Manager extends Employee {
@JsonProperty("item")
public List<Item> items;
public Manager(String name, List<Item> items) {
super(name);
this.items = items;
}
public Manager() {
}
public static final class Item {
public final String name;
public final String desc;
public Item(@JsonProperty("name") String name, @JsonProperty("desc") String desc) {
this.name = name;
this.desc = desc;
}
}
}
@JsonTypeName("Staff")
public static final class Staff extends Employee {
@JsonProperty("item")
public String item;
public Staff(String name) {
super(name);
this.item = item;
}
public Staff() {
}
}
这很好,可以在测试中使用,但是在junit中,您已经在
@BeforeClass
中注册了反序列化程序。如何在dto中注册反序列化程序以直接从REST服务进行编组您不必使用ObjectMapper
注册反序列化程序。您只需将@jsondeseerialize(使用=EmployeeDeserializer.class)
放在Employee
类的顶部即可。它也应该起作用。在测试中尝试一下。只要注释掉@BeforeClass
中的所有内容,除了创建ObjectMapper
之外,当我尝试在dto.test.EmployeeTest中获得java.lang.NullPointerException时,应该反序列化员工字符串吗?ok(EmployeeTest.java:115)
不是我。我自己试过了。您是否无意中注释掉了对象映射器的创建?我不知道你的第115行是什么,你可以用你的更新吗,那么我们是否需要将这些类视为静态类,但这是基于指定值的工作方式…即员工或经理…但是如果值不同,那么它将不正常工作…如果指定为技术人员,那么它将不工作
// note hashCode(), equals() and toString() methods left out for brevity!
@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "designation")
@JsonSubTypes({ @JsonSubTypes.Type(Staff.class), @JsonSubTypes.Type(Manager.class) })
public static abstract class Employee {
@JsonProperty("name")
public String name;
public Employee(String name) {
this.name = name;
}
public Employee() {
}
}
@JsonTypeName("Manager")
public static final class Manager extends Employee {
@JsonProperty("item")
public List<Item> items;
public Manager(String name, List<Item> items) {
super(name);
this.items = items;
}
public Manager() {
}
public static final class Item {
public final String name;
public final String desc;
public Item(@JsonProperty("name") String name, @JsonProperty("desc") String desc) {
this.name = name;
this.desc = desc;
}
}
}
@JsonTypeName("Staff")
public static final class Staff extends Employee {
@JsonProperty("item")
public String item;
public Staff(String name) {
super(name);
this.item = item;
}
public Staff() {
}
}
@Test
public void polymorphic_deserialization_of_manager() throws Exception {
ObjectMapper mapper = new ObjectMapper().enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES)
.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.enable(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED);
String json = "{ name: 'Rohit', designation: 'Manager', item: { name: 'ABC', desc: '1234' } }";
Employee employee = new Manager("Rohit", ImmutableList.of(new Manager.Item("ABC", "1234")));
assertThat(mapper.readValue(json, Employee.class), equalTo(employee));
assertThat(mapper.writeValueAsString(employee), equivalentTo(json));
}
@Test
public void polymorphic_deserialization_of_staff() throws Exception {
ObjectMapper mapper = new ObjectMapper().enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES).enable(
JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES);
String json = "{ name: 'Manu', designation: 'Staff', item: 'abc' }";
Employee employee = new Staff("Manu", "abc");
assertThat(mapper.readValue(json, Employee.class), equalTo(employee));
assertThat(mapper.writeValueAsString(employee), equivalentTo(json));
}