I am trying to submit form data from a JSP to a controller and have the data bind to one of two implementations of an abstract class based on a "type" field in the form. I saw this post that sounded promising, but after creating and registering a converter, it is not being called: @ModelAttribute and abstract class
What am I missing? The wiring looks correct to me, but this is also my first time trying to configure this.
When I submit the form data, my controller throws this exception: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.project.types.Food]: Is it an abstract class?
Here is the abstract class structure:
abstract Food
String type
Banana extends Food
Apple extends Food
Here is my controller:
@RequestMapping(value = "/web/pickFood", method = RequestMethod.POST)
public ModelAndView foodSubmit(@ModelAttribute("food") Food food) {...}
My converter:
public class FoodConverter implements Converter<String, Food> {
@Override
public Food convert(String type) {
Food food = null;
switch (type) {
case "banana":
food = new Banana();
break;
case "apple":
food = new Apple();
break;
default:
throw new IllegalArgumentException("Unknown food type:" + type);
}
return food;
}
}
How I register the converter:
@Configuration
@EnableWebMvc
public class FoodWebMvCContext extends WebMvcConfigurerAdapter {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new FoodConverter());
}
}
And the form on my JSP, right now I just want to submit the type and see it convert to an empty food object of that type.
<form:form method="POST"
action="/web/pickFood"
modelAttribute="food">
<table>
<tr>
<td><form:label path="type">Type</form:label></td>
<td><form:input path="type" name="food"/></td>
</tr>
</table>
</form:form>
I was able to fix it by changing the input of my form from
<tr>
<td><form:label path="type">Type</form:label></td>
<td><form:input path="type" name="food"/></td>
</tr>
to
<tr>
<input type="text" name="food" />
</tr>