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