序列化 @Validated class
Serializing a @Validated class
假设我有一个属性 class 正在 Class
中使用,需要由 Spring 缓存序列化,使用 Redis 作为实现。我还通过使用 Spring 的 @Validated
(docs) 注释来验证此 class。
@ConfigurationProperties(prefix = "myprops")
@Validated
public class MyProps implements Serializable {
}
@EnableConfigurationProperties(MyProps.class)
@Named
public class ClassThatNeedsToBeSerialized implements Serializable {
@Inject
private MyProps myProps;
}
正在尝试缓存此 class 的实例:
@Inject
private ClassThatNeedsToBeSerialized classThatNeedsToBeSerialized;
@Cacheable("my-cache")
public ClassThatNeedsToBeSerialized fetch() {
return classThatNeedsToBeSerialized;
}
将使用以下堆栈跟踪抛出异常:
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
注释的 class 吗?如果没有,是否有类似的替代方案可以工作?
我已经通过注册 configurationPropertiesValidator
bean 解决了这个问题 here:
为 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
- 没有注释
假设我有一个属性 class 正在 Class
中使用,需要由 Spring 缓存序列化,使用 Redis 作为实现。我还通过使用 Spring 的 @Validated
(docs) 注释来验证此 class。
@ConfigurationProperties(prefix = "myprops")
@Validated
public class MyProps implements Serializable {
}
@EnableConfigurationProperties(MyProps.class)
@Named
public class ClassThatNeedsToBeSerialized implements Serializable {
@Inject
private MyProps myProps;
}
正在尝试缓存此 class 的实例:
@Inject
private ClassThatNeedsToBeSerialized classThatNeedsToBeSerialized;
@Cacheable("my-cache")
public ClassThatNeedsToBeSerialized fetch() {
return classThatNeedsToBeSerialized;
}
将使用以下堆栈跟踪抛出异常:
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
注释的 class 吗?如果没有,是否有类似的替代方案可以工作?
我已经通过注册 configurationPropertiesValidator
bean 解决了这个问题 here:
为 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
- 没有注释