序列化@Validated类

时间:2018-04-18 11:14:28

标签: java spring bean-validation

假设我有一个属性类在Class中使用,需要由Spring Cache序列化,使用Redis作为实现。我也使用Spring的@Validateddocs)注释来验证这个类。

@ConfigurationProperties(prefix = "myprops")
@Validated
public class MyProps implements Serializable {

}

@EnableConfigurationProperties(MyProps.class)
@Named
public class ClassThatNeedsToBeSerialized implements Serializable {
   @Inject
   private MyProps myProps;
}

尝试缓存此类的实例:

@Inject
private ClassThatNeedsToBeSerialized classThatNeedsToBeSerialized;

@Cacheable("my-cache")
public ClassThatNeedsToBeSerialized fetch() {
   return classThatNeedsToBeSerialized;
}

将使用以下stacktrace抛出异常:

org.springframework.core.serializer.support.SerializationFailedException: Failed to serialize object using DefaultSerializer; nested exception is java.io.NotSerializableException: org.springframework.validation.beanvalidation.MethodValidationInterceptor
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:68)
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:35)
        at org.springframework.data.redis.serializer.JdkSerializationRedisSerializer.serialize(JdkSerializationRedisSerializer.java:94)
        ... 31 common frames omitted
    Caused by: java.io.NotSerializableException: org.springframework.validation.beanvalidation.MethodValidationInterceptor
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
        at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1378)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
        at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
        at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
        at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
        at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
        at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348)
        at org.springframework.core.serializer.DefaultSerializer.serialize(DefaultSerializer.java:46)
        at org.springframework.core.serializer.support.SerializingConverter.convert(SerializingConverter.java:63)
        ... 33 common frames omitted 

有没有办法序列化用@Validated注释的类?如果没有,是否有类似的替代方案可行?

1 个答案:

答案 0 :(得分:0)

我通过注册here解释configurationPropertiesValidator bean来解决这个问题:

MyClass

创建自定义验证程序
public class ClassThatNeedsToBeSerializedValidator implements Validator {

    @Override
    public boolean supports(Class<?> clazz) {
        return ClassThatNeedsToBeSerialized.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors) {
        //Validate
    }
}

将其注册为bean:

    @Bean
    public Validator configurationPropertiesValidator() {
        return new ClassThatNeedsToBeSerializedValidator();
    }

ClassThatNeedsToBeSerialized现在可以实现Serializable并在没有问题的情况下进行序列化。其缺点是:

  • 据我所知,无法注册多个configurationPropertiesValidators
  • 没有注释