0

I want to serialize some string json (I use Spring Boot):

{
  "commandId": "34d3a914-a3d7-112a-bs37-3452ac130002",
  "status": "SUCCESS",
  "response": {
    "prop1": "",
    "prop2": "",
    "prop3": "true",
    "prop4": ""
  }
}

My mapper:

private static final ObjectMapper mapper = new ObjectMapper();

public static <T> T fromJson(String json, TypeReference<T> type) {
    T t;
    try {
      t = mapper.reader().forType(type).readValue(json);
    } catch (IOException e) {
      String message = "Error converting from json";
      log.error(message, e);
      throw new IllegalArgumentException(message);
    }

The usage of the mapper:

final Command command =
              JsonUtils.fromJson(json, new TypeReference<Command>() {});

Command class:

public class Command {
  private UUID commandId;
  private status status;
  private String response;
  private String error;
}

Currently I get the error:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token

I want to save in Mongo db response field as string and later on after receiving that object from DB I can deserialize the whole object. Is there any annotation to tell the Json mapper to not to serialize the structure inside the response field?

Laurel
  • 5,965
  • 14
  • 31
  • 57
Matley
  • 1,953
  • 4
  • 35
  • 73

2 Answers2

0

You can write a custom deserializer for response field to deserialize reponse node object as string. And use it one reponnse field using @JsonDeserialize.

public class Command {
  ...
  @JsonDeserialize(using = RawJsonDeserializer.class)
  private String response;
  ...
}

public class RawJsonDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser jp, DeserializationContext ctxt)
           throws IOException, JsonProcessingException {
        ObjectMapper mapper = (ObjectMapper) jp.getCodec();
        JsonNode node = mapper.readTree(jp);
        return mapper.writeValueAsString(node);
    }
}
Eklavya
  • 17,618
  • 4
  • 28
  • 57
0

Other than having a deserializer, another simpler approach is using @JsonProperty annotation in your Command class.

public class Command {
  private UUID commandId;
  private String status;
  private String response;
  private String error;

  public UUID getCommandId() {
    return commandId;
  }

  @JsonProperty("commandId")
  public void setCommandId(String commandId) {
    this.commandId = UUID.fromString(commandId);
  }

  public String getStatus() {
    return status;
  }

  public void setStatus(String status) {
    this.status = status;
  }

  public String getResponse() {
    return response;
  }

  @JsonProperty("response")
  private void setResponse(Map<String, String> response) {
    this.response = response.toString();
  }

  public String getError() {
    return error;
  }

  public void setError(String error) {
    this.error = error;
  }
}
Abhinaba Chakraborty
  • 3,488
  • 2
  • 16
  • 37