Java 8 Optional<?> validation unwrapper in Spring Java 8 Optional<?> validation unwrapper in Spring spring spring

Java 8 Optional<?> validation unwrapper in Spring


You should register a ValidatedValueUnwrapper to the validator.

The validator could be configured via the LocalValidatorFactoryBean:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:util="http://www.springframework.org/schema/util"  xsi:schemaLocation="    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">  <bean name="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">    <property name="validationPropertyMap">      <util:map>        <entry key="hibernate.validator.validated_value_handlers"                value="com.mycompany.validator.OptionalValidatedValueUnwrapper"/>      </util:map>    </property>  </bean></beans>

or in java:

@Beanpublic LocalValidatorFactoryBean validator() {    LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();    validator.getValidationPropertyMap().put("hibernate.validator.validated_value_handlers",            "com.mycompany.validator.OptionalValidatedValueUnwrapper");    return validator;}

You could find a proper ValidatedValueUnwrapper implementation in the dropwizard framework (based on the Optional from guava).

public class OptionalValidatedValueUnwrapper extends ValidatedValueUnwrapper<Optional<?>> {    private final TypeResolver resolver = new TypeResolver();    @Override    public Object handleValidatedValue(final Optional<?> optional) {        return optional.orNull();    }    @Override    public Type getValidatedValueType(final Type type) {        ResolvedType resolvedType = resolver.resolve(type);        return resolvedType.typeParametersFor(Optional.class).get(0).getErasedType();    }}