[英]How to deserialize enum by implemented interface without knowing sub-classes
I am writing a custom spring boot starter that provides a uniform error response class for all repositories that will add this starter.
我正在编写一个自定义的 spring 引导启动程序,它为将添加此启动程序的所有存储库提供统一的错误响应 class。 It also provides the corresponding exception handler.
它还提供了相应的异常处理程序。 The problem is, that this error response needs an error code which might differ between all those repositories, using my starter.
问题是,这个错误响应需要一个错误代码,它可能在所有这些存储库之间不同,使用我的启动器。 So the solution would be to create an error response with an error code that is an interface.
所以解决方案是创建一个错误响应,错误代码是一个接口。 Other repositories can then create enums implementing this interface to achieve the desired behavior.
然后其他存储库可以创建实现此接口的枚举以实现所需的行为。 It is written in kotlin
写在kotlin
interface BaseErrorCode {
val message: String
}
class ErrorResponse {
val customMessage: String,
val errorCode: BaseErrorCode,
val timestamp: OffsetDateTime
}
Now, in another repository, I use this starter, get access to the classes above and create my error code enum:
现在,在另一个存储库中,我使用这个启动器,访问上面的类并创建我的错误代码枚举:
enum class MyCustomErrorCodes : BaseErrorCode {
FOO
}
Now, I can throw an exception and through the handler, this json will be produced:
现在,我可以抛出异常并通过处理程序生成这个 json:
{
"customMessage": "My message",
"errorCode": "FOO",
"timestamp": "2023-01-27T12:15:31.7730645+01:00"
}
So serializing works absolutely fine.
所以序列化工作绝对没问题。
However, when deserializing the ErrorResponse in my integration-tests, I get the following exception:
但是,在我的集成测试中反序列化ErrorResponse时,出现以下异常:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `my.package.BaseErrorCode` (no Creators, like default constructor, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
at [Source: (String)"{"customMessage":"My message","errorCode":"FOO","timestamp":"2023-01-27T12:12:06.4932227+01:00"}"; line: 1, column: 54] (through reference chain: my.package.ErrorResponse["errorCode"])
Approach 1 I know a solution where you write a custom deserializer.
方法 1我知道一个解决方案,您可以在其中编写自定义解串器。 But this could not be placed in the spring boot starter because I need to know the implementing classes of that ´BaseErrorCode`-interface.
但这不能放在 spring 引导启动器中,因为我需要知道该“BaseErrorCode”接口的实现类。
Approach 2 Using @JsonSubType , I can also tell Jackson how to handle this interface.
方法 2使用@JsonSubType ,我还可以告诉 Jackson 如何处理这个接口。 But I do need some information about implementing enums as well, which I do not have in my starter
但是我也确实需要一些关于实现枚举的信息,我的启动器中没有这些信息
Is there any way to deserialize this error response
有没有办法反序列化这个错误响应
BaseErrorCode , BUT knowing that it will ALWAYS be an enum?BaseErrorCode的类,但知道它总是一个枚举?I think the answer lies in using intentionally dissimilar objects.
我认为答案在于有意使用不同的对象。 I have not tested, but I think:
我没有测试过,但我认为:
enum rather an instance of enum which conforms to BaseErrorCode .enum ,而是序列化符合BaseErrorCode的enum实例。BaseErrorCode (this can be private to the Starter) that you deserialize the JSON in to.BaseErrorCode (这对于 Starter 来说是私有的)进行了具体实现,您将 JSON 反序列化到其中。 (Adding @JsonIgnoreProperties(ignoreUnknown = true) to guard against an unknown subclass sending more data than you can deal with). @JsonIgnoreProperties(ignoreUnknown = true)以防止未知子类发送超出您处理能力的数据)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.