2

我有以下豆:

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

和这个:

public class AdminRole {    

    @Id
    @Column(name = "role_id", nullable = false, unique = true)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_id")
    @SequenceGenerator(name = "user_id", sequenceName = "user_id")
    private Long id;

    @Column(name = "role")
    private String role;
    ....
}

内部控制器:

@RequestMapping(value = "/admin/addNewAdmin")
public String adminUsers(@Valid TerminalAdmin terminalAdmin,
            BindingResult bindingResult, ModelMap model, Principal principal, HttpSession session) {

从客户端我发送以下请求:

在此处输入图像描述

terminalAdmin 来的方法长这样

在此处输入图像描述

  1. 为什么 spring 将值写入role字段?
  2. 如何强制spring写入250/251进入id字段?

附言

我试着写

InitBinder
public void initBinder(WebDataBinder binder) {
    binder.registerCustomEditor(AdminRole.class, new PropertyEditorSupport() {
        public void setAsText(String name) {
            ....
        }
    });
}

setAsText方法不调用。

4

1 回答 1

0

这不是将模型对象填充到表单中的好习惯,因为如果您的 init binder 未正确配置,Spring 可以将字段绑定到对象,即使它们未填充到视图中也是如此。

最简单的方法是创建 DTO 对象,例如。您可以创建填充到视图中的 AdminTerminalDTO 或 AdminTerminalForm。

表单可以包含与 AdminTerminal 相同的字段,不包括 ID 字段或任何其他敏感字段。您不能从视图中插入新 ID,因为它会导致数据库完整性错误。

成功验证后,您只需使用 DTO/Form 对象填充模型对象即可。

此外,您的 JSR-303 注释似乎没有以正确的方式使用。

@Size 注释不是检查字符串长度的正确验证。您必须改用@Length。您使用 @Size 检查数组的长度。@Size 也适用于字符串,但 @Length 更准确。

  1. 您不能只发送一个 Integer 并尝试绑定到您的 Set(spring 做了一些奇怪的绑定,如您现在所见)。相反,您已经在控制器中完成了 addNewAdmin 方法,该方法已经通知它添加了一个管理员用户。
  2. 您必须在此方法中在服务器端分配管理员角色。首先,您可以使用 DTO,其中将包含例如。用户名、密码和其他字段。您使用正确的 JSR-303 注释对它们进行注释。使用 bindingResult 检查是否有任何验证错误。如果表单验证良好,您只需将 DTO/Form 对象转换为模型对象。然后您可以添加管理员角色并保留您的模型对象。

如果这些提示还不够,我可以编写一些示例代码。

编辑:

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

}

我把它写成一个例子,这不是一个现成的代码

于 2015-10-31T10:49:50.560 回答