当前位置: 首页 > 知识库问答 >
问题:

如何在Jackson中正确反序列化映射

王炜
2023-03-14

我有以下POJO,可以序列化为字节或JSON

public final class Message {

  private final Data data;
  private final Request request;
  private final Response response;

  public Message() {
    this.data = new Data();
    this.request = new Request();
    this.response = new Response();
  }

  public Data getData() {
    return data;
  }

  public Request getRequest() {
    return request;
  }

  public Response getResponse() {
    return response;
  }

  public Object query(String pointer) {
    return toJson().query(pointer);
  }

  public byte[] toBytes() {
    try {
      return new ObjectMapper(new MessagePackFactory()).writeValueAsBytes(this);
    } catch (JsonProcessingException ex) {
      throw new MessageException(ex);
    }
  }

  public JSONObject toJson() {
    try {
      return new JSONObject(new ObjectMapper().writeValueAsString(this));
    } catch (JsonProcessingException ex) {
      throw new MessageException(ex);
    }
  }

  @Override
  public String toString() {
    try {
      return toString(0);
    } catch (MessageException ex) {
      throw new MessageException(ex);
    }
  }

  public String toString(int indent) {
    try {
      return toJson().toString(indent);
    } catch (MessageException ex) {
      throw new MessageException(ex);
    }
  }
}
public class Data {

  private final Map<String, Map<String, Object>> dataMap;

  public Data() {
    this.dataMap = new HashMap();
  }

  public Data addToSet(String name, String key, Object value) {
    Map<String, Object> map = dataMap.get(name);
    if (map == null) {
      map = new HashMap();
    }
    map.put(key, value);
    dataMap.put(name, map);
    return this;
  }

  public Map<String, Map<String, Object>> getSets() {
    return dataMap;
  }

  public Data updateSet(String name, String key, Object value) {
    return Data.this.addToSet(name, key, value);
  }

  public Data removeFromSet(String name, String key) {
    Map<String, Object> map = dataMap.get(name);
    if (map == null) {
      throw new MessageException("No such property '" + key + "' for set '" + name + "'");
    }
    map.remove(key);
    return this;
  }

  public Map<String, Object> getSet(String name) {
    return dataMap.get(name);
  }
}
public class Request {

  private String method;
  private String resource;
  private final Map<String, Object> body;
  private final Map<String, String> headers;
  private final Map<String, String[]> parameters;

  public Request() {
    this.body = new HashMap();
    this.headers = new HashMap();
    this.parameters = new HashMap();
  }

  public String getMethod() {
    return Objects.toString(method, "");
  }

  public String getResource() {
    return Objects.toString(resource, "");
  }

  public Map<String, Object> getBody() {
    return body;
  }

  public Map<String, String> getHeaders() {
    return headers;
  }

  public Map<String, String[]> getParameters() {
    return parameters;
  }

  public String getHeader(String name) {
    return headers.get(name);
  }

  public Request setBody(String payload) {
    try {
      this.body.putAll(new ObjectMapper().readValue(payload, new TypeReference<Map<String, Object>>() {
      }));
      return this;
    } catch (JsonProcessingException ex) {
      throw new MessageException(ex);
    }
  }

  public Request setMethod(String name) {
    this.method = name;
    return this;
  }

  public Request setResource(String name) {
    this.resource = name;
    return this;
  }

  public Request setHeaders(Map<String, String> headers) {
    this.headers.putAll(headers);
    return this;
  }

  public Request setParameters(Map<String, String[]> parameters) {
    this.parameters.putAll(parameters);
    return this;
  }
}
public class Response {

  private String code;
  private String data;
  private String messageId;
  private String timestamp;
  private String description;

  public Response() {
  }

  public String getCode() {
    return Objects.toString(code, "");
  }

  public String getData() {
    return Objects.toString(data, "");
  }

  public String getMessageId() {
    return Objects.toString(messageId, "");
  }

  public String getTimestamp() {
    return Objects.toString(timestamp, "");
  }

  public String getDescription() {
    return Objects.toString(description, "");
  }

  public Response setCode(String code) {
    this.code = code;
    return this;
  }

  public Response setData(String data) {
    this.data = data;
    return this;
  }

  public Response setMessageId(String messageId) {
    this.messageId = messageId;
    return this;
  }

  public Response setTimestamp(String timestamp) {
    this.timestamp = timestamp;
    return this;
  }

  public Response setDescription(String description) {
    this.description = description;
    return this;
  }
}
{
    "request": {
        "headers": {},
        "method": "",
        "resource": "",
        "body": {
            "whatsapp": {
                "conversationId": "39f09c41-1bd3-4e81-b829-babed3747d4b",
                "name": "Dave",
                "source": "+123456789098"
            },
            "payment": {
                "product": "chocolate",
                "amount": 1,
                "method": "cashapp",
                "msisdn": "123456789098",
                "entity": "The Fudge Shop"
            }
        },
        "parameters": {}
    },
    "data": {
        "sets": {
            "whatsapp": {
                "provider": "clickatell",
                "name": "Dave",
                "destination": "123456789098",
                "source": "123456789098",
                "message": "Your payment of $1.00 received, your receipt.no is QWJ124XPA9."
            },
            "cashapp": {
                "amount": 1,
                "receiptNo": "QWJ124XPA9",
                "name": "Dave Chapelle",
                "msisdn": "123456789098"
            }
        }
    },
    "response": {
        "code": "202",
        "data": "",
        "messageId": "20210623160202a647d32ee9ae477f9c90d8b1fbfd763a",
        "description": "Processing Request",
        "timestamp": "2021-06-23 16:02:02.408"
    }
}
Message output = new ObjectMapper().readValue(json.toString(), Message.class);
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token

当试图反序列化映射 正文时,该错误似乎是从请求类生成的:

我怎样才能正确地反序列化地图?

共有1个答案

凌昕
2023-03-14

对我来说有效的解决方案是使用自定义反序列化@jsonDeserialize注释&jsonDeserializer接口,以实现预期的结果。

以下是解决方案:

public class Request {

  private String method;
  private String resource;
  @JsonDeserialize(using = BodyDeserializer.class)
  private final Map<String, Object> body;
  private final Map<String, String> headers;
  private final Map<String, String[]> parameters;

  public Request() {
    this.body = new HashMap();
    this.headers = new HashMap();
    this.parameters = new HashMap();
  }

  public String getMethod() {
    return method;
  }

  public String getResource() {
    return resource;
  }

  public Map<String, Object> getBody() {
    return body;
  }

  public Map<String, String> getHeaders() {
    return headers;
  }

  public Map<String, String[]> getParameters() {
    return parameters;
  }

  public String getHeader(String name) {
    return headers.get(name);
  }

  public Request setBody(Map<String, Object> body) {
    this.body.putAll(body);
    return this;
  }

  public Request setMethod(String name) {
    this.method = name;
    return this;
  }

  public Request setResource(String name) {
    this.resource = name;
    return this;
  }

  public Request setHeaders(Map<String, String> headers) {
    this.headers.putAll(headers);
    return this;
  }

  public Request setParameters(Map<String, String[]> parameters) {
    this.parameters.putAll(parameters);
    return this;
  }

  private static class BodyDeserializer extends JsonDeserializer<Map<String, Object>> {

    @Override
    public Map<String, Object> deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
      JsonDeserializer<Object> deserializer = dc.findRootValueDeserializer(dc.constructType(Map.class));
      Map<String, Object> map = (Map<String, Object>) deserializer.deserialize(jp, dc);
      return map;
    }
  }
}
 类似资料:
  • 我对Jackson有一个错误的理解,就是将json文件反序列化为poco。这是我的代码: 我的POCO命名为AnimalBean: }还有我的JSON文件: } 当我执行我的代码时,我有以下错误:未识别的字段“动物园”(类动画豆),未标记为可忽略的。我知道问题是我的json文件开始不直接由动物,但我不能改变它,因为它不是我的。我已经尝试把对象apper.configure(Deseriazatio

  • 可以序列化/反序列化< code >映射吗 在这种特殊情况下,我知道总是,和 - 第三方类(我有序列化器和反序列化器),其他值是盒装原语。 有可能和杰克逊做这样的事吗?使用MapSerializer/MapDeserializer可以做到这一点吗?(我找不到任何例子)

  • 根据这里描述的内容,我应该使用JSR-310表示而不是数字表示来序列化对象。但是,我得到了数字表示。可能有什么问题? 我是这样配置我正在使用的映射器的: 这是我得到的反序列化示例 对于以下事例类:

  • 问题内容: 我一直在尝试将对象序列化为CSV,但是该对象包含,并且不能在对象上使用。 预期样本输出 : 实际输出 : 这是我的代码 :(其中大多数是2个POJO) 我尝试的一切似乎都没有任何效果,但找不到有效的解决方案。 抱歉,我无缘无故留下的毫无意义的注释,如果您回答了代码,请随时删除它们。 问题答案: 从错误中,我想相信这与您的模式有关,该模式的列取自on 而不是值。 您可能想在其中添加,但是

  • 我需要一个自定义反序列化器来在复杂的POJO中转换字符串。反序列化工作直到使用反序列化器:特别是使用自定义反序列化器时,我的对象的非对象属性不会序列化。 我有一个restful Web服务,它有一个pojo作为参数。 所以我的类PreentivoWs需要一个方法。这里是类定义: 在jsonObject中,我有一个枚举定义为 但此对象需要转换反序列化程序: 并在财产上标注: fromString方法