2010-12-02 16 views
6

imaginar un código como este:@ModelAttribute en un método

@RequestMapping(value="/users", method=RequestMethod.GET) 
public String list(Model model) { 
    ... 
} 

@InitBinder("user") 
public void initBinder(WebDataBinder binder) { 
    binder.setDisallowedFields("password"); // Don't allow user to override the value 
} 

@ModelAttribute("user") 
public User prepareUser(@RequestParam("username") String username){ 
    ... 
} 

@RequestMapping(value="/user/save", method=RequestMethod.POST) 
public String save(@ModelAttribute("user") User user, Model model) {   
    ... 
} 

utilizo un aglutinante init para evitar que un campo se puede binded y me marca un método (prepareUser()) con @ModelAttribute para preparar mi objeto Usuario antes de que esté encuadernado. Entonces cuando invoco/user/save, se ejecutan initBinder() y prepareUser().

He configurado "usuario" en @InitBinder y @ModelAttribute para que Spring-MVC pueda entender que este método solo debe aplicarse antes de ejecutar un método con @ModelAttribute ("usuario").

El problema es que el método anotado con @ModelAttribute ("usuario") se ejecuta antes de cada método asignado de este controlador. Por ejemplo, si invoco/users prepareUser se ejecuta antes del método list(). ¿Cómo puedo hacer que este preparador se ejecute solo antes de que el método save() tenga todos los métodos en el mismo controlador?

Gracias

+0

¿Qué hace 'prepareUser' en realidad? – skaffman

+0

@skaffman toma el nombre de usuario param y carga el objeto Usuario desde la base de datos, por lo que no se sobrescriben todos los datos que no pueden enlazarse (por ejemplo, contraseña) con valores nulos cuando se conserva después de la vinculación – Javi

Respuesta

7

eso no es realmente lo que @ModelAttribute es para. Si lo usa como un parámetro de método, pone el parámetro anotado en el modelo (eso está bien). Si lo pone en un método, se lo llamará siempre para proporcionar datos de referencia a los que todos los métodos del controlador deberían tener acceso.

Si desea tomar el control de la creación de su objeto Usuario, tiene varias opciones. Los dos que están más obvio para mí son:

  1. utilice su método InitBinder añadir un nuevo editor personalizado (una clase PropertyEditor) para la construcción de objetos de usuario,
  2. Utilice la conversion service in Spring 3 para convertir los nombres de usuario de cuerda a los objetos de usuario.
+0

OK Entiendo que deba hacerse en initbinder con un editor de propiedades, pero no entiendo cuál es el verdadero propósito de los métodos con la anotación @ModelAttribute. ¿Me puede decir un ejemplo para su uso típico? Y también, ¿por qué se puede dar una cadena como valor en la anotación (por ejemplo, "usuario" en @ModelAttribute ("usuario")) si se ejecuta antes de cada método? – Javi

+1

@Javi Buenas preguntas. Primero, no creo que * debería * hacerse en initbinder, es solo posible. Prefiero el enfoque más moderno del servicio de conversión. Un uso típico de los métodos anotados con @ModelAttribute es para los datos de referencia que requieren todos los métodos en un controlador. Para utilizar una tienda de mascotas como ejemplo, un controlador puede tener métodos para mostrar mascotas y ver mascotas individuales, pero todas necesitan información para un menú de Categorías ("Conejos", "Perros", etc.). Le ahorra tener que repetir esto en cada método. – GaryF

+2

@Javi En cuanto a por qué puede darle un nombre, es para que Spring pueda colocar el objeto devuelto en el modelo con ese nombre. El ejemplo en el manual de Spring merece una mirada: http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-ann-modelattrib – GaryF

Cuestiones relacionadas