2015-04-14 3 views
0

Я использую валидатор Hibernate @NotNull, и я пытаюсь создать пользовательские сообщения, чтобы сообщить пользователю, какое поле сгенерировало ошибку, когда оно равно null. Что-то вроде этого:Как создать персонализированные сообщения для подтверждения на основе свойства аннотации?

notNull.custom = The field {0} can't be null. 

(это будет в файле ValidationMessages.properties).

Если {0} должно быть имя поля передается считывающему таким образом:

@NotNull(field="field name") 

Существует ли способ я могу сделать это?

+0

Используйте валидатор спящего режима. У него должен быть слушатель для проверки всех отмеченных полей перед сохранением. – 00Enthusiast

+0

Я использую Hibernate Validator ... но я не нашел вариант, чтобы сделать это, о котором я упомянул. 00Enthusiast, можете ли вы разместить пример кода? – chr0x

+0

, поэтому для этого должен быть слушатель. Например: событие с предварительным сохранением. Я думаю, вам нужно что-то вроде @EntityListeners (JPAValidateListener.class). Затем вы можете обрабатывать исключение, если параметр недействителен. Обратите внимание, что вы должны реализовать этого слушателя самостоятельно, расширяя встроенный прослушиватель спящего режима. Не могу указать точные источники, это идея, как это сделать, и я считаю, что она должна работать. – 00Enthusiast

ответ

1

Если ваше требование может быть удовлетворено путем интерполирования зимуют сообщения, так что вы можете создать/имя вашего * свойство файла так:

ValidationMessages.properties 

А внутри что:

javax.validation.constraints.NotNull.message = CUSTOMIZED MESSAGE WHEN NOTNULL is violated! 

Hibernate обыски по умолчанию a ResourceBundle по названию ValidationMessages. Также могут быть вовлечены локаль: ValidationMessages_en, ValidationMessages_de, < ..>

Hibernate обеспечит настроенное сообщение через interpolatedMessage параметра, поэтому все ConstraintViolationException соответствующей информации (входит в вашем сообщение) будет показан. Таким образом, сообщение станет частью реального исключения. Будет предоставлена ​​какая-то громоздкая информация!

Если вы хотите сделать свое собственное исключение (без по умолчанию ConstraintViolationException поведения) проверить это:

Использование GenericDao концепции рассмотрит следующие

public void saveOrUpdate(IEntity<?> entity) { 
     try { 
      if(entity.getId == null) { 
      em.persist(entity); 
      } else { 
      em.merge(entity)l 
      } 
     } catch(ConstraintViolationException cve) { 
      throw new ConstraintViolationEx(constructViolationMessage(cve.getConstraintViolations())); 
     } 
    } 

private String constructMessage(Set<ConstraintViolation<?>> pConstraintViolations) { 
    StringBuilder customMessages = new StringBuilder(); 
    for(ConstraintViolation<?> violation : pConstraintViolations) { 
     String targetAnnotation = violation.getConstraintDescriptor().getAnnotation().annotationType().getSimpleName(); 
     if(supportsCustomMessage(targetAnnotation)) { 
      applyMessage(violation, targetAnnotation, customMessages); 
     } else { 
      // do something with not customized constraints' messages e.g. append it to existing container 
     } 
    } 
    return customMessages.toString(); 
} 

private void applyMessage(ConstraintViolation<?> pViolation, String pTargetAnnotation, StringBuilder pCustomMessages) { 
    String targetClass = pViolation.getRootBean().getClass().getName(); 
    String targetField = pViolation.getPropertyPath().toString(); 
    pCustomMessages.append(MessageFormat.format(getMessageByAnnotation(pTargetAnnotation), targetClass, targetField)); 
    pCustomMessages.append(System.getProperty("line.separator")); 
} 


private String getBundleKey() { 
    return "ValidationMessages"; //FIXME: hardcoded - implement your true key 
} 

private String getMessageByAnnotation(String pTargetAnnotation) { 
    ResourceBundle messages = ResourceBundle.getBundle(getBundleKey()); 
    switch(pTargetAnnotation) { 
    case "NotNull": 
     return messages.getString(pTargetAnnotation + ".message"); 
    default: 
     return ""; 
    } 
} 

private boolean supportsCustomMessage(String pTargetAnnotation) { 
    return customizedConstraintsTypes.contains(pTargetAnnotation); 
} 

Произведенного результат:

test.model.exceptions.ConstraintViolationEx 
    test.model.Person : name cannot be null 
    test.model.Person : surname cannot be null 

Спящий режим ConstraintViolation содержит соответствующую информацию о root class и restricted field. Как вы видите, он применяется для всех поддерживаемых спящим режимами ограничений, поэтому вам нужно проверить, можно ли настроить текущую аннотацию на supportsCustomMessage(<..>)! Если это возможно (это зависит от вас), вы должны получить соответствующее сообщение с помощью аннотации ограничения, сделав `getMessageByAnnotation (< ..>) '.

Все, что вам нужно сделать, это реализовать не поддерживаемые логики ограничений. Например, он может добавить сообщение о причине или интерполировать сообщение по умолчанию (и истинное исключение переходит в файл журнала)

Смежные вопросы