我正在使用spring mvc + jpa 2.1 + hibernate验证器在liferay 6.2上开发一个portlet
在我的pom中我有
....
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.0.6.Final</version>
</dependency>
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.0.6.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.2.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>5.2.2.Final</version>
<exclusions>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
....
我为hibernate验证器
创建了一些自定义约束@Target({FIELD, METHOD})
@Retention(RUNTIME)
@Constraint(validatedBy = CheckCodiceFiscaleValidator.class)
@Documented
public @interface CheckCF {
String message() default "{validator.assertFalse}";
Class<? extends Payload>[] payload() default { };
Class<?>[] groups() default { };
}
并且实现的验证器是
public class CheckCodiceFiscaleValidator implements ConstraintValidator<CheckCF, String> {
@Override
public void initialize(CheckCF constraintAnnotation) {
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
@Override
public boolean isValid(String object, ConstraintValidatorContext constraintContext) {
//constraintContext.disableDefaultConstraintViolation();
constraintContext.buildConstraintViolationWithTemplate(
"{it.realt.validator.constraint.custom.cf.genericError.message}").addConstraintViolation();
if (Strings.isNullOrEmpty(object)) {
return false;
}
return validaCF(object, constraintContext);
}
private boolean validaCF(String cf, ConstraintValidatorContext constraintContext) {
int i, s, c;
String cf2;
int setdisp[]
= {
1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18, 20,
11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23
};
if (cf.length() == 0) {
constraintContext.buildConstraintViolationWithTemplate(
"{it.realt.validator.constraint.custom.cf.notEmpty.message}").addConstraintViolation();
return false;
}
if (cf.length() != 16) {
constraintContext.buildConstraintViolationWithTemplate(
"{it.realt.validator.constraint.custom.cf.tooShort.message}").addConstraintViolation();
return false;
}
cf2 = cf.toUpperCase();
for (i = 0; i < 16; i++) {
c = cf2.charAt(i);
if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'Z')) {
constraintContext.buildConstraintViolationWithTemplate(
"{it.realt.validator.constraint.custom.cf.invalidChars.message}").addConstraintViolation();
return false;
}
}
s = 0;
for (i = 1; i <= 13; i += 2) {
c = cf2.charAt(i);
if (c >= '0' && c <= '9') {
s = s + c - '0';
} else {
s = s + c - 'A';
}
}
for (i = 0; i <= 14; i += 2) {
c = cf2.charAt(i);
if (c >= '0' && c <= '9') {
c = c - '0' + 'A';
}
s = s + setdisp[c - 'A'];
}
if (s % 26 + 'A' != cf2.charAt(15)) {
constraintContext.buildConstraintViolationWithTemplate(
"{it.realt.validator.constraint.custom.cf.controlCode.message}").addConstraintViolation();
return false;
}
return true;
}
}
在实体类中我有
...
@Column(name = "cognome")
@NotEmpty
private String cognome;
@Column(name = "nome")
@NotEmpty
private String nome;
@Column(name = "indirizzo")
@NotEmpty
private String indirizzo;
@Column(name = "cap")
@NotEmpty
@Length(min=5, max=5)
private String cap;
@Column(name = "citta")
@NotEmpty
private String citta;
@Column(name = "provincia")
@NotEmpty
private String provincia;
@Column(name = "partita_iva")
@CheckPIVA
private String partitaIva;
@Column(name = "codice_fiscale")
@CheckCF
private String codiceFiscale;
...
在我的控制器中我放了@Valid注释
...
@ActionMapping(params = "action=register")
public void richiestaRegistrazione(ActionRequest actionRequest, ActionResponse actionResponse,
@ModelAttribute("anagrafica") @Valid Anagrafica anagrafica, BindingResult result, Model model) throws IOException,
PortletException {
boolean succeded = this.anagraficaManager.richiediRegistrazione(anagrafica);
model.addAttribute("succeded", succeded);
}
...
最后jsp是
...
<form:form name="<portlet:namespace/>anagrafica" modelAttribute="anagrafica" action="${registraRichiestaURL}" method="post">
<center>
<table>
<tr align="left">
<th align="right">Partita IVA: </th>
<td align="left" class="generale"><span><form:input path="partitaIva" maxlength="11"/><form:errors path="partitaIva" cssClass="error"/></span></td>
</tr>
...
当我提交表单时,验证失败,我得到了异常
javax.validation.ConstraintViolationException: Validation failed for classes [it.realt.mypos.domain.Anagrafica] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=cap, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=natoA, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=citta, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=provincia, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=indirizzo, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=cognome, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be empty', propertyPath=nome, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.NotEmpty.message}'}
ConstraintViolationImpl{interpolatedMessage='may not be null', propertyPath=natoIl, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{javax.validation.constraints.NotNull.message}'}
ConstraintViolationImpl{interpolatedMessage='Si è verificato un errore nel controllo del Codice Fiscale', propertyPath=codiceFiscale, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{it.realt.validator.constraint.custom.cf.genericError.message}'}
ConstraintViolationImpl{interpolatedMessage='{validator.assertFalse}', propertyPath=codiceFiscale, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{validator.assertFalse}'}
ConstraintViolationImpl{interpolatedMessage='length must be between 5 and 5', propertyPath=cap, rootBeanClass=class it.realt.mypos.domain.Anagrafica, messageTemplate='{org.hibernate.validator.constraints.Length.message}'}
]
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:138)
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:78)
at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:205)
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:82)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560)
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434)
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337)
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39).....
并且页面中没有绑定任何错误...
我查看了google中发现的几个示例,看起来我做的都是正确的...所以问题出在哪里?
由于
安德烈
答案 0 :(得分:0)
您的示例是正确的,为什么没有错误在您的页面中绑定,原因很简单,您在“partitaIva”字段中有任何错误,您可以在ConstraintViolationException跟踪中看到。
如果您想要显示所有错误,则必须从
中删除路径属性<form:errors path="partitaIva" cssClass="error"/>