Java Джексон объект Mapper не удается на правильное имя переменной - PullRequest
0 голосов
/ 04 февраля 2019

Примечание: я знаю, что переменные не имеют правильного имени.Я очищаю старый код от другого разработчика, который перечислил их как переменные-члены.Они будут названы правильно, и да, я знаю, что мне понадобятся аннотации для этого, но здесь я ищу объяснение, почему переменная EmployeeId, она ищет EmployeeID, но находит несуществующую переменную 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"])

Как вы видите, он не находит 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, когда он не существует нигде во всем моем коде?Я полагал, что аннулирование / перезапуск исправит это, но это не

Ответы [ 2 ]

0 голосов
/ 05 февраля 2019

Для сопоставления JSON ключей с POJO свойствами Jackson используется то, что называется PropertyNamingStrategy.В вашем JSON мы можем найти как минимум две стратегии:

  1. SNAKE_CASE (page_size, error_message и т. Д.)
  2. UPPER_CAMEL_CASE (EmployeeId, DepartmentId и т. Д.)

С другой стороны POJO класс предоставляет третью стратегию:

  1. "m" + UPPER_CAMEL_CASE (mEmployeeId, mDepartmentId и т. Д.)

Именно поэтому 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 +
            '}';
    }
}

С тех пор вы можете десериализовать выше *От 1041 * до POJO.

Когда вы добавили аннотацию @JsonProperty с именами свойств, вы сказали Jackson использовать пользовательское сопоставление.

См. Также:

  1. Стратегия именования свойств Spring Jackson
  2. PropertyNamingStrategy
  3. Больше аннотаций Джексона
0 голосов
/ 04 февраля 2019

Ответ, как это часто бывает: обратите внимание на код, который вы пишете.

Получатели и установщики представляют поля как m * (где * - фактическое имя поля).

Посмотрите на это:

getmEmployeeId(
   ^
   |

Это буква 'm'.

Таким образом это выставляет имя поля как "mEmployeeId"

Подробнее:
Значение, возвращаемое методом, не имеет ничего общего с именем значения, предоставляемого получателем.Java требует, чтобы имена получателей имели формат «getFieldName» и чтобы у сеттеров был формат «setFieldName», где «FieldName» - это любое значение, которое не является частью «get» или «set» имени метода.

Это называется «соглашением об именах JavaBean», и вы обязательно должны понимать и соблюдать его, если кодируете на Java и используете любую стороннюю библиотеку Java.

...