POJOのフィールドに対する注釈付きのスプリング検証は、jsonリクエスト本文から作成されたときに機能します。ただし、同じオブジェクトを手動で(セッターを使用して)作成し、検証をトリガーする場合、その方法がわかりません。
これは、オブジェクトを構築できるBuilder内部クラスを持つRegistrationクラスです。ビルドメソッドでは、春の検証をトリガーします。一番下までスクロールし、Builder.build()およびBuilder.valiate()メソッドを確認して、現在の実装を確認してください。私はjavax.validation.Validatorを使用して検証をトリガーしていますが、可能であれば春の検証を活用することを好みます。
package com.projcore.dao;
import com.projcore.util.ToString;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.hibernate.validator.constraints.NotEmpty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.constraints.Size;
import Java.util.List;
import Java.util.Set;
/**
* The data transfer object that contains the information of a Registration
* and validation rules for attributes.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public final class Registration {
private static final Logger LOGGER = LoggerFactory.getLogger(Registration.class);
private String id;
@NotEmpty
@Size(max = 255)
private String messageId;
@NotEmpty
@Size(max = 255)
private String version;
@Size(max = 255)
private String system;
public Registration() {
}
private Registration(Builder builder) {
this.id = builder.id;
this.messageId = builder.messageId;
this.version = builder.version;
this.system = builder.system;
}
public static Builder getBuilder() {
return new Builder();
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMessageId() {
return messageId;
}
public void setMessageId(String messageId) {
this.messageId = messageId;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getSystem() {
return system;
}
public void setSystem(String system) {
this.system = system;
}
@Override
public String toString() {
return ToString.create(this);
}
/**
* Builder pattern makes the object easier to construct in one line.
*/
public static class Builder {
private String id;
private String messageId;
private String version;
private String system;
private Builder() {}
public Builder id(String id) {
this.id = id;
return this;
}
public Builder messageId(String messageId) {
this.messageId = messageId;
return this;
}
public Builder version(String version) {
this.version = version;
return this;
}
public Builder system(String system) {
this.system = system;
return this;
}
public Registration build() {
Registration entry = new Registration(this);
// *** Would like to trigger spring validation here ***
Set violations = validate(entry);
if (violations.isEmpty())
return entry;
else
throw new RuntimeException(violations.toString());
}
private Set validate(Registration entry) {
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
Set<ConstraintViolation<Registration>> constraintViolations = validator.validate(entry);
return constraintViolations;
}
}
}
検証はここで正常に機能します。
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
Registration create(@RequestBody @Valid Registration registration)
解決:
Registraion.Builder.validate()を削除しました。 Registraion.Builder.build()を以下に更新しました:
public Registration build() {
Registration entry = new Registration(this);
return (Registration) ValidatorUtil.validate(entry);
}
ValidationUtil.Java
package projcore.util;
import com.ericsson.admcore.error.InvalidDataException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;
import org.springframework.validation.beanvalidation.SpringValidatorAdapter;
import javax.validation.Validation;
import javax.validation.Validator;
import Java.util.Set;
public class ValidatorUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(ValidatorUtil.class);
private static final Validator javaxValidator = Validation.buildDefaultValidatorFactory().getValidator();
private static final SpringValidatorAdapter validator = new SpringValidatorAdapter(javaxValidator);
public static Object validate(Object entry) {
Errors errors = new BeanPropertyBindingResult(entry, entry.getClass().getName());
validator.validate(entry, errors);
if (errors == null || errors.getAllErrors().isEmpty())
return entry;
else {
LOGGER.error(errors.toString());
throw new InvalidDataException(errors.getAllErrors().toString(), errors);
}
}
}
InvalidDataException.Java
package projcore.error;
import org.springframework.validation.Errors;
/**
* This exception is thrown when the dao has invalid data.
*/
public class InvalidDataException extends RuntimeException {
private Errors errors;
public InvalidDataException(String msg, Errors errors) {
super(msg);
setErrors(errors);
}
public Errors getErrors() {
return errors;
}
public void setErrors(Errors errors) {
this.errors = errors;
}
}
Springは、JSR-303 Bean Validation APIを完全にサポートしています。これには、JSR-303実装をSpring Beanとしてブートストラップするための便利なサポートが含まれます。これにより、アプリケーションで検証が必要な場所にjavax.validation.Validatorを挿入できます。
LocalValidatorFactoryBeanを使用して、デフォルトのJSR-303バリデーターをSpring Beanとして構成します。
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
上記の基本設定により、デフォルトのbootstrap=メカニズムを使用してJSR-303が初期化されます。HibernateValidatorなどのJSR-303プロバイダーは、クラスパスに存在し、自動的に検出されます。 。
5.7.2.1バリデータの挿入
LocalValidatorFactoryBean implements both javax.validation.Validator and org.springframework.validation.Validator.
これら2つのインターフェースのいずれかへの参照を、検証ロジックを呼び出す必要のあるBeanに挿入できます。
JSR-303 APIを直接操作する場合は、javax.validation.Validator
への参照を挿入します。
// JSR-303 Validator
import javax.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;
}
BeanでSpring Validation APIが必要な場合は、org.springframework.validation.Validator
への参照を挿入します。
// Spring Validator
import org.springframework.validation.Validator;
@Service
public class MyService {
@Autowired
private Validator validator;
}
これはよく説明された例です 「古典的な」Spring ValidatorsでJSR 303を使用する(SpringValidatorAdapterを入力してください)
このリンクは非常に役立ちます。 org.springframework.validation.beanvalidation.SpringValidatorAdapterでjavax.validation.Validatorをラップすると、エラーを一貫して処理するのに役立ちました。これを回答として追加して、受け入れられるようにできますか
および 春のドキュメントはこちら