简体   繁体   中英

Jackson with Kotlin: how to serialize only annotated properties

I'm trying to start using Kotlin in my existing Java project, but Jackson is not detecting the @JsonProperty in my Kotlin objects (whereas it works perfectly with Java objects).

Any way to configure Jackson to make this work for Kotlin like it works for Java?

Here is the Java class:

public class TestJavaObj {
    @JsonProperty
    private String includeMe;
    private String dontIncludeMe;

    public TestJavaObj(String includeMe, String dontIncludeMe) {
        this.includeMe = includeMe;
        this.dontIncludeMe = dontIncludeMe;
    }
}

and the Kotlin class:

class TestKotlinObj(
    @JsonProperty val includeMe: String,
    val dontIncludeMe : String?
)

Here is the test code:

public static void main(String[] args) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper()
            .registerModule(new KotlinModule()) //jackson-module-kotlin
            .configure(MapperFeature.AUTO_DETECT_GETTERS, false)
            .configure(MapperFeature.AUTO_DETECT_CREATORS, false)
            .configure(MapperFeature.AUTO_DETECT_FIELDS, false)
            .configure(MapperFeature.AUTO_DETECT_IS_GETTERS, false)
            .configure(MapperFeature.AUTO_DETECT_SETTERS, false);

    TestJavaObj javaObj = new TestJavaObj("hello", "world");
    TestKotlinObj kotlinObj = new TestKotlinObj("hello", "world");

    System.out.println("Expected: " + mapper.writeValueAsString(javaObj));
    System.out.println("Got: " + mapper.writeValueAsString(kotlinObj));
}

And here is the output:

Expected: {"includeMe":"hello"}
Got: {}

Version numbers from my gradle file:

kotlin_version = '1.3.72'
...
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version" 
...
apply plugin: 'kotlin'
...
compile('com.fasterxml.jackson.core:jackson-annotations:2.10.3')
compile('com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8')
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"

Specify annotation use-site target :

class TestKotlinObj(
        @get:JsonProperty val includeMe: String,
        val dontIncludeMe : String
)

Result:

Expected: {"includeMe":"hello"}
Got: {"includeMe":"hello"}

Background :

The class translated to Java bytecode has only a constructor parameter annotated:

public final class TestKotlinObj {
   @NotNull // no annotation here
   private final String includeMe;
   @NotNull
   private final String dontIncludeMe;

   @NotNull // nor here
   public final String getIncludeMe() {
      return this.includeMe;
   }

   @NotNull
   public final String getDontIncludeMe() {
      return this.dontIncludeMe;
   }
                     // but here
                     // vvvv 
   public TestKotlinObj(@JsonProperty @NotNull String includeMe, @NotNull String dontIncludeMe) {
      Intrinsics.checkParameterIsNotNull(includeMe, "includeMe");
      Intrinsics.checkParameterIsNotNull(dontIncludeMe, "dontIncludeMe");
      super();
      this.includeMe = includeMe;
      this.dontIncludeMe = dontIncludeMe;
   }
}

Which is not taken into account when serializing the object.

See related issue: Kotlin data class Jackson @JsonProperty not honored

Try changing the Kotlin class to this:

class TestKotlinObj {
    @JsonProperty
    val includeMe: String;
    val dontIncludeMe : String;

    constructor(includeMe: String, dontIncludeMe: String) {
      this.includeMe = includeMe;
      this.dontIncludeMe = dontIncludeMe;
    }
}

It may be that the current Kotlin class you have is equivalent to this in java (which would obviously not work):

public class TestJavaObj {
    public String includeMe;
    public String dontIncludeMe;

    public TestJavaObj(@JsonProperty String includeMe, String dontIncludeMe) {
        this.includeMe = includeMe;
        this.dontIncludeMe = dontIncludeMe;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM