Как создать пользовательский десериализатор с использованием jackson для преобразования числа (которое является идентификатором отдела) в объект отдела?

#java #json #jackson #json-deserialization

#java #json #джексон #json-десериализация

Вопрос:

У меня есть класс с именами User и Department, которые указывают на соответствующие таблицы в базе данных mysql (отношение «Многие ко многим»). Я хочу создать пользовательский десериализатор для списка отделов в классе User.

мой POST Json выглядит следующим образом:

{ «userId»: 1456, «FirstName»: «David», «MiddleName»: «», «LastName»: «Bekham», «gender»: «M», «rollNo»: «», «semestr»: 0, «section»: «», «email»: «david8@gmail.com «, «пароль»: «d123avid», «телефон»: «9844547852», «статус»: 0, «Тип пользователя»: 1, «userBio»: «я преподаю статистику», «profilePicture»: null, «dob»: «1999-03-21», «facultyType»: 1, «отделы»: [109] }

Мое определение пользовательского класса выглядит следующим образом:

 @Entity
@Table(name="user")
public class User {

@Id
@Column(name="user_id")
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
private long userId; 

@Column(name="first_name")
private String firstName;

@Column(name="middle_name")
private String middleName;

@Column(name="last_name")
private String lastName;

@Column(name="gender")
private char gender;

@Column(name="roll")
private String rollNo;

@Column(name="semester")
private byte semester;

@Column(name="section")
private char section;

@Column(name="email")
private String email;

@Column(name="password")
private String password;

@Column(name="phone")
private String phone;

@Column(name="status")
private byte status;

@Column(name="user_type")
private byte userType;

@Column(name="user_bio")
private String userBio;

@Column(name="profile_picture")
private String profilePicture;

@Column(name="dob")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd")
private LocalDate dob;

@Column(name="faculty_type")// 0 is for student, 1 for permanent and 2 for visiting
private byte facultyType;

//for join table
@ManyToMany(fetch=FetchType.EAGER,
        cascade= {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH})
@JoinTable(
    name="user_department",
    joinColumns=@JoinColumn(name="user_id"),
    inverseJoinColumns=@JoinColumn(name="dept_id")
    )
private List<Department> departments;
  

в настоящее время я получаю сообщение об ошибке, в котором говорится, что

Ошибка синтаксического анализа JSON: не удается создать экземпляр com.maverick.project.entity.Отдел: нет конструктора int / Int-argument / фабричного метода для десериализации из числового значения (109); вложенным исключением является com.fasterxml.jackson.databind.Исключение JsonMappingException: не удается создать экземпляр com.maverick.project.entity.Отдел: нет конструктора int / Int-argument / фабричного метода для десериализации из числового значения (109)

Мое определение класса Department выглядит следующим образом:

 @Entity
@Table(name="department")
public class Department {

@Id
@Column(name="dept_id")
@JsonFormat(shape = JsonFormat.Shape.NUMBER)
private int deptId;

@Column(name="dept_name")
private String deptName;


@ManyToMany(fetch=FetchType.EAGER,
        cascade= {CascadeType.PERSIST, CascadeType.MERGE,CascadeType.DETACH, CascadeType.REFRESH})
@JoinTable(
    name="user_department",
    joinColumns=@JoinColumn(name="dept_id"),
    inverseJoinColumns=@JoinColumn(name="user_id")
    )
@JsonIgnore
private List<User> users;
  

Комментарии:

1. в принципе, вам нужен метод setDepartments(List<Integer> id){...} , который выполнит выборку из базы данных за вас

Ответ №1:

Вам не нужен пользовательский десериализатор. Вы можете добавить один конструктор аргументов, который принимает int :

 public Department() {
}

public Department(int deptId) {
    this.deptId = deptId;
}
  

И он будет автоматически десериализован в Department . После десериализации вам нужно выполнить дополнительную настройку, если это необходимо.