Java 布尔字段的反序列化和验证

Java 布尔字段的反序列化和验证,java,json,jackson,Java,Json,Jackson,我发现了一些关于布尔getter的东西,我想检查一下我是否遗漏了一些东西,或者它是否是一个Jackson非托管用例。 我有两个Java类Employee和PersonalData,这两个类都有一个布尔属性,它们名为public Boolean的getter是…(){}PersonalData也是Employee的一个属性 我的类的“轻”描述是: import javax.validation.Valid; 导入javax.validation.constraints.*; 导入java.io.S

我发现了一些关于布尔getter的东西,我想检查一下我是否遗漏了一些东西,或者它是否是一个Jackson非托管用例。
我有两个Java类
Employee
PersonalData
,这两个类都有一个布尔属性,它们名为
public Boolean的getter是…(){}
PersonalData
也是
Employee
的一个属性

我的类的“轻”描述是:

import javax.validation.Valid;
导入javax.validation.constraints.*;
导入java.io.Serializable;
公共类Employee实现了可序列化{
私有静态最终长serialVersionUID=8106504890586067631L;
@NotNull
私有布尔激活;
//StackOverflow注释:已激活且未激活以匹配布尔getter命名规则
公共布尔值已激活(){
返回激活;
}
公共无效设置已激活(布尔值已激活){
这个.激活的=激活的;
}
//StackOverflow注释:@Valid可增强子元素验证
@NotNull
@有效的
个人资料;
公共PersonalData getPersonalData(){
返回个人数据;
}
public void setPersonalData(PersonalData PersonalData){
this.personalData=个人数据;
}
}
公共类PersonalData实现可序列化{
私有静态最终长SerialVersionId=-61880360904142526L;
/**
*性别-男性为真,女性为假
*/
@NotNull
私人布尔人;
//isMan和not getMan匹配布尔getter命名规则
公共布尔isMan(){
返回人;
}
公共void setMan(布尔man){
这个人=人;
}
}
我的前端是有角度的,所以我将这些类的Json发送给控制器方法

@PostMapping(“/employees”)
public ResponseEntity createEmployee(@Valid@RequestBody Employee-Employee)抛出URISyntaxException{
//Stackoverflow评论:我们并不真正关心这里的内容
返回null;
}
我尝试了3个用例:

  • 一个有效的JSON->它可以正常工作

    { 
        "activated": true,
        "personalData": {
            "man": true
        }
    }
    
  • 无效的json,因为
    已激活
    为空。正如预期的那样,验证失败:激活消息的BadRequest必须为NotNull

    {
        "activated": null, 
        "personalData": {
            "man": true
        }
    }
    
  • 无效的Json,因为
    man
    为空意外结果:反序列化失败:InternalServerError,消息显示personalData.man无法映射

    {
        "activated": true, 
        "personalData": {
            "man": null
        }
    }
    
  • 现在,如果我将我的
    isMan()
    getter重命名为
    getMan()
    ,它修复了这个问题,第三个用例由于预期的验证问题而失败(idem第二个用例)。因此,
    isActivated
    正常,而
    isMan
    不正常


    那么,我遗漏了什么还是Jackson遗漏了什么(=要反序列化,子元素的getter属性必须被调用
    get…()
    不能是
    is…()
    )?

    首先,我建议使用Joshua Block在书中所写的不可变对象。因此,请尝试添加所有args构造函数并删除所有setter

    PS:您可以使用lombok来考虑额外的代码添加注释
    @allargsconstuctor、@Getter、@Setter

    PSS:我不能重新考虑这个问题。这是我的代码片段:

    class ExternalClass {
        private Boolean flag;
        private InternalClass internalClass;
    
        public Boolean isFlag() {
           return flag;
        }
    
        public void setFlag(Boolean flag) {
           this.flag = flag;
        }
    
        public InternalClass getInternalClass() {
           return internalClass;
        }
    
        public void setInternalClass(InternalClass internalClass) {
           this.internalClass = internalClass;
        }
    }
    
    class InternalClass {
       private Boolean flag;
    
       public Boolean isFlag() {
          return flag;
       }
    
       public void setFlag(Boolean flag) {
           this.flag = flag;
       }
    }
    
    public static void main(String... args) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
    
        ExternalClass clazz1 = mapper.readValue("{\n" +
                                                       "  \"flag\": true,\n" +
                                                       "  \"internalClass\": {\n" +
                                                       "    \"flag\": false\n" +
                                                       "  }\n" +
                                                       "}", ExternalClass.class);
    
        ExternalClass clazz2 = mapper.readValue("{\n" +
                                                       "  \"flag\": null,\n" +
                                                       "  \"internalClass\": {\n" +
                                                       "    \"flag\": false\n" +
                                                       "  }\n" +
                                                       "}", ExternalClass.class);
    
        ExternalClass clazz3 = mapper.readValue("{\n" +
                                                       "  \"flag\": true,\n" +
                                                       "  \"internalClass\": {\n" +
                                                       "    \"flag\": null\n" +
                                                       "  }\n" +
                                                       "}", ExternalClass.class);
      }
    

    这并没有回答问题,更多的是对代码其他方面的评论。你没有解决问题,你说OP应该使用不可变对象和Lombok,它们是评论而不是答案。你不能重现问题的事实也不是答案,因为OP显然存在问题。同样,这也会保证注释要求一个。命名约定只适用于返回类型为
    boolean
    的getter,而不是返回类型为
    boolean
    的getter。当返回类型为
    Boolean
    时,正常的
    getXXX
    命名约定适用。但是,我无法解释为什么这会导致顶级属性和嵌套属性之间的差异。如果您想强制NOTNULL,为什么不直接使用
    布尔值
    ?您使用的是什么版本的Jackson?你应该试试最新的。下面我的代码片段成功地将JSON反序列化到Jackson v.2.8.11。我使用的2.9.9是目前可用的最新版本。@MarkrotVeel我同意您关于
    is…()
    for
    boolean
    get…
    for
    boolean
    的看法。“我的域”是从对象模型(带有一个名为jhipster的生成器)生成的,使用的数据类型是
    Boolean
    。遇到这个问题时,我看了一下最佳实践(在建议更改生成器之前进行检查),似乎有人说
    is…
    也已成为
    Boolean
    的标准。是的,我可以更改数据类型,但我想避免手动重构。对于
    布尔
    属性,唯一的定义是
    isXXX
    ,因此
    布尔
    属性的标准是
    getXXX