2011-01-04 15 views
8

मेरे पास एक कस्टम बीन सत्यापनकर्ता है जो जांचता है कि किसी इकाई पर दिया गया फ़ील्ड कुछ स्थितियों के लिए अद्वितीय है या नहीं। यदि सत्यापन विफल रहता है, तो संदेश में पहले से मौजूद इकाई का एक फ़ील्ड (उदा। आईडी) शामिल होना चाहिए। तो उदाहरण के लिए संदेश होना चाहिए:बीन सत्यापन संदेश में इंटरपोलेट सत्यापन-विशिष्ट पैरामीटर

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

क्या यह बीन सत्यापन का उपयोग कर संभव है?

AFAICS, संदेश स्वरूप जैसे मानकों, शामिल हो सकते हैं:

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

लेकिन यह केवल मान्यता एनोटेशन के "स्थिर" गुण संदर्भित कर सकते हैं, इस मामले में:

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

में मेरा मामला, मान केवल मेरे कस्टम सत्यापनकर्ता के isValid के भीतर जाना जाता है।

उत्तर

2

आप सही हैं !, और जो भी आप चाहते हैं !, आप isValid() विधि के अंदर बाधा उल्लंघन संदेश बना सकते हैं। इसके लिए बाधाएं एनोटेशन विशेष वर्ग के लिए विशिष्ट होना चाहिए जिस पर इसे लागू किया गया है और यह एक वर्ग स्तर सत्यापन बाधा होना चाहिए। प्रमाणीकरण की विफलता पर झूठी वापसी से पहले isValid के अंदर आप कक्षा उदाहरण के संदेश शामिल मूल्य बना सकते हैं। उदाहरण के लिए:

@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. 

} 

लेकिन मुझे लगता है कि आप फील्ड स्तर एनोटेशन के साथ ऐसा करना चाहते हैं! मुझे आपके परिणामों की प्रतीक्षा करने के बारे में कोई जानकारी नहीं है।

+0

समस्या यह है कि मैं वैधकर्ता में अंतिम संदेश, केवल एक प्रारूप (अनुवादों के लिए) और पैरामीटर बनाना नहीं चाहता हूं। लेकिन मुझे लगता है कि मुझे वैधता के अंदर संदेश को स्थानीयकृत करना है। – robinst

+0

मैंने समाधान पोस्ट किया जिसे हम एक और जवाब के साथ समाप्त कर दिया। लेकिन मुझे लगता है कि आपका उत्तर अधिक विशिष्ट त्रुटि संदेशों के लिए अनुमति देता है, भले ही स्थानीयकरण को वैधकर्ता के अंदर किया जाना है, मैंने इसे स्वीकार कर लिया है। – robinst

0

यह वास्तव में सबसे अच्छा समाधान है, लेकिन क्या हम अपने शीर्ष स्तर के अपवाद हैंडलिंग कोड के लिए निम्न की तरह कुछ जोड़ने था कर समाप्त हो गया:

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

ध्यान दें कि PrimaryKeyed उस पर प्रयोग किया जाता है एक कस्टम इंटरफेस है हमारी संस्थाएं हमारे पास कुछ अन्य इंटरफेस और कस्टम हैंडलिंग भी ऊपर नहीं दिखाए गए हैं।

+0

इन दोनों विधियों में कौन सी कक्षा बैठी है? एक 'context.buildConstraintViolationWithTemplate ("{no.mobitroll.rest.resources.entities.beans.validators.QuizType.enum}" के साथ मेरी कस्टम बाधा ")। AddConstraintViolation();' अभी तक मान को अलग नहीं करता है। – Stephane

+0

@Stephane हम उन्हें शीर्ष-स्तरीय अपवाद हैंडलर क्लास में रखते हैं, जो शायद ध्यान देने योग्य एक अच्छी बात है। जहां आप इसे जोड़ते हैं, वास्तव में आपके आर्किटेक्चर पर निर्भर करता है और आप किस ढांचे का उपयोग करते हैं, इसलिए मैं वास्तव में दुर्भाग्य से अधिक विशिष्ट उत्तर नहीं दे सकता। – robinst

संबंधित मुद्दे