Абстрактные классы и Spring MVC @ModelAttribute/@RequestParam
У меня есть иерархия классов моделей в моем приложении Spring/Hibernate.
При отправке формы POST в контроллер Spring MVC, существует ли какой-либо стандартный способ указания типа отправляемого объекта, поэтому Spring может создать экземпляр правильного подкласса типа, объявленного в @ModelAttribute или @RequestParam принимающего метода?
Например:
public abstract class Product {...}
public class Album extends Product {...}
public class Single extends Product {...}
//Meanwhile, in the controller...
@RequestMapping("/submit.html")
public ModelAndView addProduct(@ModelAttribute("product") @Valid Product product, BindingResult bindingResult, Model model)
{
...//Do stuff, and get either an Album or Single
}
Джексон может десериализовать JSON как определенный подтип, используя аннотацию @JsonTypeInfo. Я надеюсь, что Весна может сделать то же самое.
1 ответ
Джексон может десериализовать JSON как определенный подтип, используя аннотацию @JsonTypeInfo. Я надеюсь, что Весна может сделать то же самое.
Предполагая, что вы используете Джексона для преобразования типов (Spring использует Джексона автоматически, если находит его на пути к классам и у вас есть <mvc:annotation-driven/>
в вашем XML), то это не имеет ничего общего с Spring. Аннотируйте типы, и Джексон будет создавать правильные классы. Тем не менее, вам придется сделать instanceof
проверяет ваш метод контроллера Spring MVC.
Обновление после комментариев:
Посмотрите на 15.3.2.12 Настройка инициализации WebDataBinder. Вы могли бы использовать @InitBinder
метод, который регистрирует редактор на основе параметра запроса:
@InitBinder
public void initBinder(WebDataBinder binder, HttpServletRequest request) {
String productType = request.getParam("type");
PropertyEditor productEditor;
if("album".equalsIgnoreCase(productType)) {
productEditor = new AlbumEditor();
} else if("album".equalsIgnoreCase(productType))
productEditor = new SingleEditor();
} else {
throw SomeNastyException();
}
binder.registerCustomEditor(Product.class, productEditor);
}