当前位置: 首页 > 知识库问答 >
问题:

验证不适用于嵌套对象

步兴为
2023-03-14

我试图通过将请求参数直接绑定到用户实体来简化我的代码,而不是一个字段一个字段地复制值,但是我似乎不能通过这种方式得到验证。

控制器:

    @Autowired
    private UserValidator validator;

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(validator);
    }

    @PreAuthorize("isAnonymous()")
    @RequestMapping("/register")
    public List<String> register(@Valid @ModelAttribute RegisterRequest request, BindingResult result){
        return result.getAllErrors().stream().map(error -> error.getCodes()[1]).collect(Collectors.toList());
    }

验证器:

@Component
public class UserValidator implements Validator {

    @Autowired
    private UserRepository repo;

    @Override
    public boolean supports(Class<?> clazz) {
        return clazz.equals(RegisterRequest.class)||clazz.equals(User.class);
    }

    @Override
    public void validate(Object target, Errors errors) {
        if(target instanceof RegisterRequest){
            RegisterRequest request = (RegisterRequest)target;
            if(isRegistered(request))
                errors.rejectValue("User.Email", "InUse");
            if(!isRepassCorrect(request))
                errors.rejectValue("Repassword", "NoMatch");
        }

    }

    private boolean isRegistered(RegisterRequest request){
        return repo.findByEmail(request.getUser().getEmail())!=null;
    }

    private boolean isRepassCorrect(RegisterRequest request){
        return request.getPassword().equals(request.getRepassword());
    }

}

模型(注意嵌套对象用@Valid标注):

public class RegisterRequest {

    @Valid
    private User user = new User();

    @NotEmpty
    private String password;

    @NotEmpty
    private String repassword;

    //Generated getters and setters for all fields

}

@Entity
@Table(name = "users")
public class User implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 3726459440738726042L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @NotEmpty
    @Email
    @Column(name = "email", nullable = false)
    private String email;

    @NotEmpty
    @Column(name = "hash", nullable = false)
    private String hash;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(referencedColumnName = "id")
    private UserRole role;

    @Column(name = "enabled", nullable = false)
    private boolean enabled;

    @NotEmpty
    @Column(name = "name", nullable = false)
    private String name;

    @Column(name = "company")
    private String company;

    //Getters, setters, equals and hashCode

}

问题是只有密码和重新密码字段被正确验证,用户类中的验证注释被忽略,任何密码匹配的请求都通过,但它应该会出现错误。空密码或不同的密码会按预期出现错误。

共有1个答案

支嘉祥
2023-03-14

initBinder中使用addValidator方法而不是setValidator,并通过在注释中添加MaV名称来告诉它要验证哪个MaV对象

@InitBinder("request")

... @Valid @ModelAttribute("request") RegisterRequest request
 类似资料:
  • 六羟甲基三聚氰胺六甲醚。。在某些情况下,我有一个对象需要在hazelcast实例上执行操作。所以我实现了HazelcastInstanceAware接口,但这似乎不适用于嵌套类。。。 以下核心输出"null"到控制台: 公共类NullError实现可序列化,HazelcastInstanceAware{私有瞬态HazelcastInstance instance1;私有瞬态HazelcastIns

  • 问题内容: 我有一个注入了Facade对象的Jersey资源。这是在我的配置中,并且立面被很好地注入了。外墙包含一个DAO类,该类也应注入并在同一类中配置。现在到我的问题;DAO类为null。因此,不注射。 工厂实例非常简单。他们只是调用构造函数并将参数传递给它。 奇怪的是,当我使用bind(Class object)而不是bindFactory时,这绝对可以正常工作。 编辑 工厂工厂 问题答案:

  • 我正在使用spring(4.2.0.RELEASE)、hibernate validator(5.2.1.Final)和validation api(1.1.0.Final)对后端应用程序进行JSR验证,配置如下:, 但是没有一个JSR303注释在我的应用程序中工作。 注意:在POJO类上添加了JSR303注释,在服务类(使用POJO)上添加了@Validated注释,还尝试在方法级别添加@Val

  • 我正在尝试使用Hibernate Validator 5.0.1和JSF2.2,但自mojarra版本2.2.3以来,它们的集成似乎被破坏了。我创建了一个小应用程序来演示这个问题,并获得异常“javax.servlet.ServletException:表达式错误:命名对象:未找到javax.faces.Bean”在Tomcat 7.0.42上运行时。 还有其他人有这个问题吗? webapp/页面

  • 我使用的是OpenApi规范,这是生成类的代码示例: 我想禁止发送以下请求: 如果我使用了它看起来像: 有什么方法可以使用文件做同样的事情吗?

  • Elasticsearch排序不适用于嵌套字段。它显示了升序和降序的混合值。比如40,30,50。它不是按升序显示的:30,40,50 查询: