【问题标题】:JSON serialization - how not to serialize one class property with the whole structureJSON序列化-如何不使用整个结构序列化一个类属性
【发布时间】:2020-07-05 11:52:57
【问题描述】:

我想序列化一些字符串json(我用的是Spring Boot):

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

我的映射器:

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);
    }

mapper的用法:

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

命令类:

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

目前我收到错误:

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

我想在 Mongo db response 字段中保存为字符串,稍后在从 DB 接收到该对象后,我可以反序列化整个对象。是否有任何注释告诉 Json 映射器不要序列化 ​​response 字段内的结构?

【问题讨论】:

    标签: java json spring-boot json-deserialization json-serialization


    【解决方案1】:

    您可以为response 字段编写自定义反序列化程序,以将响应节点对象反序列化为字符串。并使用@JsonDeserialize 使用它一个reponnse 字段。

    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);
        }
    }
    

    【讨论】:

      【解决方案2】:

      除了反序列化器之外,另一种更简单的方法是在您的 Command 类中使用 @JsonProperty 注释。

      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;
        }
      }
      

      【讨论】:

      • 实际上现在 response 没有反序列化为 Map&lt;String, String&gt; 并且您正在制作地图的 toString。所以它不再是 json 了,我认为 OP 想再次反序列化。然后就不行了。
      • @Eklavya 完全同意。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-10
      相关资源
      最近更新 更多