You*_*sef 3 java spring spring-mvc jackson
我正在使用,Spring-MVC并且具有如下所示的DTO结构,JSON用于从客户端(foo实体)接收数据,并使用以下命令将其保存到数据库中JPA :
public class FooDTO {
public Integer id;
public String label;
public Double amount;
public List<Integer> states;
...
Run Code Online (Sandbox Code Playgroud)
但是当客户想要编辑foo实体时,我必须像下面这样构造它
public class FooDTO {
public Integer id;
public String label;
public Double amount;
public List<SimpleDto> states;
...
Run Code Online (Sandbox Code Playgroud)
用 SimpleDto
public class SimpleDto {
public Integer value;
public String label;
}
Run Code Online (Sandbox Code Playgroud)
区别只是states有时List<SimpleDto>和有时是类型,List<Integer>而我不想创建另一个dto。
那么如何在dto(json)中实现动态字段类型呢?
P.S JSON data is handled by com.fasterxml.jackson.core
使用自定义解串器是解决问题的一种方法
public class DynamicDeserializer extends JsonDeserializer {
@Override
public Object deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String requestString = jp.readValueAsTree().toString();
JSONArray jo = new JSONArray(requestString);
List<SimpleDto> simpleDtoList = new ArrayList<>();
List<Integer> integers = new ArrayList<>();
if(jo!=null && jo.length()>0) {
for (int i = 0; i < jo.length(); i++) {
Object string = jo.get(0);
if(string!=null && string instanceof JSONObject){
JSONObject value = jo.getJSONObject(i);
SimpleDto simpleDto = new SimpleDto();
simpleDto.setValue(value.getInt("value"));
simpleDtoList.add(simpleDto);
}else{
integers.add(jo.getInt(0));
}
}
}
return integers.isEmpty() ? simpleDtoList:integers;
}
}
Run Code Online (Sandbox Code Playgroud)
发送请求并打印回的控制器
@PostMapping("/test")
public Optional<TestObject> testDynamicMapper(
@RequestBody final TestObject testObject) {
List<Object> states = testObject.getStates();
for (Object object:states) {
if(object instanceof SimpleDto){
SimpleDto dto = (SimpleDto)object;
System.out.println(dto.getValue());
}
if(object instanceof Integer){
Integer dto = (Integer)object;
System.out.println(dto);
}
}
return Optional.of(testObject);
}
Run Code Online (Sandbox Code Playgroud)
有通用映射的pojo类
public class TestObject implements Serializable {
@JsonDeserialize(using = DynamicDeserializer.class)
private List<Object> states;
public List<Object> getStates() {
return states;
}
public void setStates(List<Object> states) {
this.states = states;
}
}
Run Code Online (Sandbox Code Playgroud)
{
"states": [
{
"label": "1",
"value": 0
}
]
}
Run Code Online (Sandbox Code Playgroud)
{
"states": [
1,2
]
}
Run Code Online (Sandbox Code Playgroud)
使用适合您的 DTO 类型的 Spring 类型转换器。这样,客户端可以发布 stateId,转换器将为给定 ID 解析正确的 DTO 类型。
这是一个例子: https: //www.baeldung.com/spring-type-conversions