Я унаследовал достаточно простой контроллер . Проблема в том, что он возвращает интерфейс и Spring AFAIK не может десериализовать , если не может создать экземпляр . Я могу исправить это с помощью одной аннотации на (каждом) транспортном интерфейсе, но это исключает любые преимущества возврата интерфейса в отличие от конкретного класса и выходит за пределы обязанностей DTO.
Поэтому мой вопрос может что-то быть сделано на стороне client , чтобы использовать контроллер как есть? Если нет, то можно ли что-то сделать с контроллером кодом без изменения UserDto
интерфейса?
Вот контроллер Rest:
@RestController
@RequestMapping(value = "/user")
public class UserController {
// ...
@RequestMapping(value = "/create", method = RequestMethod.POST)
public UserDto create(@RequestBody UserDto user) throws ServiceException {
return service.save(user);
}
// ...
}
Вот тест, который действует как клиент и потребляет контроллер:
@Test
public void UserControllerRealTest() {
ClientUser user1 = new ClientUserImpl("ADSMarko", "Marko Savić", "Slayer!!!");
RestTemplate rt = new RestTemplate();
HttpEntity<ClientUser> request = new HttpEntity<>(user1);
UserDto result1 = rt.postForObject(createUrl, request, UserDtoImpl.class);
System.out.println("User " + result1.getUsername() + " saved with id " + result1.getId());
ClientUser user2 = new ClientUserImpl("Marko", "Marko Savić", "Slayer!!!");
request = new HttpEntity<>(user2);
ParameterizedTypeReference<UserDto> ptr = new ParameterizedTypeReference<UserDto>() {};
ResponseEntity<UserDto> re = rt.exchange(createUrl, HttpMethod.POST, request, ptr);
UserDto result2 = re.getBody();
System.out.println("User " + result2.getUsername() + " saved with id " + result2.getId());
}
Ниже приведен интерфейс. Он работает с ведущей аннотацией, но без него выдает com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
@JsonDeserialize(as = UserDtoImpl.class) // Or the longer annotation
public interface UserDto {
// ... just getters and setters
}