我有一个域对象类User
(它是一个JPA实体):
@Entity
public class User {
private String name;
private boolean enabled = true;
// getters/setters
}
我正在尝试提供一个REST API,以允许客户端使用Spring 3 MVC创建新用户:
@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);
...
}
}
效果很好,但是我不知道将域对象用作@RequestBody 是否是一个好主意,因为我必须保护某些不应由客户端直接修改的字段(例如,在这种情况下为“启用” )。
这些替代方案的优点/缺点是什么:
第二种选择如下所示:
@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);
...
}
}
还有没有其他方法可以避免代码重复并且更易于维护?
最佳答案
还有另一个选项-您可以使用 DataBinder.setDisallowedFields(..)
(或使用.setAllowedFields(..)
)禁止提交一组给定的属性
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(..);
}
如果您具有一个或两个不同的属性,这很好。
否则,拥有一个特殊的对象(例如
ProfileDetails
或UserRequest
)更有意义。在这种情况下,我正在使用类似DTO的对象,然后从commons-beanutils用BeanUtils.copyProperties(..)
传输字段第三种,也许是更好的选择,是将所有与配置文件相关的字段放入一个单独的实体(与用户的
@OneToOne
映射)或一个@Embeddable
对象,并改为使用它。