我有实体类别,其属性名称是HashMap。我可以为不同语言的一个类别设置多个名称。我想创建拒绝空值的自定义验证器(我总是在jsp中设置键,因此键始终不为null)并使用form:error将它们绑定到jsp中 到目前为止,这是我的代码。问题是,当形式:错误我使用路径名称,每个输入显示错误。我需要分别显示每个输入的错误。
非常感谢您回答任何问题
@Entity
public class Category extends AbstractEntity {
@ValidMap(message = "{NotNull}")
@ElementCollection(fetch = FetchType.EAGER)
@MapKeyColumn(name="language")
@Column(name="name")
@CollectionTable(name="category_name", joinColumns=@JoinColumn(name="category_id"))
Map<String, String> names = new HashMap<>();
}
@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = ValidMapValidator.class)
@ReportAsSingleViolation
@Documented
public @interface ValidMap {
String message() default "{}";
Class<? extends Payload>[] payload() default {};
Class<?>[] groups() default {};
}
public class ValidMapValidator implements ConstraintValidator<ValidMap, Map<String, String>> {
@Override
public void initialize(ValidMap validMap) {
}
@Override
public boolean isValid(Map<String, String> map, ConstraintValidatorContext context) {
boolean isValid = true;
for (Map.Entry<String, String> entry : map.entrySet()) {
if(entry.getValue()==null){
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("{NotNull}")
.addBeanNode()
.inIterable().atKey( entry.getKey().toString() )
.addConstraintViolation();
isValid = false;
}
}
return isValid;
}
}
我的控制器
@RequestMapping(method = RequestMethod.POST, value = "/save-category/{id}")
public String saveCategory(@PathVariable("id") long id,
@ModelAttribute("category") @Validated Category category,
BindingResult result,
Locale locale,
Model model
) {
if(result.hasErrors()){
model.addAttribute("category");
model.addAttribute("validationFailed", true);
return "offer/category";
}
categoryRepo.save(category);
return "redirect:/offers/items/" + id;
}
和Jsp
<form:form method="POST" action="${url}" modelAttribute="category" class="form-horizontal" id="category_form">
<table class="table borderless">
<c:forEach items="${category.names}" var="name" varStatus="status">
<tr class="offer-names">
<td>
<div class="form-group">
<label for="first_name_input" class="col-sm-2 control-label label-name" style="text-align: left">
<spring:message code="ware.name"/>
</label>
<div class="col-sm-2 input-name">
<form:input path="names['${name.value} ${key = name.key}']"
cssStyle="width: 100%" cssClass="input-name-field" value="${name.value}"/>
<br>
<form:errors path="names"/>
</div>
<div style="margin-top: 3px; color: darkgray" id="offer_name_language_text">
<span><spring:message code="offer.language.${name.key}"/></span>
</div>
</div>
</td>
</tr>
</c:forEach>
<tr>
<td>
<div class="form-group" style="margin-bottom: 0px">
<label id="radioLabel" class="col-sm-2 control-label" style="text-align: left;">
<spring:message code="users.table.active"/>
</label>
<div class="col-sm-2" style="padding-top: 5px">
<form:radiobutton path="isActive" value="true" id="active"/>
<label for="active">
<spring:message code="users.active.yes"/>
</label><br>
<form:radiobutton path="isActive" value="false" id="notActive"/>
<label for="notActive">
<spring:message code="users.active.no"/>
</label>
</div>
</div>
</td>
</tr>
<tr>
<td>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-2" style="text-align: right">
<c:url value="${backUrl}" var="backUrlVar"/>
<a href="${backUrlVar}" class="btn btn-default">
<spring:message code="displayOrganization.button.back"/>
</a>
<input type="submit" class="btn btn-primary"
value="<spring:message code="editOrganization.save"/>"/>
</div>
</div>
</td>
</tr>
</table>
<form:hidden path="offer.id" value="${id}"/>
<c:if test="${not empty category.id}">
<form:hidden path="id" value="${category.id}"/>
</c:if>
</form:form>