with type polymorphic only instantiated information additional java inheritance binding spring-mvc jackson

java - type - jackson nested json



Clases abstractas y Spring MVC @ ModelAttribute/@ RequestParam (1)

Tengo una jerarquía de clases modelo en mi aplicación Spring / Hibernate.

Al enviar un formulario POST a un controlador MVC de Spring, ¿hay alguna forma estándar de especificar el tipo de objeto que se envía, de modo que Spring pueda instanciar la subclase correcta del tipo declarado en @ModelAttribute o @RequestParam del método de recepción?

Por ejemplo:

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 }

Jackson puede deserializar JSON como un subtipo específico utilizando la anotación @JsonTypeInfo. Espero que Spring pueda hacer lo mismo.


Jackson puede deserializar JSON como un subtipo específico utilizando la anotación @JsonTypeInfo. Espero que Spring pueda hacer lo mismo.

Suponiendo que usa Jackson para la conversión de tipos (Spring usa Jackson automáticamente si lo encuentra en classpath y tiene <mvc:annotation-driven/> en su XML), entonces no tiene nada que ver con Spring. Anota los tipos, y Jackson instanciará las clases correctas. Sin embargo, tendrá que hacer instanceof verificaciones en su método de controlador Spring MVC.

Actualización después de los comentarios:

Eche un vistazo a 15.3.2.12 Personalización de la inicialización de WebDataBinder . Puede usar un método @InitBinder que registre un editor basado en un parámetro de solicitud:

@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); }