@RequestBody 映射复杂的 json 对象

Posted

技术标签:

【中文标题】@RequestBody 映射复杂的 json 对象【英文标题】:@RequestBody mapping complex json object 【发布时间】:2018-10-27 09:30:30 【问题描述】:

我需要将下面的 json 转换为 @RequestBody 的 java 对象。


    "entity": 
        "id": 3,
        "name": "james"
    ,
    "conjunction": "OR",
    "conditions": [
        
            "operation": "equalTo",
            "dataKey": "department",
            "dataType": "string",
            "value": "abc"
        ,
        
            "operation": "notEqualTo",
            "dataKey": "ID",
            "dataType": "number",
            "value": "100"
        ,
        
            "operation": "notEqualTo",
            "dataKey": "name",
            "dataType": "strubg",
            "value": "jack"
        ,
        
            "operation": "between",
            "dataKey": "END_DATE",
            "dataType": "date",
            "value1": "20180502",
            "value2": "20180519"
        
    ]

数组的前三个元素对应下面的java对象。

public class ComparisonCondition extends Condition 
    private String value;

最后一个元素对应下面的对象。

public class BetweenCondition extends Condition 
    private String value1;
    private String value2;

它们都继承自下面的对象。

public class Condition 
    private String dataKey;
    private String dataType;
    private String operation;

spring mvc方法如下。

@RequestMapping(value = RequestAction.FILTER, method = RequestMethod.POST)
public List<Student>  filter(
        @RequestBody  Filter<Student> filterConfig)    
    return null;


Filter 对象在下方。

public class Filter<T> 
    private String conjunction;
    private T entity;
    private List<Condition> conditions;

如何成功地将 json 映射到 java 对象? 目前它报告"Could not read JSON: Unrecognized field "value" (class com.ssc.rest.entity.Condition), not marked as ignorable (3 known properties: "dataType", "dataKey", "operation"])

【问题讨论】:

How can I polymorphic deserialization Json String using Java and Jackson Library?的可能重复 滚动到已接受答案中的第二个解决方案 你不能用private List&lt;Map&lt;String, String&gt;&gt; conditions;吗? 【参考方案1】:

对于您的错误,如果 jackson 解析器不知道某个字段,则会引发异常。

你可以通过添加注释来避免它:

@JsonIgnore(ignoreUnknown=true)

在目标物体上。

对于您的映射,我建议您创建一个与您的 json 输入相对应的对象,然后手动映射到您的目标对象。

【讨论】:

这不能回答问题,@JsonIgnore 在这里没有帮助,因为 OP 想要根据 operation 字段选择实现(ComparisonCondition 或 BetweenCondition)。【参考方案2】:

您在 JSON 中为条件传递 4 个变量


    "operation": "equalTo",
    "dataKey": "department",
    "dataType": "string",
    "value": "abc"
,

但是你的 Java POJO 只有 3 个变量

public class Condition 
    private String dataKey;
    private String dataType;
    private String operation;

只需添加value 即可。

底线是:POJO 类应该有 JSON 中传递的所有字段。

顺便说一句,你的异常说明了同样的事情

Unrecognized field "value"

编辑 1:

我错过了BetweenCondition和ComparisonCondition

您可以在您的案例Condition 中使用 Sub Class 属性定义基类,希望它应该可以工作

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "javaclass")
@JsonSubTypes(
    @Type(value = ComparisonCondition.class),
    @Type(value = BetweenCondition.class)
)

public class Condition 
    private String dataKey;
    private String dataType;
    private String operation;

【讨论】:

您的回答解释了错误,但没有回答实际问题。查看层次结构,ComparisonCondition 类中有 value 字段。 OP想要多态反序列化 是的,我可以理解错误消息,但我想知道如何解决此错误,因为我有包含此 value 属性的子类,并且我还有具有 value1 和 value2 的 BetweenCondition。 spring 能处理这个复杂的情况吗?

以上是关于@RequestBody 映射复杂的 json 对象的主要内容,如果未能解决你的问题,请参考以下文章

@RequestBody 没有将 JSON 映射到 Java 对象 - Spring Boot

@requestbody与json映射需要set方法吗

RequestBody没有正确映射有对象列表的对象。

使用Spring的@RequestBody注解,无法映射首字母大写属性的踩坑记录

@RequestBody

@RequestBody的使用