У меня есть универсальный Rest-Constroller, который должен создать сущность из имени сущности - тело запроса, представляющее свойства сущностей. Мне нужно вручную сопоставить тело запроса с целевым классом.
Я уже пробовал разные способы настроить способ, которым мой RestController десериализует данные, и считаю, что мой текущий подход является самым простым. Теперь я регистрирую @PostMapping и извлекаю entityName, который я использую для определения правильного класса, и сущность @RequestBody StringJJ, которую я преобразую через ObjectMapper в определенный класс.
, но при десериализации LocalDate у меня возникают проблемы (Примечание: мои строки даты имеют формат 'гггг-ММ-дд'Т'ЧЧ: мм: сс.СССЗ', где времена нули).
Я использую Springboot 2.1.6.RELEASE с jpa 2.1.9 ипоэтому не требуется настраиваемая обработка свойств LocalDate / LocalDateTime в моих RestControllers, если я использую параметр сущности @RequestBody XXXEntity. Но при внедрении компонента OnjectMapper в мой RestController и попытке десериализации objectMapper.readValue (entityJson, entityClass) происходит сбой в свойствах LocalDate.
Как я могу десериализовать способ, которым Spring делает (правильно), если класс сущности известен заранее?
1.) Исключение без пользовательской конфигурации: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Невозможно создать экземпляр java.time.LocalDate
(не существует создателей, таких как конструкция по умолчанию): нет конструктора String-аргумент/ factory метод для десериализации из строкового значения ('2019-10-29T00: 00: 00.000Z')
2.) При использовании пользовательского JSR310Module ObjecktMapper
java.time.format.DateTimeParseException: Текст '2019-10-29T00: 00: 00.000Z' не может быть проанализирован, найден неразобранный текст по индексу 10
ObjectMapper objectMapper = Jackson2ObjectMapperBuilder.json()
.serializationInclusion(JsonInclude.Include.NON_NULL)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.modules(new JSR310Module())
.build();
Same error with custom DateFormat:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
objectMapper.setDateFormat(df);
Я попытался зарегистрировать десериализатор LocalDateTime для LocalDate das well:
Jackson2ObjectMapperBuilder.json()
.deserializerByType(LocalDate.class, LocalDateTimeDeserializer.INSTANCE)
Результат улучшается ... поэтому не удается выполнить очистку, когда я нажимаю часовой пояс UTC: java.time.format.DateTimeParseException: текст '2019-10-29T00: 00: 00.000Z' не может быть проанализирован, найден неразобранный текст с индексом 23
Вот так выглядит мой контроллер:
@Autowired
public AdminRestController(EntityService entityService, ObjectMapper objectMapper) {
this.entityService = entityService;
this.objectMapper = objectMapper;
}
...
@Transactional
@PostMapping(value = "/entities/{entityName}")
public List<T> createEntity(@PathVariable String entityName, @RequestBody String entityJson) {
T newEntity = constructEntity(entityName, entityJson);
entityService.create(newEntity);
...
}
...
private T constructEntity(String entityName, String entityJson) {
Class<T> entityClass;
try {
entityClass = findClassByName(entityName);
} catch (ClassNotFoundException e) {
throw new IllegalStateException("Entity " + entityName + " unknwon.");
}
try {
T entity = objectMapper.readValue(entityJson, entityClass);
return entity;
} catch (IOException e) {
throw new IllegalStateException("Unable to construct entity " + entityName + " from provided data.", e);
}
}