2

I'm trying to serialize and deserialize an enum with Jackson.

My enum:

public enum class Type {
    @JsonProperty("Typ A")
    TypeA,
    @JsonProperty("Typ B")
    TypeB,
}

Serializing Type.TypeA results in the desired outcome of "Typ A". However Deserializing "Typ A" results in the following error:

java.lang.IllegalArgumentException: No enum constant de.advisori.pzp.task.TaskType.Typ A

I have tried other variations that I found online, such as this:

public enum class Type (@JsonValue val value: String) {
    TypeA("Typ A"),
    TypeB("Typ B"),
}

but they all yield the same result. Serialization works, deserialization results in the error above.

How do I correctly deserialize an enum with Jackson?

If it makes any difference: I am using it in a Spring Boot RequestMapping as a @RequestParam and return value.

Finn
  • 326
  • 3
  • 11
  • 2
    I can't help with Jackson, but if you don't find a better answer, maybe you can take advantage of Kotlin's ability to include spaces in names: `public enum class Type { \`Typ A\`, \`Typ B\` }` – DodgyCodeException Jan 13 '23 at 16:39
  • 1
    If you share the rest of that stack trace, I'm guessing you'll find Jackson is not involved in this particular deserialization, and you'll need to configure Spring to do the conversion. See https://stackoverflow.com/questions/75053897/deserialize-requestparam-enum-case-insensitive-in-spring-boot-using-jackson – dnault Jan 13 '23 at 21:10
  • Does this answer your question? [How to annotate enum fields for deserialization using Jackson json](https://stackoverflow.com/questions/9300191/how-to-annotate-enum-fields-for-deserialization-using-jackson-json) – aSemy Jan 13 '23 at 21:57
  • 1
    Take a look at that question: [Serialize @JsonProperty value of enum to @RequestParam](https://stackoverflow.com/questions/69030789/serialize-jsonproperty-value-of-enum-to-requestparam) – Michał Ziober Jan 15 '23 at 23:09
  • @dnault Yes, indeed, it seems RequestParams are treated as raw values and not as JSON that could be deserialized. Hence `@JsonProperty` can only be used on a RequestBody. I ended up using @DodgyCodeException s "solution" of using enums with spaces, as it seemed the best fit for my current application. For anyone else coming across this in the future, the question suggested by @Michal Ziober seems to have a good answer for defining an explicit converter: https://stackoverflow.com/a/69031139/12898394 – Finn Jan 16 '23 at 10:28

2 Answers2

0

As @dnault pointed out, Jackson isn't used for deserialization here. @RequestParams are never treated as JSON, hence Jackson is never used on them.

Two possible solutions are:

  • Using Kotlins ability to use spaces in names: public enum class Type { `Typ A`, `Typ B` } (suggested by @DodgyCodeException)
  • Using a explicitly defined converter: https://stackoverflow.com/a/69031139/12898394 (pointed in the right direction by @Michal Ziober
Finn
  • 326
  • 3
  • 11
-1

I don't think any annotations will work to change the enum values. For this you need to write your own Serializer and Deserializer.

You will likely want to do this:

  1. Create a Serializer by subclassing StdSerializer
  2. Create a Deserializer by subclassing StdDeserializer
  3. If you intend on using the enum as a key in JSON you will need KeyDeserializer too
  4. Create a Module to wrap these up that you can pass to the configuration of Jackson, for that you use SimpleModule

There are many tutorials for this, e.g. https://www.baeldung.com/jackson-deserialization

AndrewL
  • 2,034
  • 18
  • 18
  • Downvoted because Jackson annotations can indeed alter how enum values are serialized and deserialized by Jackson. – dnault Jan 13 '23 at 21:07