Default params is a Kotlin feature. Jackson does not know about it hence we need to inform it somehow to be able to support it. Thankfully there's the excellent jackson-module-kotlin which let's you do:
val mapper: ObjectMapper = ObjectMapper()
.registerKotlinModule() //let Jackson know about Kotlin via extension method
...
data class SomeData(
private val notInJson: String = "some default value",
private val inJson: String
)
...
val data = mapper.readValue<SomeData>("""{"inJson": "sample value"}""")
println(data) // -> SomeData(notInJson=some default value, inJson=sample value)
For instructions how to use it take a look at jackson-module-kotlin Readme and pay special attention to versions of the module and Jackson itself. In order for the default parameters to work you need at least version 2.8.4 of jackson-module-kotlin
Hi I am having a problem with a kotlin data class and proguard.
Caused by: com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class com.app.models.tile.TileConfig]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?)
found for type". I have this on my config file for keeping jackson and the package I am having problem with
-keep class com.app.models.** -keep class com.fasterxml.jackson.**
I also use the jackson kotlin plugin. This is my data class
data class TileConfig( var color: String?, var icons: List<TileConfigIcon > = ArrayList())
does anyone know how to fix this problem?
Deserialization fails for a data class where one or more constructor arguments have no default
See if there is benefit from integrating with jackson-databind better wrt detecting "default" Constructor for Kotlin (data) classes
json - How do you make Jackson use Kotlin default params for missing values? - Stack Overflow
Unexpected behavior when using `NON_DEFAULT` with `data class`
@JsonProperty annotations in your code are all put on private fields within your data class and by default Jackson doesn't scan private fields for annotations. You have to instruct it to do otherwise by putting @JsonAutoDetect annotation:
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
data class CurrencyInfo(
@JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
or alternatively you can move your annotations on accessor methods:
data class CurrencyInfo(
@get:JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
You can do something like this:
data class CurrencyInfo @JsonCreator constructor (
@param:JsonProperty("currency_info")
@get:JsonProperty("currency_info")
val currencyInfo: CurrencyInfoItem?
)
code above translates to java as:
public final class CurrencyInfo {
@Nullable
private final String currencyInfo;
@JsonProperty("currency_info")
@Nullable
public final String getCurrencyInfo() {
return this.currencyInfo;
}
@JsonCreator
public CurrencyInfo(@JsonProperty("currency_info") @Nullable String currencyInfo) {
this.currencyInfo = currencyInfo;
}
}
code from accepted answer translates to java as following:
First (is not pure immutable):
@JsonAutoDetect(
fieldVisibility = Visibility.ANY
)
public final class CurrencyInfo {
@Nullable
private String currencyInfo;
@Nullable
public final String getCurrencyInfo() {
return this.currencyInfo;
}
public final void setCurrencyInfo(@Nullable String var1) {
this.currencyInfo = var1;
}
public CurrencyInfo(@JsonProperty("currency_info") @Nullable String currencyInfo) {
this.currencyInfo = currencyInfo;
}
}
Second (probably has problems with deserialization):
public final class CurrencyInfo {
@Nullable
private final String currencyInfo;
@JsonProperty("currency_info")
@Nullable
public final String getCurrencyInfo() {
return this.currencyInfo;
}
public CurrencyInfo(@Nullable String currencyInfo) {
this.currencyInfo = currencyInfo;
}
}
Reason:
This error occurs because Jackson Library doesn't know how to create your model which doesn't have an empty constructor and the model contains a constructor with parameters that didn't annotate its parameters with @JsonProperty("field_name"). By default Java compiler creates an empty constructor if you didn't add a constructor to your class.
Solution:
Add an empty constructor to your model or annotate constructor parameters with @JsonProperty("field_name")
If you use a Kotlin data class then also can annotate with @JsonProperty("field_name") or register jackson module kotlin to ObjectMapper.
You can create your models using http://www.jsonschema2pojo.org/.
If you're using Lombok on a POJO model, make sure you have these annotations:
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
It could vary, but make sure @Getter and especially @NoArgsConstructor.