2011-08-12 30 views
5

Tôi có một lớp đối tượng miền User (nó là một thực thể JPA):mùa xuân Bộ điều khiển: đối tượng sử dụng tên miền như @RequestBody

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

Và tôi đang cố gắng để cung cấp một API REST để cho phép khách hàng để tạo người dùng mới , sử dụng 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); 
      ... 
    } 
} 

nó hoạt động tuyệt vời, nhưng tôi không biết nếu nó là một ý tưởng tốt để sử dụng các đối tượng miền như @RequestBody, bởi vì tôi phải bảo vệ một số lĩnh vực mà không nên trực tiếp sửa đổi bởi khách hàng (I E. "đã bật" trong trường hợp này).

những ưu/nhược điểm của những lựa chọn thay thế là gì:

  1. Sử dụng miền đối tượng và bảo vệ các lĩnh vực người dùng không được phép sửa đổi (ví dụ đặt chúng vào null hoặc giá trị mặc định của nó bằng cách tay)
  2. Sử dụng bộ mới của các đối tượng quen thuộc (cái gì đó tương tự như DTO), chẳng hạn như UserRequest chỉ chứa các trường tôi muốn hiển thị thông qua REST API và ánh xạ chúng (ví dụ: Dozer) đối tượng miền.

Giải pháp thay thế thứ hai trông như thế này:

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

Có cách nào khác mà tránh được sự trùng lặp mã và dễ dàng hơn để duy trì?

Trả lời

5

Có một tùy chọn - bạn có thể không cho phép việc nộp một tập hợp các thuộc tính, sử dụng DataBinder.setDisallowedFields(..) (hoặc sử dụng .setAllowedFields(..))

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

này là tốt nếu bạn có một hoặc hai thuộc tính khác nhau.

Nếu không, có một đối tượng đặc biệt (như ProfileDetails hoặc UserRequest) sẽ có ý nghĩa hơn. Tôi đang sử dụng đối tượng giống như DTO cho trường hợp này và sau đó chuyển trường bằng BeanUtils.copyProperties(..) từ commons-beanutils

Tùy chọn thứ ba, có lẽ tốt hơn là đặt tất cả các trường liên quan đến hồ sơ vào một thực thể riêng biệt (ánh xạ với @OneToOne) với người dùng) hoặc đối tượng @Embeddable và sử dụng đối tượng đó thay thế.

+0

Câu trả lời tuyệt vời Bozho, cảm ơn bạn. Bạn nghĩ gì về việc tạo chú thích không được phép để chú thích các trường bạn không muốn hiển thị (tôi nghĩ Spring không cung cấp bất cứ thứ gì như thế), và gọi binder.setDisallowedFields (MyUtils.findDisallowedFields (User.class))? Một chú thích được phép có thể thậm chí còn an toàn hơn. –

+0

có, âm thanh hợp lý. – Bozho

+0

Xin lỗi tôi đang làm phiền bạn. Bạn có nghĩ rằng đó là một nơi tốt để sử dụng một số loại AOP pointcut có thể? –

Các vấn đề liên quan