代码之家  ›  专栏  ›  技术社区  ›  Nox

JavaJackson对象映射器在正确的变量名上失败

  •  1
  • Nox  · 技术社区  · 5 年前

    注意:我知道变量的名称不正确。我正在清理另一个将这些列为成员变量的开发人员的旧代码。它们将被正确命名,是的,我知道我需要注释,但是我在这里要找的是一个解释,为什么变量是employeeid,它在寻找employeeid,但是找到一个不存在的变量mempolyeid。顺便说一句,这发生在服务器上,而不仅仅是在IDE中。

    出于某种未知的原因——在修改变量名、保存、重新启动、使缓存无效之后,一切——杰克逊无法映射到propper变量名。我正在使用IntLIJ与Java进行此操作。

    错误:

    Exception in badge service getting by badgeId: Unrecognized field 
    "EmployeeId" (class com.companyName.attendance.entity.DTOs.badgeservice.BadgeDTO), not marked as ignorable (6 known properties: "mBadgeId", "mEmployeeId", "mLanId", "mFirstName", "mEmail", "mLastName"]) 
    at [Source: (String)"{"backoff":null,"error_id":null,"error_message":null,"error_name":null,"has_more":false,"items":[{"EmployeeId":"888888","LanId":"NTest","FirstName":"Name","MiddleName":null,"LastName":"Test","Email":null,"Location":null,"Title":null,"Phone":null,"DepartmentId":null,"DepartmentName":null,"DepartmentNumber":null,"Groups":null,"Found":false,"BadgeId":"222222","JobTitle":null,"Picture":null,"OrgUrl":null,"Manager":null,"Coworkers":null,"DirectReports":null}],"page":null,"page_size":null,"quo"[truncated 61 chars]; line: 1, column: 113] (through reference chain: com.companyName.attendance.entity.DTOs.badgeservice.BadgeServiceResponseDTO["items"]->java.util.ArrayList[0]->com.companyName.attendance.entity.DTOs.badgeservice.BadgeDTO["EmployeeId"])
    

    如您所见,在DTO中找不到EmployeeID,并说预期的feild是mempolyeID。但是,这里是我的DTO变量声明:

    public class BadgeDTO {
    //TODO: Convert member variables to proper practice names
    String BadgeId;
    String EmployeeId;
    String FirstName;
    String LanId;
    String LastName;
    String Email;
    
    public BadgeDTO(String BadgeId, String EmployeeId, String FirstName, 
    String LanId, String LastName, String Email) {
        super();
        this.BadgeId = BadgeId;
        this.EmployeeId = EmployeeId;
        this.FirstName = FirstName;
        this.LanId = LanId;
        this.LastName = LastName;
        this.Email = Email;
    }
    public BadgeDTO() {
        super();
    }
    public String getmBadgeId() {
        return BadgeId;
    }
    public void setmBadgeId(String BadgeId) {
        this.BadgeId = BadgeId;
    }
    public String getmEmployeeId() {
        return EmployeeId;
    }
    public void setmEmployeeId(String EmployeeId) {
        this.EmployeeId = EmployeeId;
    }
    public String getmFirstname() {
        return FirstName;
    }
    public void setmFirstName(String FirstName) {
        this.FirstName = FirstName;
    }
    public String getmLanId() {
        return LanId;
    }
    public void setmLanId(String LanId) {
        this.LanId = LanId;
    }
    public String getmLastName() {
        return LastName;
    }
    public void setmLastName(String LastName) {
        this.LastName = LastName;
    }
    public String getmEmail() {
        return Email;
    }
    public void setmEmail(String Email) {
        this.Email = Email;
    }
    @Override
    public String toString() {
        return "BadgeDTO [BadgeId=" + BadgeId + ", EmployeeId=" + EmployeeId + 
    ", Firstname=" + FirstName
                + ", LanId=" + LanId + ", LastName=" + LastName + ", Email=" + 
    Email + "]";
    }
    }
    

    现在疯狂的是,做以下工作:

    @JsonProperty("BadgeId")
    String BadgeId;
    @JsonProperty("EmployeeId")
    String EmployeeId;
    @JsonProperty("FirstName")
    String FirstName;
    

    杰森:

    {
    "backoff": null,
    "error_id": null,
    "error_message": null,
    "error_name": null,
    "has_more": false,
    "items": [
        {
            "EmployeeId": "888888",
            "LanId": "TName",
            "FirstName": "Test",
            "MiddleName": null,
            "LastName": "Name",
            "Email": null,
            "Location": null,
            "Title": null,
            "Phone": null,
            "DepartmentId": null,
            "DepartmentName": null,
            "DepartmentNumber": null,
            "Groups": null,
            "Found": false,
            "BadgeId": "222222",
            "JobTitle": null,
            "Picture": null,
            "OrgUrl": null,
            "Manager": null,
            "Coworkers": null,
            "DirectReports": null
        }
    ],
    "page": null,
    "page_size": null,
    "quota_max": null,
    "quota_remaining": null,
    "total": null,
    "type": null
    }
    

    所以,我已经使用上面的JSONproperty注释解决了这个问题,但是为什么它仍然在寻找mempolyeid,当它不存在于我的整个代码中的任何位置时?我认为无效/重新启动可以解决这个问题,但它没有

    2 回复  |  直到 5 年前
        1
  •  1
  •   DwB    5 年前

    答案是, 通常是:注意你写的代码。

    getter和setter将字段公开为m*(其中*是实际字段名)。

    看看这个:

    getmEmployeeId(
       ^
       |
    

    这是字母“M”。

    因此,这将字段名公开为“mempolyeid”

    更多细节:
    方法返回的值与getter公开的值的名称无关。 Java要求吸气剂名称具有“GETFieldNeX”格式。 该setter nanes的格式为“setfieldname” 其中“fieldname”是不是方法名的“get”或“set”部分的任何值。

    这被称为“JavaBean命名约定”,如果您在Java中编码并使用任何第三方Java库,则必须绝对地理解并遵守它。

        2
  •  0
  •   Michał Ziober    5 年前

    相配 JSON 带钥匙 POJO 性质 Jackson 使用一种叫做 PropertyNamingStrategy . 在你 杰森 我们可以找到至少两种策略:

    1. SNAKE_CASE ( page_size , error_message 等)
    2. UPPER_CAMEL_CASE ( EmployeeId , DepartmentId 等)

    从另一边 波乔 课程提供第三种策略:

    1. “M”+ 上骆驼壳 ( mEmployeeId , mDepartmentId 等)

    这就是为什么 杰森 不匹配 波乔 . 要使其发挥作用,您需要实施如下所示的新战略:

    class MNamingStrategy extends PropertyNamingStrategy {
    
        @Override
        public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method,
            String defaultName) {
            return defaultName.substring(1); // remove first `m` letter
        }
    }
    

    您可以这样使用它:

    @JsonNaming(MNamingStrategy.class)
    class Clazz {
    
        private int Id = 11;
    
        public int getmId() {
            return Id;
        }
    
        public void setmId(int id) {
            this.Id = id;
        }
    
        @Override
        public String toString() {
            return "Clazz{" +
                "Id=" + Id +
                '}';
        }
    }
    

    从现在起,您可以反序列化上面的内容 杰森 波乔 .

    当你添加 @JsonProperty 带有您告诉的属性名的批注 杰克逊 使用自定义映射。

    参见:

    1. Spring Jackson property naming strategy
    2. PropertyNamingStrategy
    3. More Jackson Annotations