2011-09-14 13 views
8

Parece que no puedo obtener mi formulario para enlazar al control de casilla de verificación. Leí muchas publicaciones aquí e intenté algunas técnicas pero no tuve suerte. Tal vez un nuevo par de ojos te ayude.Encuadernación con resorte Lista <Object> con la forma: casillas de verificación

mi controlador:

public String editAccount(@RequestParam("id") String id, Model model) { 
    model.addAttribute("account", accountService.getAccount(id)); 
    model.addAttribute("allRoles", roleService.getRoles()); 
    return EDIT_ACCOUNT; 
} 

mi jsp:

<form:form action="" modelAttribute="account"> 
<form:checkboxes items="${allRoles}" path="roles" itemLabel="name" itemValue="id" delimiter="<br/>"/> 
</form> 

el HTML generado:

<span><input id="roles1" name="roles" type="checkbox" value="1"/><label for="roles1">User</label></span><span><br/><input id="roles2" name="roles" type="checkbox" value="2"/><label for="roles2">Admin</label></span><span><br/><input id="roles3" name="roles" type="checkbox" value="3"/><label for="roles3">SuperAdmin</label></span<input type="hidden" name="_roles" value="on"/> 

utilicé un segundo para cada bucle (no mostrado) para asegurarse de que el objeto modelo contenía los roles. Lo hace, sin embargo, ninguna de las casillas de verificación está marcada y cuando envío los roles, el objeto siempre está vacío. ¿Alguien puede decirme qué me estoy perdiendo?

Gracias

EDITAR

En este momento solo se dio cuenta de que podría ser útil para ver las cuentas y objetos de función:

public class Account { 

    private String username, firstName, lastName, email; 
    private List<Role> roles; 

    @NotNull 
    @Size(min = 1, max = 50) 
    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @NotNull 
    @Size(min = 1, max = 50) 
    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    @NotNull 
    @Size(min = 1, max = 50) 
    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

    @NotNull 
    @Size(min = 6, max = 50) 
    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public List<Role> getRoles() { 
     return roles; 
    } 

    public void setRoles(List<Role> roles) { 
     this.roles = roles; 
    } 

    public String toString() { 
     return ReflectionToStringBuilder.toString(this); 
    } 

} 

public class Role { 

private int id; 
private String name; 

public Role() {} 

public Role(int id, String name) { 
    this.id = id; 
    this.name = name; 
} 

public int getId() { 
    return id; 
} 

public void setId(int id) { 
    this.id = id; 
} 

@NotNull 
@Size(min = 1, max = 50) 
public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

}

editar # 2

Controlador Mensaje Método

@RequestMapping(value = "edit", method = RequestMethod.POST) 
public String updateAccount(@RequestParam("id") String id, @ModelAttribute("account") @Valid AccountEditForm form, BindingResult result) { 
    System.out.println("FORM VALUES AFTER: " + form); 
    return (result.hasErrors() ? EDIT_ACCOUNT : ACCOUNT_REDIRECT); 
} 

AccountEditForm es el objeto de formulario de respaldo. Cuando hago un GET agarro un objeto Account y paso los valores a un AccountEditForm antes de mostrar la pantalla. Adjuntaré el AccountEditForm solo por claridad. Es muy similar al objeto de cuenta. Acabo de separar los objetos de mi formulario de mis objetos modelo.

public class AccountEditForm { 

    private String username, firstName, lastName, email; 
    private List<Role> roles = new ArrayList<Role>(); 

    @NotNull 
    @Size(min = 1, max = 50) 
    public String getUsername() { 
     return username; 
    } 

    public void setUsername(String username) { 
     this.username = username; 
    } 

    @NotNull 
    @Size(min = 1, max = 50) 
    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    @NotNull 
    @Size(min = 1, max = 50) 
    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

    @NotNull 
    @Size(min = 6, max = 50) 
    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public List<Role> getRoles() { 
     return roles; 
    } 

    public void setRoles(List<Role> roles) { 
     this.roles = roles; 
    } 

    public String toString() { 
     return ReflectionToStringBuilder.toString(this); 
    } 

} 

editar # 3 Papel Editor de propiedades

public class RolePropertyEditor extends PropertyEditorSupport { 

    private Map<Integer, Role> roleMap = new HashMap<Integer, Role>(); 

    public RolePropertyEditor(List<Role> roleList) { 
     for (Role r : roleList) roleMap.put(r.getId(), r); 
    } 

    public void setAsText(String incomingId) { 
     Role role = roleMap.get(incomingId); 
     System.out.println("PROPERTY EDITOR ROLE " + role); 
     setValue(role); 
    } 

    public String getAsText() { 
     System.out.println("PROPERTY EDITOR ID " + ((Role)getValue()).getId()); 
     return String.valueOf(((Role)getValue()).getId()); 
    } 
} 

Definido en mi controlador como:

@InitBinder 
public void initBinder(WebDataBinder binder) { 
    binder.setAllowedFields(new String[] { 
      "username", "password", "confirmPassword", "firstName", "lastName", "email", "acceptTerms", "currentPassword" 
    }); 
    binder.registerCustomEditor(Role.class, new RolePropertyEditor(roleService.getRoles())); 
} 

editar # 4 NUEVO ProeprtyEditor

public class SecurityRolePropertyEditor extends PropertyEditorSupport { 

    private RoleService roleService; 

    public SecurityRolePropertyEditor(RoleService roleService) { 
     this.roleService = roleService; 
    } 

    public void setAsText(final String name) { 
     Role role = roleService.getRoleByName(name); 
     setValue(role); 
    } 
} 

Respuesta

3

Añadir un igual método para tu entidad Roles.

ver esto answer (Spring MVC Pre Populate Checkboxes): de una pregunta similar para más detalles.

+0

Gracias por la respuesta.Agregué iguales a mi objeto Role y ahora, cuando veo la pantalla, las casillas de verificación se completan correctamente, pero cuando realizo un cambio o envío, la propiedad de roles del objeto de la cuenta vinculada al formulario siempre está vacía. – blong824

+0

@ blong824 ¿El problema es que los objetos de rol no son secundarios, no se han rellenado en el objeto de la cuenta o no se han guardado? – Ralph

+0

Quité todo el código para guardar y simplemente agregué una declaración de impresión al método de publicación. El objeto de roles siempre está vacío. Por lo tanto, no está poblado en el objeto Cuenta. – blong824

0

Encontré que el problema era utilizar una lista de objetos complejos en la ruta. la caja parece enviar solo lo que está en el campo "valor". SO Cambié la variable binded a la ruta a List en lugar de List y descubrí que la lista está poblada por los ID.

0

Parece que falta la implementación equals y el método hashCode en sus entidades.

Cuestiones relacionadas