I want to share the very same Java types for an API server and an API client. It seems I cannot use an abstract interface Pet
to type a field of a controller method parameter @ModelAttribute Family family
.
What I tried
- Searched for annotations like Jackson @JsonDeserialize(as = ...)
: none exists
- Custom ConversionService
: not called for initializing nested bean properties by BeanWrapperImpl
- Custom WebDataBinder
: overkill
Full test case:
public interface Pet { String getName(); }
public static class Family {
private Pet pet;
public Pet getPet() { return pet; }
public void setPet(Pet pet) { this.pet = pet; }
}
public static class Dog implements Pet {
private String name;
public String getName() {return name; }
public void setName(String name) { this.name = name;}
}
@RestController
public static class PetController {
@PostMapping("/family")
public String createFamily(@ModelAttribute Family family) {
return "Created family with pet " + family.getPet().getName();
}
}
private MockMvc mockMvc;
@BeforeEach
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(new PetController())
.build();
}
@Test
public void testPetControllerCreateFamily() throws Exception {
mockMvc.perform(post("/family")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.param("pet.name", "Fido"))
.andExpect(status().isOk())
.andExpect(content().string("Created family with pet Fido"));
}
Comment From: snicoll
Thanks for the suggesting but that sounds pretty logical to me given that we don't have any information about the type that should actually be created. Guessing is a bad idea so we won't do that.
For any follow-up as to how you could potentially implement something like this, follow on StackOverflow.