2011-01-04 33 views
8

Tôi có trình xác thực bean tùy chỉnh để kiểm tra xem một trường nhất định trên thực thể có duy nhất cho một số điều kiện hay không. Nếu xác thực không thành công, thông báo phải bao gồm một trường (ví dụ: ID) của thực thể đã tồn tại. Vì vậy, ví dụ: thông báo phải là:Nội suy thông số xác thực cụ thể trong thông báo xác thực đậu

"Product 42 already has such a value defined, choose a unique value." 

Điều này có thể sử dụng xác thực bean không?

AFAICS, định dạng tin nhắn có thể bao gồm các thông số, chẳng hạn như:

"Length must be between {min} and {max}." 

Nhưng điều này chỉ có thể tham khảo các "tĩnh" thuộc tính của chú thích xác nhận, trong trường hợp này:

@Size(min=1, max=16) 
private String name; 

Trong trường hợp của tôi, giá trị chỉ được biết trong số isValid của trình xác thực tùy chỉnh của tôi.

Trả lời

2

Bạn đã đúng !, Và đối với những gì bạn muốn !, bạn có thể xây dựng thông điệp vi phạm ràng buộc bên trong phương thức isValid(). Đối với điều này các ràng buộc Chú thích nên được cụ thể cho lớp cụ thể mà nó đã được áp dụng và nó phải là một ràng buộc xác nhận mức lớp. Bên trong isValid trước khi trả về false khi không xác nhận hợp lệ, bạn có thể tạo thông điệp chứa giá trị của cá thể lớp. Ví dụ:

@check class Test{ int id; @validations...on fields}. 

public boolean isValid(Test value, ConstraintValidatorContext context) 
{ 
// your check logic 
context.disableDefaultConstraintViolation(); 
context.buildConstraintViolationWithTemplate("It should be different for(custom message) .."+ value.id).addConstraintViolation(); 
return false; // based on constraint filure. 

} 

Nhưng tôi nghĩ bạn muốn làm điều này với chú thích cấp Field! Tôi không có ý tưởng về việc mong đợi kết quả của bạn.

+0

Vấn đề là tôi không muốn xây dựng thông báo cuối cùng trong trình xác thực, chỉ là định dạng (cho bản dịch) và các tham số. Nhưng tôi đoán tôi phải bản địa hóa thông báo bên trong trình xác nhận. – robinst

+0

Tôi đã đăng giải pháp mà chúng tôi đã kết thúc bằng một câu trả lời khác. Nhưng tôi nghĩ câu trả lời của bạn cho phép các thông báo lỗi cụ thể hơn, ngay cả khi nội địa hóa phải được thực hiện bên trong trình xác thực, tôi đã chấp nhận nó. – robinst

0

Nó không phải thực sự là giải pháp đẹp nhất, nhưng những gì chúng tôi đã kết thúc làm được thêm một cái gì đó như sau để đầu cấp mã xử lý ngoại lệ của chúng tôi:

String getConstraintViolationMessages(ConstraintViolationException e) { 
    StringBuilder sb = new StringBuilder(); 
    for (ConstraintViolation<?> violation : e.getConstraintViolations()) { 
     sb.append(getMessage(violation)); 
     sb.append("\n"); 
    } 
    sb.setLength(sb.length() - 1); 
    return sb.toString(); 
} 

String getMessage(ConstraintViolation<?> violation) { 
    String key = violation.getMessageTemplate(); 
    String messageFormat = localize(key); 

    Object entity = violation.getRootBean(); 
    String identifier; 
    if (entity instanceof PrimaryKeyed) { 
     identifier = String.valueOf(((PrimaryKeyed) entity).getId()); 
    } else { 
     identifier = entity.toString(); 
    } 

    return MessageFormat.format(messageFormat, identifier); 
} 

Lưu ý rằng PrimaryKeyed là một giao diện tùy chỉnh được sử dụng trên thực thể của chúng tôi. Chúng tôi cũng có một số giao diện khác và xử lý tùy chỉnh không được hiển thị ở trên.

+0

Trong đó lớp học là hai phương pháp ngồi? Ràng buộc tùy chỉnh của tôi với một 'context.buildConstraintViolationWithTemplate (" {no.mobitroll.rest.resources.entities.beans.validators.QuizType.enum} "). AddConstraintViolation();' không nội suy giá trị. – Stephane

+0

@Stephane Chúng tôi có chúng trong một lớp xử lý ngoại lệ cấp cao nhất, mà có lẽ là một điều tốt để có bất kể. Nơi bạn thêm điều này thực sự phụ thuộc vào kiến ​​trúc của bạn và những khung công tác bạn sử dụng, vì vậy tôi thực sự không thể đưa ra một câu trả lời cụ thể hơn. – robinst

Các vấn đề liên quan