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

时间:2019-07-26 04:15:38

标签: java json jackson

我想出了一些关于布尔型getter的知识,我想检查是否错过了一些东西,或者这是否是Jackson的非托管用例。
我有2个Java类EmployeePersonalData,这两个类都具有Boolean属性,并将它们的getter命名为public Boolean is...() {}PersonalData也是Employee的属性。

我的课程的“简短”描述是:

import javax.validation.Valid;
import javax.validation.constraints.*;

import java.io.Serializable;

public class Employee implements Serializable {

    private static final long serialVersionUID = 8106504890586067631L;

    @NotNull
    private Boolean activated;

    // StackOverflow comment : isActivated and not getActivated to match the Boolean getter naming rules
    public Boolean isActivated() {
        return activated;
    }

    public void setActivated(Boolean activated) {
        this.activated = activated;
    }

    // StackOverflow comment : @Valid to enhance child element validation
    @NotNull
    @Valid
    private PersonalData personalData;

    public PersonalData getPersonalData() {
        return personalData;
    }

    public void setPersonalData(PersonalData personalData) {
        this.personalData = personalData;
    }
}

public class PersonalData implements Serializable {

    private static final long serialVersionUID = -61880360094142526L;

    /**
     * Gender - true if man, false if woman
     */
    @NotNull
    private Boolean man;    

    // isMan and not getMan to match the Boolean getter naming rules
    public Boolean isMan() {
        return man;
    }

    public void setMan(Boolean man) {
        this.man = man;
    }
}

我的前端是Angular,所以我将这些类的Json发送到控制器方法

@PostMapping("/employees")
public ResponseEntity<Employee> createEmployee(@Valid @RequestBody Employee employee) throws URISyntaxException {
    // Stackoverflow comment : We don't really care of the content here
    return null;
}

我尝试了3个用例:

  1. 有效的JSON->可以按预期运行

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

    {
        "activated": null, 
        "personalData": {
            "man": true
        }
    }
    
  3. 无效的Json,因为man为空。 意外结果:反序列化失败:InternalServerError,并提示无法映射PersonalData.man

    {
        "activated": true, 
        "personalData": {
            "man": null
        }
    }
    

现在,如果我将我的isMan()吸气剂重命名为getMan(),它将解决此问题,并且由于预期的验证问题,第3个用例失败了(同上第二个用例)。因此,isActivated不错,而isMan不好。

那么,我是想念东西还是杰克逊想念东西(=要反序列化,子元素的getter属性必须称为get...()不能为is...())?

1 个答案:

答案 0 :(得分:-2)

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

PS:您可以使用lombok来补充添加注释@AllArgsConstructor, @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);
  }
相关问题