当前位置: 首页 > 知识库问答 >
问题:

如何在静态编程语言中使用Jackson JsonSubTypes注释

骆昊阳
2023-03-14

我试图转换一些使用Jackson的@JsonSubTypes注释来管理多态性的Java代码。

以下是可用的Java代码:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Comment.class, name = "CommentNote"),
    @JsonSubTypes.Type(value = Photo.class, name = "PhotoNote"),
    @JsonSubTypes.Type(value = Document.class, name = "DocumentNote")
})
public abstract class Note implements Identifiable {
    [...]

以下是我认为等效的Kotlin代码:

JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
JsonSubTypes(
    JsonSubTypes.Type(value = javaClass<Comment>(), name = "CommentNote"),
    JsonSubTypes.Type(value = javaClass<Photo>(), name = "PhotoNote"),
    JsonSubTypes.Type(value = javaClass<Document>(), name = "DocumentNote")
)
abstract class Note : Identifiable {
    [...]

但我在三行“JsonSubTypes.Type”中的每一行都会出现以下错误:

Kotlin: An annotation parameter must be a compile-time constant
Kotlin: Annotation class cannot be instantiated

知道吗?

共有3个答案

水飞掣
2023-03-14

我知道这是一个老问题,但是如果有人仍然在寻找解决方案来使用jackson在kotlin中序列化/反序列化继承的类,我建议使用密封的类而不是使用@JsonSubTypes

我还建议使用include作为EXISTING_PROPERTY并通过密封类中的val获取属性。否则,如果您在数组中添加组合继承对象,杰克逊将无法反序列化并将抛出一个com.fasterxml.jackson.databind.exc.InvalidTypeIdException

以下是示例用法:

@JsonTypeInfo(
   use = JsonTypeInfo.Id.NAME,
   include = JsonTypeInfo.As.EXISTING_PROPERTY,
   property = "type")
sealed class Note{
    val type = this::class.java.simpleName
}
data class Document(val text: String, ...) : Note()

这应该很有魅力,包括在数组中使用这个类!

这种方法的另一大优点是,您不需要手动设置任何内容。众所周知,手动操作容易出错,因为在添加或删除子类、修改名称等的情况下,您可能会忘记添加/删除/修改。在这种方法中,您既不需要手动雕刻子类型列表,也不需要手动提供类名的json表示。

谷奕
2023-03-14

原来这是编译器中的一个错误,感谢您报告它。要解决此问题,您可以导入JsonSubTypes。键入并无限制地使用它:

import org.codehaus.jackson.annotate.JsonSubTypes.Type

JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
JsonSubTypes(
    Type(value = javaClass<Comment>(), name = "CommentNote"),
    Type(value = javaClass<Photo>(), name = "PhotoNote"),
    Type(value = javaClass<Document>(), name = "DocumentNote")
)
abstract class Note : Identifiable {
    [...]
张绍晖
2023-03-14

我相信这已经解决了,现在你可以这样写:

import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo

@JsonTypeInfo(
   use = JsonTypeInfo.Id.NAME,
   include = JsonTypeInfo.As.PROPERTY,
   property = "type")
   @JsonSubTypes(
       JsonSubTypes.Type(value = Comment::class, name = "CommentNote"),
       JsonSubTypes.Type(value = Photo::class, name = "PhotoNote"),
       JsonSubTypes.Type(value = Document::class, name = "DocumentNote"))
interface Note

注意JsonSubTypes.Type中缺少@和类符号。

 类似资料:
  • 上下文:我想在Spring Boot中创建一个自定义注释,并为处理添加额外的逻辑。我举了一个注释非常简单的例子,但我希望有几个这样的注释具有更细粒度的控制。 解决这个问题有几种方法: 创建过滤器 创建拦截器 使用自定义处理创建注释 我必须使用最新的一个,因为上面两个不适用于我的用例。 问题: 我在静态编程语言中有一个自定义注释,我希望它被注册并在运行时被检查。 REST控制器如下: 其思想是每个方

  • 我试图用OkHttp和Cucumber在静态编程语言中设置一个Spring启动项目,并且在运行Cucumber任务时遇到以下错误。如何修复? 还有build gradle kts片段 我看到了这个错误https://github.com/square/okio/issues/647看起来可能是它,并修复了这个build.gradle,我如何将其翻译为kotlinbuild.gradle.kts?

  • 我有以下问题:-创建了几个模块来实现类,并用-我的Android应用程序正在使用检索这些类。但是由于某种原因,没有在

  • 我试图将@Age constraint的实现从java复制到Kotlin,我复制了Java代码库,并使用IDE将其转换为Kotlin代码。 Java代码 Intellij生成的对应静态编程语言代码 Kotlin代码导致错误声明“注释类中不允许成员”。将注释类List从Age中移出是否可以解决此问题?还有其他方法可以在另一个类中实现注释类吗? 非常感谢。

  • 我知道内联函数可能会提高性能 编译器可以发出以下代码,而不是为参数创建函数对象并生成调用。(来源) 但是我发现没有kotlin为一个非内联函数创建的函数对象。为什么?

  • 我使用的是Gradle 5.5,我有一个基于Groovy的构建脚本,我正试图将其迁移到Kotlin DSL。任务包含将所有依赖项复制到jar文件的典型行: 我找不到一种方法来把这一行翻译成Kotlin DSL。 让我给你一些背景知识。这是我最初基于Groovy的构建脚本: 这是我基于静态编程语言的构建脚本。它运行良好,除了一行: