Java 在spring中定制表单bean创建过程
我有以下bean:Java 在spring中定制表单bean创建过程,java,spring,spring-mvc,spring-form,spring-mvc-initbinders,Java,Spring,Spring Mvc,Spring Form,Spring Mvc Initbinders,我有以下bean: public class TerminalAdmin { @Id @Column(name = "admin_id", nullable = false, unique = true) @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id") @SequenceGenerator(name = "user_id", sequenceName = "us
public class TerminalAdmin {
@Id
@Column(name = "admin_id", nullable = false, unique = true)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id")
@SequenceGenerator(name = "user_id", sequenceName = "user_id")
private Long adminId;
@Column(name = "email", nullable = false)
private String email;
@Column(name = "phone")
@Size(max = 255)
private String phone;
@Size(max = 255)
@Column(name = "name")
private String name;
@Column(name = "registration_date")
@Temporal(TemporalType.TIMESTAMP)
private Calendar createDate;
@Column(name = "password", nullable = false)
@Size(min=1, max = 255, message = "введите пароль длиной от 1 до 255 символов")
private String password;
@ManyToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinTable(name = "admin_role", joinColumns = {
@JoinColumn(name = "admin_id", nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "role_id",
nullable = false) })
private Set<AdminRole> adminRoles;
@Column(name = "blocked")
private boolean blocked;
...
}
内部控制器:
@RequestMapping(value = "/admin/addNewAdmin")
public String adminUsers(@Valid TerminalAdmin terminalAdmin,
BindingResult bindingResult, ModelMap model, Principal principal, HttpSession session) {
我从客户端发送以下请求:
terminalAdmin得出的方法如下所示
role
字段李>
250
/251
写入id字段InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(AdminRole.class, new PropertyEditorSupport() {
public void setAsText(String name) {
....
}
});
}
但是
setAsText
方法不会调用。将模型对象填充到表单中不是一个好的做法,因为如果init绑定器配置不正确,Spring可以将字段绑定到对象,即使它们没有填充到视图中
最简单的方法是创建DTO对象,例如,您可以创建填充到视图中的AdminTerminalTo或AdminTerminalForm
表单可以包含与AdminTerminal相同的字段,不包括ID字段或任何其他敏感字段。您不能从视图中插入新ID,因为它可能导致DB完整性错误
成功验证后,只需持久化模型对象,并用DTO/Form对象填充它
此外,您的JSR-303注释似乎没有以正确的方式使用
@Size注释不适合作为检查字符串长度的验证。您必须使用@Length。您可以使用@Size检查数组的长度@大小也适用于字符串,但@Length更精确
公共类终端管理器{
私有字符串用户名;
@长度(最大值=255)
公共字符串getUsername(){
返回用户名;
}
public void setUsername(字符串用户名){
this.username=用户名;
}
公共终端管理员convertToTerminalAdmin(){
TerminalAdmin TerminalAdmin=新的TerminalAdmin();
terminalAdmin.setUsername(this.username);
返回终端管理员;
}
}
@实体
@桌子
公共类终端管理员{
@身份证
@列(name=“admin\u id”,null=false,unique=true)
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“用户id”)
@SequenceGenerator(name=“user\u id”,sequenceName=“user\u id”)
私有长管理员ID;
@列(name=“email”,nullable=false)
私人字符串电子邮件;
@列(name=“phone”)
@尺寸(最大值=255)
私人电话;
@尺寸(最大值=255)
@列(name=“name”)
私有字符串名称;
@列(name=“注册日期”)
@时态(TemporalType.TIMESTAMP)
私人日历创建日期;
@列(name=“password”,null=false)
@尺寸(最小值为1,最大值为255,信息为“(最小值为255”)
私有字符串密码;
@ManyToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinTable(name=“admin_role”,joinColumns={
@JoinColumn(name=“admin\u id”,nullable=false)},
inverseJoinColumns={@JoinColumn(name=“role\u id”,
nullable=false)})
私人设置管理员角色;
@列(name=“blocked”)
私有布尔阻塞;
...
}
@请求映射(value=“/admin/addNewAdmin”)
公共字符串adminUsers(@Valid TerminalAdminDTO TerminalAdminDTO,
BindingResult BindingResult,ModelMap模型,主体,HttpSession会话){
if(result.hasErrors()){
返回“errorPage”;
}否则{
createAdminUser(terminalAdminDTO);
返回“successPage”;
}
}
@服务
@交易的
公共类UserServiceImpl实现UserService{
私有最终内部管理角色ID=0;
@自动连线
实体管理器实体管理器;
public void createAdminUser(TerminalAdminTo TerminalAdminTo){
TerminalAdmin TerminalAdmin=TerminalAdminTo.convertToTerminalAdmin();
AdminRole AdminRole=entityManager.find(AdminRole.class,ADMIN\u ROLE\u ID);
terminalAdmin.getAdminRoles().add(adminRole);
entityManager.create(terminalAdmin);
}
}
我将其作为一个示例来编写,这不是现成的代码请提供示例“您不能从视图中插入新ID,因为它可能导致数据库完整性错误”-这就是我们有限制的原因。但更重要的是:OP的案例中不会插入ID
@Length
不是标准注释。如果不使用Hibernate验证器,您甚至无法使用它。“你不能只发送一个整数,然后尝试绑定到你的集合”-是的,你可以,如果你知道怎么做的话。“您必须在服务器端分配管理员角色”-绑定发生在服务器端,不是吗?如果不使用Hibernate验证程序,您甚至无法使用它。“您不能只发送一个整数,然后尝试绑定到您的集合”-是的,您可以,如果您知道如何按照此建议执行-如果您知道如何执行,一切都可以完成,这样发送整数可能会导致严重的安全泄漏,您可以通过这种方式添加任何角色,而无需进行适当的验证“您必须在服务器端分配管理员角色”-绑定发生在服务器端,不是吗?是吗?它绑定了所有东西,而不是关于约束的管理员角色。为什么你还要尝试约束新对象id呢?如果你不按名称引用我,我不会得到通知,也不会
InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(AdminRole.class, new PropertyEditorSupport() {
public void setAsText(String name) {
....
}
});
}
public class TerminalAdminDTO {
private String username;
@Length(max = 255)
public String getUsername(){
return username;
}
public void setUsername(String username){
this.username = username;
}
public TerminalAdmin convertToTerminalAdmin(){
TerminalAdmin terminalAdmin = new TerminalAdmin();
terminalAdmin.setUsername(this.username);
return terminAdmin;
}
}
@Entity
@Table
public class TerminalAdmin {
@Id
@Column(name = "admin_id", nullable = false, unique = true)
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id")
@SequenceGenerator(name = "user_id", sequenceName = "user_id")
private Long adminId;
@Column(name = "email", nullable = false)
private String email;
@Column(name = "phone")
@Size(max = 255)
private String phone;
@Size(max = 255)
@Column(name = "name")
private String name;
@Column(name = "registration_date")
@Temporal(TemporalType.TIMESTAMP)
private Calendar createDate;
@Column(name = "password", nullable = false)
@Size(min=1, max = 255, message = "введите пароль длиной от 1 до 255 символов")
private String password;
@ManyToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
@JoinTable(name = "admin_role", joinColumns = {
@JoinColumn(name = "admin_id", nullable = false) },
inverseJoinColumns = { @JoinColumn(name = "role_id",
nullable = false) })
private Set<AdminRole> adminRoles;
@Column(name = "blocked")
private boolean blocked;
...
}
@RequestMapping(value = "/admin/addNewAdmin")
public String adminUsers(@Valid TerminalAdminDTO terminalAdminDTO,
BindingResult bindingResult, ModelMap model, Principal principal, HttpSession session) {
if(result.hasErrors()){
return "errorPage";
}else{
userService.createAdminUser(terminalAdminDTO);
return "successPage";
}
}
@Service
@Transactional
public class UserServiceImpl implements UserService {
private final int ADMIN_ROLE_ID = 0;
@Autowired
EntityManager entityManager;
public void createAdminUser(TerminalAdminDTO terminalAdminDTO){
TerminalAdmin terminalAdmin = terminalAdminDTO.convertToTerminalAdmin();
AdminRole adminRole = entityManager.find(AdminRole.class,ADMIN_ROLE_ID);
terminalAdmin.getAdminRoles().add(adminRole);
entityManager.create(terminalAdmin);
}
}