当前位置: 首页 > 面试题库 >

在一个字段中反序列化具有多种类型的JSON

郎增
2023-03-14
问题内容

我想反序列化JSON(使用Jackson 1.9.11和RestTemplate 1.0.1),其中一个字段可能具有更多类型含义,例如:

    {"responseId":123,"response":"error"}

要么

    {"responseId":123,"response":{"foo":"bar", ... }}

一个或另一种情况对于一个特定类型的设置器(String od custom
Response类)都可以正常工作,但是当我将实体bean重写的设置器放入能够处理这两种情况时,将引发异常:

Caused by: org.springframework.web.client.RestClientException: Could not extract response: no suitable HttpMessageConverter found for response type [xxxx.templates.ExportResponse] and content type [application/json;charset=utf-8]

我当时在考虑三种解决方案,但没有任何一种可行:

  • 仅使用String setter并在内部使用ObjectMapper解组该字符串(如果它不等于“错误”),但是当该JS Array出现时,它不是字符串,因此不使用String setter :(。
  • 使用具有自己的JsonDeserializer扩展名的多态类型处理(@JsonTypeInfo批注)-我仍在尝试理解并实现。
  • 创建HttpMessageConverter列表并将其放入所有消息转换器中,我可以使用。但我认为此步骤是不必要的,因为仅使用了MappingJacksonHttpMessageConverter,对吗?

实体Bean中的二传手:

@JsonDeserialize(using = ResponseDeserializer.class)
public void setResponse(Object responseObject) {
    if(responseObject instanceof Response)
        response = (Response) responseObject;
}

ResponseDeserializer中的反序列化方法:

public Response deserialize(JsonParser parser, DeserializationContext context) throws IOException, JsonProcessingException {
    Response response = new Response();

    if(JsonToken.START_OBJECT.equals(parser.getCurrentToken())) {
        ObjectMapper mapper = new ObjectMapper();
        response = mapper.readValue(parser, Response.class);
    } else
        throw new JsonMappingException("Unexpected token received.");

    return response;
}

问题答案:

实现此目标的唯一方法是使用自定义解串器。

这是一个例子:

ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule = new SimpleModule("MyModule", new Version(1, 0, 0, null));
testModule.addDeserializer(Response.class, new ResponseJsonDeserializer());
mapper.registerModule(testModule);

这是如何编写(至少我应该如何编写)反序列化器的方法:

class ResponseJsonDeserializer extends JsonDeserializer<Response>  {
  @Override
  public Responsedeserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    Response response = new Response();
    if(jp.getCurrentToken() == JsonToken.VALUE_STRING) {
        response.setError(jp.getText());
    } else {
       // Deserialize object
    }
    return response;
  }
}

class Response {
   private String error;
   private Object otherObject; // Use the real type of your object

   public boolean isError() {
      return error != null;
   }

   // Getters and setters

}


 类似资料:
  • 我目前正在努力反序列化JSON数据结构,如下所示: 示例1: 示例 2: 我必须处理许多此类结构的实例。它是规则生成器的输出。我无法更改JSON的格式,我必须使用我得到的东西。该结构是递归的,可以有多个级别。 我正在使用Jackson的ObjectMapper并构建一些内部类来映射数据。 大多数实例看起来像示例1,对于那些已经很好地工作的实例,但是有一些更复杂的实例,比如示例2,实际上比示例2更复

  • 这是保存过程开始的地方。我定义了一个抽象方法,以后在运行时已知的类中实现。 这里我知道的类型,我想调用一个方法。 所以问题是ConfigurationPersistenceHelper中的方法。运行此方法时,配置中得到的不是而是。 我知道我可以在每个具体应用程序类的方法中实现反序列化器逻辑。但这会导致大量重复代码。这是我目前的解决方案。 此外,我知道我可以将类型从(其中类型在运行时仍然可用)传递给

  • 问题内容: 我有一个叫做抽象类,然后两个是实现,和。我遇到的问题是,当我将a的其余端点调用到数据库中时,理想情况下,我希望它像将实例传递给REST端点的位置一样。如果不是用一个以上的实现来抽象,那就没问题了,但是由于我有2个,所以我得到了一个错误。 “问题:抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么被其他类型信息实例化” 在找到解决方案之后,我找到了一个SO答案,说我可以使用类

  • 问题内容: 假设我们有这样的结构: JSON: 和对应的POJO: 响应类 身体类 CatWrapper.class 类别 但是现在让我们说,我们具有相同的结构,但是我们得到的不是 我在上使用GSON(默认json解析器),在提供解决方案时请考虑一下。 我们可以在此处使用泛型,因此响应如下所示: 但是我们不能,因为字段名称是特定于类的。 题: 我如何做才能自动序列化它而不创建太多样板类?我并不真的

  • 问题内容: 我正在为项目使用Typescript,需要将集合序列化为json,将其保存到文件中,然后将该文件反序列化为类似的集合。该集合看起来像: 我的工具界面如下所示: 工具实现如下所示: 我有一些工具界面的实现:textTool,imageTool和rectangleTool。我需要解决的问题是,当我将文件内容反序列化为工具集合时,我只会得到一个常规对象,而不是例如textTool的实例。 我

  • 我从超文本传输协议Web服务收到以下JSON响应 现在我希望能够反序列化这个。我偶然发现了来自谷歌的Gson,它最初在一些小测试用例中运行良好,但我在反序列化上面的字符串时遇到了一些困难。 我正在阅读Gson用户指南,理想情况下,我希望有一个对象,它有两个属性:和,但是字段必须是对象的,这可能会让Gson感到困难。 然后我看了这个例子,它更接近我的问题,但我仍然不太明白。在这个例子中,整个响应是一