У меня возникли проблемы с отправкой объекта JSON из моего пользовательского интерфейса в контроллер Spring Boot.
Вот мой контроллер, я закомментировал код контроллера и просто возвращаю новый объект. Кажется, что JSON неправильно анализируется для объекта домена:
PersonnelController:
@Controller
@RequestMapping(value = "/Personnel")
public class PersonnelController {
@RequestMapping(value = "update", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Personnel updateJson(@RequestBody Personnel personnel) {
System.out.println("update personnel json : " + personnel.toString());
return new Personnel();
}
}
Мой контроллер не является контроллером REST, и я использую согласование содержимого, чтобы иметь возможность использовать модель Spring и REST API вместе.
Это мои занятия:
Пользователь:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class User extends AbstractDomainClass {
@Column(unique = true)
private String username;
@Transient
private String password;
private String encryptedPassword;
private boolean enabled = true;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable
@JsonBackReference(value = "roles")
private List<Role> roles = new ArrayList<>();
}
Персонал:
@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Personnel extends User {
private String firstName;
private String lastName;
private long nationalId;
private long perssonnelId;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate birthDate;
@ManyToOne(fetch = FetchType.LAZY)
private Company company;
}
Компания:
@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
public class Company extends AbstractDomainClass {
@Column(unique = true)
private String name;
private String description;
private String address;
private String adminName;
@OneToMany(fetch = FetchType.LAZY , cascade = CascadeType.PERSIST , orphanRemoval = true)
@JoinTable
@JsonBackReference
private List<Personnel> personnels = new ArrayList<>();
@OneToOne(fetch = FetchType.EAGER , cascade = CascadeType.ALL)
private User admin;
}
Роль:
@Entity
@JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class Role extends AbstractDomainClass {
@Column(unique = true)
private String roleName;
@ManyToMany(fetch = FetchType.EAGER , mappedBy = "roles")
private List<User> users = new ArrayList<>();
@ManyToMany
@Fetch(FetchMode.SELECT)
private List<Permission> permissions = new ArrayList<>();
}
(Я пропустил геттеры и сеттеры.)
Это JSON, который я отправляю контроллеру:
и это ошибка Spring Boot:
WARN 10289 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Failed to read HTTP message: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `navid.usermanagementsys.domain.Company` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('{"id":26,"version":0,"dateCreated":"2018-08-08T16:02:15.000+0000","name":"company1","description":"Description Description Description Description","address":"IRAN","adminName":"Company admin","admin":{"id":25,"version":0,"dateCreated":"2018-08-08T16:02:15.000+0000","username":"company","password":null,"encryptedPassword":"$2a$10$kw5T5CCep.WwC5kj7Szgyu6akB7Zbx.jgqIz5dQtAx6Oz4F8ywIWq","enabled":true,"dateLastUpdated":"2018-08-08T16:02:15.000+0000"},"dateLastUpdated":"2018-08-08T16:02:15.000+0000"}');
nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `navid.usermanagementsys.domain.Company` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value** ('{"id":26,"version":0,"dateCreated":"2018-08-08T16:02:15.000+0000","name":"company1","description":"Description Description Description Description","address":"IRAN","adminName":"Company admin","admin":{"id":25,"version":0,"dateCreated":"2018-08-08T16:02:15.000+0000","username":"company","password":null,"encryptedPassword":"$2a$10$kw5T5CCep.WwC5kj7Szgyu6akB7Zbx.jgqIz5dQtAx6Oz4F8ywIWq","enabled":true,"dateLastUpdated":"2018-08-08T16:02:15.000+0000"},"dateLastUpdated":"2018-08-08T16:02:15.000+0000"}')
at [Source: (PushbackInputStream); line: 1, column: 152] (through reference chain: navid.usermanagementsys.domain.Personnel["company"])
Я потратил часы на поиск решения, и я попытался создать конструктор без аргументов, но ничто не решило мою проблему.
@mrkernelpanic да, я не использую ObjectMapper, насколько я знаю, аннотации Spring заботятся о сериализации / десериализации
Spring MVC внутренне использует Jacksons Objectmapper ... Попробуйте.
@mrkernelpanic извините, но я новичок в загрузке Spring, вопрос, который вы упомянули, говорит, что я должен попробовать mapper.configure (DeserializationConfig.Feature.ACCEPT_EMPTY_ STRING_AS_NULL_OBJEC T, true), я не уверен, где мне это использовать? создать bean-компонент для этого?
Я решил эту ошибку, добавив конструктор, который принимает только String arg (public Company (String company) {System.out.println ("company:" + company);}), и строка json передается этому конструктору корректно, но теперь проблема в том, что объект Company не десериализован правильно, когда я пытаюсь распечатать десериализованную компанию в контроллере, он дает значение NULL
@mrkernelpanic Я изменил @JsonBackReference и использовал его в атрибуте Personnel calss для атрибута компании. Теперь у меня такая ошибка: Не удалось прочитать сообщение HTTP: org.springframework.http.converter.HttpMessageNotReadableExc eption: Ошибка синтаксического анализа JSON: невозможно десериализовать значение типа java.lang.Integer из строки ": недопустимое целочисленное значение; вложенное исключение com.fasterxml.jackson.databind.exc .InvalidFormatException: (через цепочку ссылок: navid.usermanagementsys.domain.Personnel ["компания"])

Вы смотрели stackoverflow.com/questions/45110371/…?