Java 两个传入REST json的公共dto

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

我想创建一个通用dto,如下图所示,用于从REST服务接收传入的经理和员工详细信息

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));
}