2011-08-12 21 views
5

Tengo una clase de objeto de dominio User (que es una entidad JPA):Controlador de primavera: objetos de uso de dominio como @RequestBody

@Entity 
public class User { 
    private String name; 
    private boolean enabled = true; 
    // getters/setters 
} 

y estoy tratando de ofrecer una API REST para permitir a los clientes crear nuevos usuarios , utilizando Spring MVC 3:

@Controller 
public class UserController { 
    @RequestMapping(value="/user", method=RequestMethod.POST) 
    @ResponseBody 
    public String createRealm(@RequestBody User user) { 
      user.setEnabled(true); // client is not allowed to modify this field 
      userService.createUser(user); 
      ... 
    } 
} 

funciona muy bien, pero no sé si es una buena idea utilizar los objetos de dominio como @RequestBody, porque tengo que proteger algunos campos que no deberían estar directamente modificado por el cliente (es decir. "habilitado" en este caso).

¿Cuáles son las ventajas/desventajas de estas alternativas:

  1. utilizar los objetos del dominio y proteger los campos no se permite al usuario modificar (por ejemplo, las puso en nulo o en su valor predeterminado por mano)
  2. Use un nuevo conjunto de objetos auxiliares (algo similar a un DTO), como un UserRequest que solo contiene los campos que quiero exponer a través de la API REST, y asigne (es decir, con Dozer) al objetos de dominio.

La segunda alternativa tiene el siguiente aspecto:

@Entity 
public class User { 
    private String name; 
    private boolean enabled = true; 
    // getters/setters 
} 

public class UserRequest { 
    private String name; 
    // enabled is removed 
    // getters/setters 
} 

@Controller 
public class UserController { 
    @RequestMapping(value="/user", method=RequestMethod.POST) 
    @ResponseBody 
    public String createRealm(@RequestBody UserRequest userRequest) { 
      User user = ... // map UserRequest -> User 
      userService.createUser(user); 
      ... 
    } 
} 

¿Hay alguna otra forma que evite la duplicación de código y es más fácil de mantener?

Respuesta

5

Hay otra opción - que puede no permitir la presentación de un conjunto dado de propiedades, utilizando el DataBinder.setDisallowedFields(..) (o usando .setAllowedFields(..))

@InitBinder 
public void initBinder(WebDataBinder binder) { 
    binder.setDisallowedFields(..); 
} 

Esto está bien si usted tiene uno o dos propiedades que difieren.

De lo contrario, tener un objeto especial (como ProfileDetails o UserRequest) tiene más sentido. Estoy usando un objeto tan DTO similar para este escenario y luego transferir los campos con BeanUtils.copyProperties(..) de bienes comunes BeanUtils

Un tercer quizás mejor opción, es poner todos los campos relacionadas con los perfiles a una entidad separada (mapeado con @OneToOne con el usuario) o a un objeto @Embeddable, y úselo en su lugar.

+0

Gran respuesta Bozho, gracias. ¿Qué piensas sobre la creación de una anotación no permitida para anotar los campos que no deseas exponer (creo que Spring no ofrece nada de eso), y llamar a binder.setDisallowedFields (MyUtils.findDisallowedFields (User.class))? Una anotación permitida podría ser aún más segura. –

+0

sí, parece razonable. – Bozho

+0

Lo siento, te estoy molestando. ¿Crees que es un buen lugar para usar algún tipo de punto de corte AOP? –

Cuestiones relacionadas