繁体   English   中英

Spring Controller:使用域对象作为@RequestBody

[英]Spring Controller: use domain objects as @RequestBody

我有一个域 object class 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是否是个好主意,因为我必须保护一些不应由客户端直接修改的字段(即在这种情况下为“启用”)。

这些替代方案的优点/缺点是什么:

  1. 使用域对象并保护不允许用户修改的字段(例如将它们设置为 null 或手动设置为默认值)
  2. 使用一组新的辅助对象(类似于 DTO),例如只包含我想通过 REST API 和Z1D78DC8ED51214E518B5114FE249对象公开的字段的 UserRequest

第二种选择如下所示:

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

如果您有一个或两个不同的属性,这很好。

否则,使用特殊的 object(如ProfileDetailsUserRequest )更有意义。 我在这种情况下使用了类似 DTO 的 object,然后使用BeanUtils.copyProperties(..)从 commons-beanutils 传输字段

第三种可能更好的选择是将所有与配置文件相关的字段放入一个单独的实体(使用@OneToOne和用户映射)或@Embeddable object,然后使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM