Automatic deserialization from String to object for @RequestBody in Spring

Issue

I am having issues with serialization and as much as I have been looking around, I am not able to find a solution to this.

I have inside my @RestController something similar to this method for and endpoint:

public ResponseEntity<String>(@RequestBody RequestObject requestObject )

The RequestObject looks like this:

public class RequestObject {

  private Driver driver;
  private List<Tracks> tracks;
  //constructors, getters and setters
}
public class Tracks {

    private Enum1 name;
    private List<Enum2> missions;
    //constructors, getters and setters
}

So, the problem comes with the Listof Enum2. This is because what I receive from the JSON is not a list of strings, but rather a string, that I need to parse to convert to the values of Enum2

So Enum2 looks like this:

    A,
    B,
    C;

And what I get from the request as a JSON is:

{
    "driver" : {
        "name" : "myname"
        }
    },
    "tracks" : [
    {
        "name" : "madrid",
        "missions" : "ABCCBA"
    },
    {
        "name" : "barcelona",
        "mission" : "CBBCA"
    },
   ]

}

Thing is all deserialization works perfectly out of the box (including all nested enums) except for the List<Enum2> missions

I have managed to do a dirty trick, but I’d like to do it the proper way, which I understand would be to write some kind of deserializer that runs when the controller is fired and that does all that parsing and converting from the string to the list (this splitting code I do have it, but I don’t know where to put it).

At the moment I am getting this

2021-09-13 21:02:34.924  WARN 99904 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.ArrayList<org.package.model.Enum2>` from String value (token `JsonToken.VALUE_STRING`); nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<org.model.Enum2>` from String value (token `JsonToken.VALUE_STRING`)
 at [Source: (PushbackInputStream); line: 13, column: 26] (through reference chain: org.model.RequestObject["missions"]->java.util.ArrayList[0]-org.model.Track["missions"])]

Is there a way to do this at all?

Solution

I found the solution. I had to mark Track as follows:

@JsonDeserialize(using = TrackDeserializer.class)
public class Track

and the write the TrackDeserializer:

public class TrackDeserializer extends JsonDeserializer<Track>{
    @Override
    public Track deserialize(JsonParser j, DeserializationContext ctxt) throws IOException{

        JsonNode jsonNode = j.getCodec().readTree(jsonParser);

        String name = jsonNode.get("name").asText();
        final List<Enum2> enum = parseEnums(jsonNode.get("mission").asText());

        return new Track(name, enum);
    }

And parseEnums does the splitting and conversion to list.

Now TrackDeserializer is called for every Track with the given JSON in the question.

Answered By – user3083022

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published