Абстрактные классы и 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);
}
Другие вопросы по тегам