杰克逊的Java对象映射器在正确的变量名称失败

问题描述 投票:1回答:2

注:我知道这个变量没有正确命名。我从其他开发人员谁曾这些列为成员变量清理旧代码。他们将正确命名是的,我知道我将需要的注释,但我正在寻找在这里是一个解释,为什么变量是雇员,它在寻找雇员,但要找到一个不存在的变量mEmployeeId。顺便说一句,这种情况发生在服务器上,而不是在IDE中。

对于一些未知的原因 - 修改变量名,保存,重启,无效缓存,一切之后 - 杰克逊未能映射到propper变量名。我使用的IntelliJ与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和雇员表示,预计费尔德是mEmployeeID。然而,这里是我的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;

JSON:

{
"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注释的问题,但为什么在世界上是不是还在寻找mEmployeeId当它存在于我的代码全部没有在哪里?我想通无效/重启可以解决这个问题,但是事实并非如此

java json jackson dto objectmapper
2个回答
1
投票

答案是,因为它往往是:注意你的代码编写。

getter和setter暴露字段为m *(其中*是实际的字段名称)。

看这个:

getmEmployeeId(
   ^
   |

这是字母“M”。

因此,这暴露了字段名称为“mEmployeeId”

更多细节: 该方法返回的值无关,与由吸气剂暴露值的名称。 Java的需求是吸气名的格式为“getFieldName”和二传手nanes的格式为“setFieldName”,其中“字段名”是任何值不是“get”或“集”的方法名称的一部分。

这就是所谓的“JavaBean命名公约”和你绝对必须同时了解并遵守它,如果你在Java代码和使用任何第三方Java库。


1
投票

为了配合JSON使用一种叫POJO Jackson性能PropertyNamingStrategy键。在您的JSON我们可以发现至少有两个策略:

  1. SNAKE_CASEpage_sizeerror_message等)
  2. UPPER_CAMEL_CASEEmployeeIdDepartmentId等)

来自对岸POJO类提供了第三个策略:

  1. “M” + UPPER_CAMEL_CASEmEmployeeIdmDepartmentId等)

这就是为什么JSON不匹配POJO。为了使它工作,你需要实施新的战略,可能看起来象下面这样:

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 +
            '}';
    }
}

因为现在,你可以反序列化上面qazxsw POI给出qazxsw POI。

当你添加属性名称标注JSON你告诉POJO使用自定义映射。

也可以看看:

  1. @JsonProperty
  2. Jackson
  3. Spring Jackson property naming strategy
© www.soinside.com 2019 - 2024. All rights reserved.