gpt4 book ai didi

java - SpringValidator(net.sf.oval): Recursive Error Reporting

转载 作者:太空宇宙 更新时间:2023-11-04 13:43:24 27 4
gpt4 key购买 nike

我正在重构应用程序中的页面,并尝试对本身具有验证约束的对象执行递归验证。然而,发生了什么,我只收到一条错误,描述该对象无效。我想要的是嵌套对象的验证错误返回到页面。

ConsumerManagementController.java

@Controller
@SessionAttributes(ConsumerManagementController.CMD_NAME)
public class ConsumerManagementController {

private org.springframework.validation.Validator validator;

public ConsumerManagementController() {
validator = new net.sf.oval.integration.spring.SpringValidator.SpringValidator(new net.sf.oval.Validator());
}

@RequestMapping(value = FORM_VIEW, method = RequestMethod.POST)
protected ModelAndView processAdjustment(HttpServletRequest request,
Model model,
@ModelAttribute(CMD_NAME) ConsumerManagementCommand cmd,
BindingResult errors) throws Exception {

...

// Validating the ConsumerManagementCommand object
validator.validate(cmd, errors);
// RESULT
// org.springframework.validation.BeanPropertyBindingResult: 1 errors
// Field error in object 'cmc' on field 'consumerAdjustment': rejected value [[com.company.core.dto.ConsumerAdjustment - memo=, -- ]]; codes [net.sf.oval.constraint.AssertValid.cmc.consumerAdjustment,net.sf.oval.constraint.AssertValid.consumerAdjustment,net.sf.oval.constraint.AssertValid.com.company.core.dto.ConsumerAdjustment,net.sf.oval.constraint.AssertValid]; arguments []; default message [com.company.web.ops.commands.consumer.account.ConsumerManagementCommand.consumerAdjustment is invalid]


// Validating the ConsumerAdjustment object
ConsumerAdjustment consumerAdjustment = cmd.getConsumerAdjustment();
BeanPropertyBindingResult consumerAdjustmentErrors = new BeanPropertyBindingResult(consumerAdjustment, "consumerAdjustment");

validator.validate(consumerAdjustment, consumerAdjustmentErrors);

// RESULT
// org.springframework.validation.BeanPropertyBindingResult: 2 errors
// Field error in object 'consumerAdjustment' on field 'memo': rejected value []; codes [consumerAdjustment.memo.err.null.consumerAdjustment.memo,consumerAdjustment.memo.err.null.memo,consumerAdjustment.memo.err.null.java.lang.String,consumerAdjustment.memo.err.null]; arguments []; default message [com.company.core.dto.ConsumerAdjustment.memo cannot be empty]

...

}
}

ConsumerManagementCommand.java

@Guarded
public class ConsumerManagementCommand implements Serializable{

@AssertValid
private ConsumerAdjustment consumerAdjustment = new ConsumerAdjustment();

}

ConsumerAdjustment.java

public class ConsumerAdjustment extends AbstractDTO implements Serializable {

@NotNull(errorCode = ERR_MEMO_NULL)
@NotEmpty(errorCode = ERR_MEMO_NULL)
@Length(max = 500, errorCode = ERR_MEMO_LENGTH)
private String memo;

}

请参阅 RESULT 注释 ConsumerManagementController 以获取错误报告。

最佳答案

过一会儿再回到这个问题。我想出了如何实现我想要的。我不会讨论太多细节,但解决方案的根源相当复杂。

首先,我必须通过扩展 SpringValidator 创建自己的 validator :

class ConsumerManagementCommandSpringValidator extends SpringValidator{

Logger log = org.slf4j.LoggerFactory.getLogger(ConsumerManagementCommandSpringValidator.class);

public ConsumerManagementCommandSpringValidator(net.sf.oval.Validator validator) {
super(validator);
}

/**
* {@inheritDoc}
* Overridden method here to handle the nested validated objects of the {@link ConsumerManagementCommand}
* type. If a nested object fails validation, we need to identify the path to the field using
* the object name.
*/
@Override
public void validate(final Object objectToValidate, final Errors errors)
{
try
{
for (final ConstraintViolation violation : super.getValidator().validate(objectToValidate))
{
final OValContext ctx = violation.getContext();
final String errorCode = violation.getErrorCode();
final String errorMessage = violation.getMessage();

if (ctx instanceof FieldContext) {
Field field = ((FieldContext) ctx).getField();

String fieldName = field.getName();
try{
errors.rejectValue(fieldName, errorCode, errorMessage);
}catch(NotReadablePropertyException nrpe){
// Resolve the property location based on the object. Uses the class
// name of the field, tweaks the case and concatenates the value
StringBuilder objectReference = new StringBuilder(field.getDeclaringClass().getSimpleName());
fieldName = objectReference.substring(0, 1).toLowerCase().concat(objectReference.substring(1)).concat(".").concat(fieldName);

errors.rejectValue(fieldName, errorCode, errorMessage);
}
} else{
errors.reject(errorCode, errorMessage);
}
}
} catch (final ValidationFailedException ex) {
log.error("Unexpected error during validation", ex);
errors.reject(ex.getMessage());
}
}

}

其次,我创建了另一个扩展 net.sf.oval.Validator 的 validator :

class ConsumerManagementCommandValidator extends net.sf.oval.Validator{

@Override
protected void checkConstraintAssertValid(
List<ConstraintViolation> violations, AssertValidCheck check,
Object validatedObject, Object valueToValidate,
OValContext context, String[] profiles) throws OValException {

if (valueToValidate == null) return;

// ignore circular dependencies
if (isCurrentlyValidated(valueToValidate)) return;

// changed here access to private class variable to getter
final List<ConstraintViolation> additionalViolations = getCollectionFactory().createList();
validateInvariants(valueToValidate, additionalViolations, profiles);

if (additionalViolations.size() != 0) {
final String errorMessage = renderMessage(context, valueToValidate, check.getMessage(), check.getMessageVariables());

violations.add(new ConstraintViolation(check, errorMessage, validatedObject, valueToValidate, context, additionalViolations));
//add the violations to parent list :-)
violations.addAll(additionalViolations);
}
}

@Override
public List<ConstraintViolation> validate(Object validatedObject, String... profiles) throws IllegalArgumentException, ValidationFailedException {
// TODO Auto-generated method stub
return super.validate(validatedObject, profiles);
}

}

现在,我可以创建我的 validator 以供使用:

private ConsumerManagementCommandSpringValidator validator = new ConsumerManagementCommandSpringValidator(new ConsumerManagementCommandValidator());

我调用验证的地方:

// Validate the form
validator.validate(cmd, errors);

现在是命令对象。由于命令对象上有两个对象,因此我需要能够根据条件验证每个对象。使用 javascript EL 的 AssertValid:

// Custom assertion here, when the selected option is defined, only validate which is necessary
// We're using javascript expression language to do the comparison
@AssertValid(when="js:_this.selectedOption == com.company.core.adjustment.ConsumerManagementOption.ADJUST_CARD_VALUE")
private ConsumerAdjustment consumerAdjustment = new ConsumerAdjustment();
@AssertValid(when="js:_this.selectedOption == com.company.core.adjustment.ConsumerManagementOption.COMBINE_CARDS")
private ConsumerCombineAccounts consumerCombineAccounts = new ConsumerCombineAccounts();

现在,当我验证命令对象时,需要验证的嵌套对象将被处理,错误将上升到命令对象级别。

关于java - SpringValidator(net.sf.oval): Recursive Error Reporting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31079827/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com