gpt4 book ai didi

java - 两个传入 REST json 的公共(public) dto

转载 作者:行者123 更新时间:2023-11-30 08:45:39 26 4
gpt4 key购买 nike

我想创建一个如下所示的公共(public) 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
}

问题是,对于经理来说,项目字段将是一个列表,而对于员工来说,它将是一个字符串,所以我为项目创建了两个字段,一个用于接收字符串,另一个用于列表,但它不起作用并且我收到 Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token

传入的json详情如下图所示

管理器传入json

{
"name": "Rohit",
"designation": "Manager",
"item": {"name": "ABC", "desc": "1234"}
}

人员传入json

{
"name": "Manu",
"designation": "Staff",
"item": "abc"
}

谁能告诉我一些解决办法

最佳答案

您可以创建一个客户反序列化器。如果 "item" 字段的节点是数组,则将其反序列化为数组,否则将其反序列化为 String。例如

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

我实际上为 “item” 添加了三个案例。它可以是作为多个项目的 JSON 数组,作为单个项目的 JSON 对象(这是您的帖子中的对象),或者是员工的字符串。如果它是一个 JSON 对象,我只需创建单个 Item 并将其添加到 List

这是一个完整的测试

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.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import static org.junit.Assert.*;
import org.junit.BeforeClass;

public class EmployeeTest {

@JsonDeserialize(using = EmployeeDeserializer.class)
public static class Employee {

public String name;
public String designation;
public String item;
public List<Item> items;
}

public static class Item {

public String name;
public String desc;

@Override
public String toString() {
return "Item{" + "name=" + name + ", desc=" + desc + '}';
}
}

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

private static ObjectMapper mapper;

@BeforeClass
public static void setUpMapper() {
mapper = new ObjectMapper();
//SimpleModule module = new SimpleModule();
//module.addDeserializer(Employee.class, new EmployeeDeserializer());
//mapper.registerModule(module);
}

@Test
public void should_deserialize_manager_list_ok() throws Exception {
final String mgrJson
= "{\n"
+ " \"name\": \"Rohit\",\n"
+ " \"designation\": \"Manager\",\n"
+ " \"item\": [{\"name\": \"ABC\", \"desc\": \"1234\"}]\n"
+ "}";
Employee mgr = mapper.readValue(mgrJson, Employee.class);
assertEquals("Rohit", mgr.name);
assertEquals("Manager", mgr.designation);
assertNull(mgr.item);
assertEquals(1, mgr.items.size());
assertEquals("ABC", mgr.items.get(0).name);
assertEquals("1234", mgr.items.get(0).desc);
}

@Test
public void should_deserialize_staff_string_ok() throws Exception {

final String staffJson
= "{\n"
+ " \"name\": \"Manu\",\n"
+ " \"designation\": \"Staff\",\n"
+ " \"item\": \"abc\"\n"
+ "}";
Employee staff = mapper.readValue(staffJson, Employee.class);
assertEquals("Manu", staff.name);
assertEquals("Staff", staff.designation);
assertEquals("abc", staff.item);
assertNull(staff.items);
}

@Test
public void should_deserialize_single_item_ok() throws Exception {
final String mgrJson
= "{\n"
+ " \"name\": \"Rohit\",\n"
+ " \"designation\": \"Manager\",\n"
+ " \"item\": {\"name\": \"ABC\", \"desc\": \"1234\"}\n"
+ "}";
Employee mgr = mapper.readValue(mgrJson, Employee.class);
assertEquals("Rohit", mgr.name);
assertEquals("Manager", mgr.designation);
assertNull(mgr.item);
assertEquals(1, mgr.items.size());
assertEquals("ABC", mgr.items.get(0).name);
assertEquals("1234", mgr.items.get(0).desc);
}
}

关于java - 两个传入 REST json 的公共(public) dto,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33198270/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com