Spring,从异常中获取多个模型违规

时间:2017-05-29 20:47:15

标签: java spring

我正在尝试验证用户注册。场景很常见:如果存在用户名或电子邮件,则应用程序必须通知用户违反了哪个字段(唯一约束)。到目前为止,我已经完成了以下操作:此方法处理注册。基本上我尝试提交事务(插入),如果失败,则使用try catch捕获异常。

@Entity
@Table(name = "users")
public class User implements Serializable{

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="user_id")
private Long user_id;

@Column(name="username")
@NotEmpty(message = "*Username is required")
@Length(min = 5, max = 20,  message = "*Your username can have min 5 and max 20 characters")
private String username;

@Column(name="password")
@NotEmpty(message = "*Password is reqired")
@Transient
private String password;

@Column(name="email")
@Email(message = "*Please provide a valid Email")
@NotEmpty(message = "*Email is required")
private String email;

@Column(name="enabled")
private int enabled;

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public int getEnabled() {
    return enabled;
}

public void setEnabled(int enabled) {
    this.enabled = enabled;
}

public Long getUser_id() {
    return user_id;
}

public void setUser_id(Long user_id) {
    this.user_id = user_id;
}
}

这是我的模特课:

<form autocomplete="off" action="#" th:action="@{/registration}"
                th:object="${user}" method="post" class="form-horizontal"
                role="form">
                <h2>Registration Form</h2>
                <div class="form-group">
                    <div class="col-sm-9">
                    <label th:if="${#fields.hasErrors('username')}" th:errors="*{username}"
                            class="validation-message"></label>
                    <input type="text" th:field="*{username}" placeholder="Username"
                            class="form-control" /> 
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <input type="text" th:field="*{email}" placeholder="Email"
                            class="form-control" /> <label
                            th:if="${#fields.hasErrors('email')}" th:errors="*{email}"
                            class="validation-message"></label>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-9">
                        <input type="password" th:field="*{password}"
                            placeholder="Password" class="form-control" /> <label
                            th:if="${#fields.hasErrors('password')}" th:errors="*{password}"
                            class="validation-message"></label>
                    </div>
                </div>

                <div class="form-group">
                    <div class="col-sm-9">
                        <button type="submit" class="btn btn-primary btn-block">Register User</button>
                    </div>
                </div>
                <span th:utext="${successMessage}"></span>
            </form>

这是我的注册页面:

public function getStatsByDQL(User $user,  String $col)
{

    $midNight = date_create('00:00:00')->format('Y-m-d H:i:s');
    $parameters = (array('user' => $user, 'date' => $midNight, 

    ));
    $em2 = $this->getDoctrine()->getManager()->getRepository('AppBundle:ExerciseStats')
        ->createQueryBuilder('g')
        ->setParameters($parameters)
        ->where('g.user = :user', 'g.timestamp < :date')
        ->select('g.'. $col)
        ->setMaxResults(1)
        ->join('g.user', 'user')
        ->orderBy( 'g.'. $col,'DESC')
        ->getQuery()->getResult(\Doctrine\ORM\Query::HYDRATE_ARRAY);
    return $em2;
}

问题。现在的问题是,在我的createNewUser方法中,我尝试捕获。发生唯一违规时,catch块会处理它。但是,如果存在多个违规行为:用户名和电子邮件?如何从异常中获取,哪个字段被违反并将其与正确的表单字段关联?

1 个答案:

答案 0 :(得分:1)

我想说你需要添加自己的自定义验证器来检查唯一的用户名和电子邮件。

从以下示例中截取的代码。     @Unique(service = UserService.class,fieldName =&#34; email&#34;,message =&#34; {email.unique.violation}&#34;)     私人字符串电子邮件;

注释和验证器

@Target({ METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = UniqueValidator.class)
@Documented
public @interface Unique {
    String message() default "{unique.value.violation}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    Class<? extends FieldValueExists> service();
    String serviceQualifier() default "";
    String fieldName();
}

public class UniqueValidator implements ConstraintValidator<Unique, Object> {
    @Autowired
    private ApplicationContext applicationContext;

    private FieldValueExists service;
    private String fieldName;

    @Override
    public void initialize(Unique unique) {
        Class<? extends FieldValueExists> clazz = unique.service();
        this.fieldName = unique.fieldName();
        String serviceQualifier = unique.serviceQualifier();

        if (!serviceQualifier.equals("")) {
            this.service = this.applicationContext.getBean(serviceQualifier, clazz);
        } else {
            this.service = this.applicationContext.getBean(clazz);
        }
    }

    @Override
    public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
        return !this.service.fieldValueExists(o, this.fieldName);
    }
}

请参阅the example