【问题标题】:Not able to map Json to java Object using Jackson and lombok无法使用 Jackson 和 lombok 将 Json 映射到 java 对象
【发布时间】:2021-05-27 10:44:30
【问题描述】:

POJO:

import lombok.Data;
@Data
public class CCMTRequest {
    
    private MOEH cch;
    
    private String filler1;
    
    private CCMTCCD ccd;
    
    private String uPwName;
}


@Data
public class MOEH {
    private String c;
    private int z;
    private String dType;
}


@Data
public class CCMTCCD {
    private dTime time;
    private int x;
}

@Data
public class dTime {
    private String dTime;
}

测试类:

public class TestJacksonParser {
    
    @Test
    void load_jsonToPOJO() {
        ObjectMapper mapper = new ObjectMapper();
        ClassLoader load = this.getClass().getClassLoader();
        File file = new File(load.getResource("request.json").getFile());
        CCMTRequest req = null;
        try {
            req = mapper.readValue(file, CCMTRequest.class);
        }
        catch(Exception e) {
            System.out.println(e.getMessage());
        }
        System.out.println("\nRequest: " + req);
    }
    
}

request.json:

{
    "cch" : {
        "c" : "C",
        "z" : 4678,
        "dType" : "dtype"       
    },
    "filler1" : "random filler1",
    "ccd" : {
        "time" : {
            "dTime" : "4:35"
        },
        "x" : 34567
    },
    "uPwName" : "uPwName"
}

错误:

无法识别的字段“dType”(com.spring.mapstruct.test.MOEH 类),不是 标记为可忽略(3 个已知属性:“z”、“c”、“dtype”]) [源文件);行:5,列:14](通过参考链: com.spring.mapstruct.test.CCMTRequest["cch"]->com.spring.mapstruct.test.MOEH["dType"])

请求:空

现在,当我将我的测试类更新为:

public class TestJacksonParser {
        
        @Test
        void load_jsonToPOJO() {
            ObjectMapper mapper = new ObjectMapper();
    
            //ignore Unknown JSON Fields
          mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

            ClassLoader load = this.getClass().getClassLoader();
            File file = new File(load.getResource("request.json").getFile());
            CCMTRequest req = null;
            try {
                req = mapper.readValue(file, CCMTRequest.class);
            }
            catch(Exception e) {
                System.out.println(e.getMessage());
            }
            System.out.println("\nRequest: " + req);
        }
        
    }

我得到的输出为:

请求:CCMTRequest(cch=MOEH(c=C, z=4678, dType=null),filler1=random 填充物1, ccd=CCMTCCD(time=dTime(dTime=4:35), x=34567), uPwName=null)

那么 jackson 是如何在这里与 lombok 合作的,属性“dType”和“uPwName”是否存在问题

【问题讨论】:

  • 这里使用Lombok重要吗?我会简单地跳过 Lombok 并使四个数据类具有公共字段,例如public class dTime { public String dTime; }
  • @Erik,是的,使用 lombok 很重要,因为请求有大约 200 个属性,我无法公开字段
  • 嗯,我不是 Lombok 方面的专家,但在我看来,Lombok 和 Jackson 似乎不同意应该调用 dType 的二传手。从您的错误消息来看,杰克逊似乎认为您的班级有一个属性 dtype(而不是 dType
  • mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true); 可能会有所帮助...

标签: java jackson lombok jackson-databind sts


【解决方案1】:

首先,下次请提供更好的示例而不是随机名称属性。很混乱。

您的问题是因为 lombok 为诸如“uPwName”之类的属性生成 getter 和 setter 变为“getUPwName()”和“setUPwName()”。 jackson 将其读作“getuPwName”和“setuPwName”;

该库对 getter 和 setter 使用不同的命名约定。

有两种方法可以解决这个问题:

  1. 为了您的快速修复:
ObjectMapper mapper = new ObjectMapper().disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES);
  1. 为了更好地解决您的问题:为您的属性使用更好的名称。

【讨论】:

  • 为什么其他属性不是这样?
  • 为什么需要 FAIL_ON_UNKNOWN_PROPERTIES ?
  • FAIL_ON_UNKNOWN_PROPERTIES 不是必需的。但默认情况下,如果 json 和 java 对象之间存在不匹配的属性,jackson 会抛出错误。如果您认为在存在不匹配的属性时需要抛出错误,则可以将其删除。该问题仅发生在前 2 个字母的混合大小写上。 Lombok 在 getter 和 setter 上将每个首字母都视为大写。并保留第二个字母。在 Jackson(以及大多数 getter 和 setter 生成器)上,如果前 2 个字母大小写混合,他们不会改变它。
  • 这里我可以配置jackson,但是如果在我的控制器方法中使用注解@RequestBody读取请求怎么办,在这种情况下,spring boot会在内部使用jackson库,我该怎么办?跨度>
  • 通过使用更好的变量名来使用第二种方法。惯例是:它应该清晰简洁,用英文书写,避免使用首字母缩写词或缩写,并且应该可读和可说。例如:使用 firstName 而不是 fName。或者使用 unitOfMeasurement 而不是 uom。但是如果你想知道如何在 Spring Boot 上覆盖 jackson 配置,这个baeldung.com/spring-boot-customize-jackson-objectmapper 应该会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 2016-01-12
  • 2016-03-30
  • 1970-01-01
相关资源
最近更新 更多