下面列出了javax.validation.ConstraintViolation#getPropertyPath ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Before("paramValidAspect()")
public void before(JoinPoint joinPoint) {
// 获取入参
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
if (arg == null) {
throw new ParamValidException(BizError.参数异常.getCode(), "入参为空");
}
Set<ConstraintViolation<Object>> violations = validator.validate(arg);
Iterator<ConstraintViolation<Object>> iterator = violations.iterator();
// 参数校验不通过,直接抛出异常
if (iterator.hasNext()) {
ConstraintViolation<Object> violation = iterator.next();
throw new ParamValidException(BizError.参数异常.getCode(),
violation.getPropertyPath() + ":" + violation.getMessage());
}
}
}
public boolean validateForm(final Object data) {
Set<ConstraintViolation<Object>> violations = this.validation.validate(data);
if (violations.size() > 0) {
final StringBuilder errorMsg = new StringBuilder();
for (ConstraintViolation violation : violations) {
errorMsg.append(violation.getMessage()).append("<br/>");
if (violation.getPropertyPath() != null && !violation.getPropertyPath().toString().equals("")) {
if (violation.getPropertyPath().toString().equals("workphone")) {
txtWorkPhone.addStyleName("errorField");
}
if (violation.getPropertyPath().toString().equals("homephone")) {
txtHomePhone.addStyleName("errorField");
}
}
}
NotificationUtil.showErrorNotification(errorMsg.toString());
return false;
}
return true;
}
private String makePath ( final ConstraintViolation<Object> entry )
{
final StringBuilder sb = new StringBuilder ();
final Path p = entry.getPropertyPath ();
for ( final Node n : p )
{
if ( sb.length () > 0 )
{
sb.append ( '.' );
}
sb.append ( n.getName () );
}
return sb.toString ();
}
/**
* Determine a field for the given constraint violation.
* <p>The default implementation returns the stringified property path.
* @param violation the current JSR-303 ConstraintViolation
* @return the Spring-reported field (for use with {@link Errors})
* @since 4.2
* @see javax.validation.ConstraintViolation#getPropertyPath()
* @see org.springframework.validation.FieldError#getField()
*/
protected String determineField(ConstraintViolation<Object> violation) {
Path path = violation.getPropertyPath();
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Path.Node node : path) {
if (node.isInIterable()) {
sb.append('[');
Object index = node.getIndex();
if (index == null) {
index = node.getKey();
}
if (index != null) {
sb.append(index);
}
sb.append(']');
}
String name = node.getName();
if (name != null && node.getKind() == ElementKind.PROPERTY && !name.startsWith("<")) {
if (!first) {
sb.append('.');
}
first = false;
sb.append(name);
}
}
return sb.toString();
}
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<Object> constraintViolationException(ConstraintViolationException e) {
ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
String value = String.valueOf(constraintViolation.getInvalidValue());
String message = WebContext.getRequest().getRequestURI() +
" [" + constraintViolation.getPropertyPath() + "=" + value + "] " + constraintViolation.getMessage();
log.warn("Hydrogen uniform valid response exception with msg: {} ", message);
ResponseEntity<Object> responseEntity = handleExceptionResponse(e, HttpStatus.BAD_REQUEST.value(), message);
return responseEntity == null ? ResponseEntity.status(HttpStatus.BAD_REQUEST.value()).body(null) : responseEntity;
}
/**
* 统一处理请求参数校验(普通传参)
*
* @param e ConstraintViolationException
* @return FebsResponse
*/
@ExceptionHandler(value = ConstraintViolationException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public FebsResponse handleConstraintViolationException(ConstraintViolationException e) {
StringBuilder message = new StringBuilder();
Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
for (ConstraintViolation<?> violation : violations) {
Path path = violation.getPropertyPath();
String[] pathArr = StringUtils.splitByWholeSeparatorPreserveAllTokens(path.toString(), ".");
message.append(pathArr[1]).append(violation.getMessage()).append(StringConstant.COMMA);
}
message = new StringBuilder(message.substring(0, message.length() - 1));
log.error(message.toString());
return new FebsResponse().message(message.toString());
}
@ExceptionHandler(ConstraintViolationException.class)
@ResponseStatus(value = HttpStatus.OK)
public Result handleConstraintViolationException(ConstraintViolationException e) {
String msg = "param valid exception";
if (e != null) {
Iterator<ConstraintViolation<?>> iterator = e.getConstraintViolations().iterator();
if (iterator.hasNext()) {
ConstraintViolation<?> violation = iterator.next();
msg = violation.getPropertyPath() + ":" + violation.getMessage();
}
log.warn(e.toString());
}
return Result.fail(msg);
}
/**
* Determine a field for the given constraint violation.
* <p>The default implementation returns the stringified property path.
* @param violation the current JSR-303 ConstraintViolation
* @return the Spring-reported field (for use with {@link Errors})
* @since 4.2
* @see javax.validation.ConstraintViolation#getPropertyPath()
* @see org.springframework.validation.FieldError#getField()
*/
protected String determineField(ConstraintViolation<Object> violation) {
Path path = violation.getPropertyPath();
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Path.Node node : path) {
if (node.isInIterable()) {
sb.append('[');
Object index = node.getIndex();
if (index == null) {
index = node.getKey();
}
if (index != null) {
sb.append(index);
}
sb.append(']');
}
String name = node.getName();
if (name != null && node.getKind() == ElementKind.PROPERTY && !name.startsWith("<")) {
if (!first) {
sb.append('.');
}
first = false;
sb.append(name);
}
}
return sb.toString();
}
<T> void validate(T object) {
Set<ConstraintViolation<T>> errs = jeeValidator.validate(object);
if (errs.size() > 0) { // error
String msg = "Invalid Bean, constraint error(s) : ";
for (ConstraintViolation<T> err : errs) {
msg += err.getPropertyPath() + " " + err.getMessage() + ". ";
}
throw new IllegalArgumentException(msg);
}
}
<T> Response validate(T object) {
Set<ConstraintViolation<T>> errs = jeeValidator.validate(object);
if (errs.isEmpty()) { // no error
return Response.status(200).entity(object).build();
} else { // error
String msg = "Invalid Bean, constraint error(s) : ";
for (ConstraintViolation<T> err : errs) {
msg += err.getPropertyPath() + " " + err.getMessage() + ". ";
}
return Response.status(400).entity(msg).build();
}
}
protected String buildErrorMessage(ConstraintViolation<?> violation) {
return "Value "
+ (violation.getInvalidValue() != null ? "'" + violation.getInvalidValue().toString() + "'" : "(null)")
+ " of " + violation.getRootBeanClass().getSimpleName()
+ "." + violation.getPropertyPath()
+ ": " + violation.getMessage();
}
protected void validateDataObject(Object data) {
if (!(data instanceof CmEntityData))
throw new IllegalArgumentException("Request body must implement CmEntityData interface.");
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(data);
if (constraintViolations.isEmpty()) return;
String errorMessage = "Invalid " + data.getClass().getSimpleName() + ":";
for (ConstraintViolation violation : constraintViolations) {
errorMessage += "\n" + violation.getPropertyPath() + " " + violation.getMessage();
}
throw new IllegalArgumentException(errorMessage);
}
public ServiceMethodConstraintViolation(Class serviceInterface, ConstraintViolation violation) {
this.message = violation.getMessage();
this.messageTemplate = violation.getMessageTemplate();
this.invalidValue = violation.getInvalidValue();
this.constraintDescriptor = violation.getConstraintDescriptor();
this.executableParameters = violation.getExecutableParameters();
this.executableReturnValue = violation.getExecutableReturnValue();
this.rootBeanClass = serviceInterface;
this.propertyPath = violation.getPropertyPath();
}
protected String derivePropertyPathByNode(ConstraintViolation<Object> vio) {
final StringBuilder sb = new StringBuilder();
final Path path = vio.getPropertyPath();
int elementCount = 0;
for (Path.Node node : path) {
if (node.isInIterable()) { // building e.g. "[0]" of seaList[0]
Object nodeIndex = node.getIndex();
if (nodeIndex == null) {
nodeIndex = node.getKey(); // null if e.g. iterable
}
sb.append("[").append(nodeIndex != null ? nodeIndex : "").append("]"); // e.g. [0] or []
}
final String nodeName = node.getName();
if (nodeName != null && node.getKind() == ElementKind.PROPERTY) {
// _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// if e.g.
// private List<@Required String> seaList;
// then path is "seaList[0].<list element>" since Hibernate Validator-6.x
// <list element> part is unneeded for property path of message so skip here
// _/_/_/_/_/_/_/_/_/_/
if (!nodeName.startsWith("<")) { // except e.g. <list element>
if (elementCount > 0) {
sb.append(".");
}
sb.append(nodeName);
++elementCount;
}
}
}
return sb.toString(); // e.g. sea, sea.hangar, seaList[0], seaList[0].hangar
}
protected void validateDataObject(Object data) {
if (!(data instanceof CmEntityData))
throw new IllegalArgumentException("Request body must implement CmEntityData interface.");
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(data);
if (constraintViolations.isEmpty()) return;
String errorMessage = "Invalid " + data.getClass().getSimpleName() + ":";
for (ConstraintViolation violation : constraintViolations) {
errorMessage += "\n" + violation.getPropertyPath() + " " + violation.getMessage();
}
throw new IllegalArgumentException(errorMessage);
}
private Response.Status getResponseStatus(final ConstraintViolation<?> constraintViolation) {
for (final Path.Node node : constraintViolation.getPropertyPath()) {
final ElementKind kind = node.getKind();
if (ElementKind.RETURN_VALUE.equals(kind)) {
return Response.Status.INTERNAL_SERVER_ERROR;
}
}
return Response.Status.BAD_REQUEST;
}
private void addValidationError(ConstraintViolation<?> violation, ValidationResult validationResult) {
String propertyPath = violation.getPropertyPath() != null ? violation.getPropertyPath().toString() : "";
validationResult.addValidationError(propertyPath, violation.getMessage());
}
private boolean addErrorsToList(ConstraintViolationException exception,
List<ValidationExceptionRepresentation.ValidationError> validationErrors) {
boolean responseError = false;
Class<?> resourceClass = ProxyUtils.cleanProxy(resourceInfo.getResourceClass());
for (ConstraintViolation<?> constraintViolation : exception.getConstraintViolations()) {
ValidationExceptionRepresentation.ValidationError validationError =
new ValidationExceptionRepresentation.ValidationError();
boolean appendToPath = false;
StringBuilder path = new StringBuilder();
Method method = null;
for (Path.Node node : constraintViolation.getPropertyPath()) {
switch (node.getKind()) {
case METHOD:
method = resolveMethod(resourceClass, node.as(Path.MethodNode.class));
continue;
case RETURN_VALUE:
validationError.setLocation(Location.RESPONSE_BODY.toString());
responseError = true;
appendToPath = true;
continue;
case PARAMETER:
ParameterInfo parameterInfo = resolveParameterInfo(
node.as(Path.ParameterNode.class),
method);
validationError.setLocation(parameterInfo.getLocation().toString());
if (!parameterInfo.isBody()) {
path.append(parameterInfo.getName()).append(".");
}
appendToPath = true;
continue;
default:
break;
}
if (appendToPath) {
path.append(node.getName()).append(".");
}
}
if (path.length() > 0) {
validationError.setPath(path.substring(0, path.length() - 1));
}
validationError.setMessage(constraintViolation.getMessage());
Object invalidValue = constraintViolation.getInvalidValue();
if (invalidValue != null) {
validationError.setInvalidValue(String.valueOf(invalidValue));
}
validationErrors.add(validationError);
}
return responseError;
}
/**
* BeanValidationの検証結果をSheet用のエラーに変換する
* @param violations BeanValidationの検証結果
* @param errors シートのエラー
*/
protected void processConstraintViolation(final Set<ConstraintViolation<Object>> violations,
final SheetBindingErrors<?> errors) {
for(ConstraintViolation<Object> violation : violations) {
final String fieldName = violation.getPropertyPath().toString();
final Optional<FieldError> fieldError = errors.getFirstFieldError(fieldName);
if(fieldError.isPresent() && fieldError.get().isConversionFailure()) {
// 型変換エラーが既存のエラーにある場合は、処理をスキップする。
continue;
}
final ConstraintDescriptor<?> cd = violation.getConstraintDescriptor();
/*
* エラーメッセージのコードは、後から再変換できるよう、BeanValidationの形式のエラーコードも付けておく。
*/
final String[] errorCodes = new String[]{
cd.getAnnotation().annotationType().getSimpleName(),
cd.getAnnotation().annotationType().getCanonicalName(),
cd.getAnnotation().annotationType().getCanonicalName() + ".message"
};
final Map<String, Object> errorVars = createVariableForConstraint(cd);
final String nestedPath = errors.buildFieldPath(fieldName);
if(Utils.isEmpty(nestedPath)) {
// オブジェクトエラーの場合
errors.createGlobalError(errorCodes)
.variables(errorVars)
.defaultMessage(violation.getMessage())
.buildAndAddError();
} else {
// フィールドエラーの場合
// 親のオブジェクトから、セルの座標を取得する
final Object parentObj = violation.getLeafBean();
final Path path = violation.getPropertyPath();
Optional<CellPosition> cellAddress = Optional.empty();
Optional<String> label = Optional.empty();
if(path instanceof PathImpl) {
final PathImpl pathImpl = (PathImpl) path;
cellAddress = new PositionGetterFactory().create(parentObj.getClass(), pathImpl.getLeafNode().getName())
.map(getter -> getter.get(parentObj)).orElse(Optional.empty());
label = new LabelGetterFactory().create(parentObj.getClass(), pathImpl.getLeafNode().getName())
.map(getter -> getter.get(parentObj)).orElse(Optional.empty());
}
// フィールドフォーマッタ
Class<?> fieldType = errors.getFieldType(nestedPath);
if(fieldType != null) {
FieldFormatter<?> fieldFormatter = errors.findFieldFormatter(nestedPath, fieldType);
if(fieldFormatter != null) {
errorVars.putIfAbsent("fieldFormatter", fieldFormatter);
}
}
// 実際の値を取得する
errorVars.putIfAbsent("validatedValue", violation.getInvalidValue());
errors.createFieldError(fieldName, errorCodes)
.variables(errorVars)
.address(cellAddress)
.label(label)
.defaultMessage(violation.getMessage())
.buildAndAddError();
}
}
}
private static Annotation[] getAnnotations(ConstraintViolation<?> violation) {
// create a simple list of nodes from the path
List<Path.Node> nodes = new ArrayList<>();
for (Path.Node node : violation.getPropertyPath()) {
nodes.add(node);
}
Path.Node lastNode = nodes.get(nodes.size() - 1);
// the path refers to some property of the leaf bean
if (lastNode.getKind() == ElementKind.PROPERTY) {
Path.PropertyNode propertyNode = lastNode.as(Path.PropertyNode.class);
return getPropertyAnnotations(violation, propertyNode);
}
// The path refers to a method parameter
else if (lastNode.getKind() == ElementKind.PARAMETER && nodes.size() == 2) {
Path.MethodNode methodNode = nodes.get(0).as(Path.MethodNode.class);
Path.ParameterNode parameterNode = nodes.get(1).as(Path.ParameterNode.class);
return getParameterAnnotations(violation, methodNode, parameterNode);
}
log.warning("Could not read annotations for path: " + violation.getPropertyPath().toString());
return new Annotation[0];
}