使用泛型进行反序列化的重构方法

2023-12-14

这是我要重构的方法:

public static List<ComponentPOCO> parseJsonComponentFromString(String fileContents){

        try {
            ObjectMapper mapper = new ObjectMapper()
                    .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
                    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            List<ComponentPOCO> component = mapper.readValue(fileContents, new TypeReference<List<ComponentPOCO>>() {});
            return component;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

我正在尝试重构我的反序列化方法以使用泛型来反序列化任何类型。对于不在集合中的对象,我可以很好地做到这一点,如下所示:

public static <T> T parseProductData(String jsonData, Class<T> typeClass) throws IOException, IllegalAccessException {
    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    T inputMessage = objectMapper.readValue(jsonData, typeClass);
    return inputMessage;
}

这是我反序列化到的数据的示例ComponentPOCO class:

[
      {   "artifactPathOrUrl": "http://www.java2s.com/Code/JarDownload/sample/sample.jar.zip",
        "namespace": "exampleNamespace1",
        "name": "exampleName1",
        "tenant": "exampleTenant1"
      },

      {   
        "artifactPathOrUrl": "http://www.java2s.com/Code/JarDownload/sample-calculator/sample-calculator-bundle-2.0.jar.zip",
        "namespace": "exampleNamespace1",
        "name": "exampleName2",
        "tenant": "exampleTenant1"
      },
      {   
        "artifactPathOrUrl": "http://www.java2s.com/Code/JarDownload/helloworld/helloworld.jar.zip",
        "namespace": "exampleNamespace1",
        "name": "exampleName3",
        "tenant": "exampleTenant1"
      },
      {   
        "artifactPathOrUrl": "http://www.java2s.com/Code/JarDownload/fabric-activemq/fabric-activemq-demo-7.0.2.fuse-097.jar.zip",
        "namespace": "exampleNamespace1",
        "name": "exampleName4",
        "tenant": "exampleTenant1"
      }
]

以下是 ComponentPOCO 类型的代码:

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.*;
import lombok.experimental.Accessors;
import org.apache.pulsar.common.io.SinkConfig;
import org.apache.pulsar.common.io.SourceConfig;

import java.util.List;
import java.util.Map;

@Setter
@Getter
@EqualsAndHashCode
@ToString
@Accessors(chain = true)
@Data
public class ComponentPOCO {
    @JsonProperty
    private String namespace;
    @JsonProperty
    private String tenant;
    @JsonProperty
    private String name;
    @JsonProperty
    private String type;
    @JsonProperty
    private String destinationTopicName;
    @JsonProperty
    private String artifactPathOrUrl;
    @JsonProperty
    private String className;
    @JsonProperty
    private List<String> inputs;
    @JsonProperty
    private String output;
    @JsonProperty
    private Map<String, Object> userConfig;
    @JsonProperty
    private String logTopic;
    @JsonProperty
    private Map<String, Object> configs;
    @JsonProperty
    private Integer parallelism;
    @JsonProperty
    public String sinkType;
    @JsonProperty
    private String sourceType;
    @JsonProperty
    public String runtimeFlags;
}

有没有办法让我能够使用这样的泛型反序列化整个列表?


您可以提取所有类型的交互Jackson额外上课并隐藏所有困难。ObjectMapper可以创建和配置一次。对于单个对象,您可以使用readValue(String content, Class<T> valueType)方法和收集你需要建立类型参考并使用readValue(String content, TypeReference valueTypeRef)方法。简单的实现如下所示:

class JsonMapper {

  private final ObjectMapper mapper = new ObjectMapper();

  public JsonMapper() {
    // configure mapper instance if required
    mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    // etc...
  }

  public String serialise(Object value) {
    try {
      return mapper.writeValueAsString(value);
    } catch (JsonProcessingException e) {
      throw new IllegalStateException("Could not generate JSON!", e);
    }
  }

  public <T> T deserialise(String payload, Class<T> expectedClass) {
    Objects.requireNonNull(payload);
    Objects.requireNonNull(expectedClass);

    try {
      return mapper.readValue(payload, expectedClass);
    } catch (IOException e) {
      throw new IllegalStateException("JSON is not valid!", e);
    }
  }

  public <T> List<T> deserialiseList(String payload, Class<T> expectedClass) {
    Objects.requireNonNull(payload);
    Objects.requireNonNull(expectedClass);

    try {
      return mapper.readValue(payload, constructListTypeOf(expectedClass));
    } catch (IOException e) {
      throw new IllegalStateException("JSON is not valid!", e);
    }
  }

  private <T> CollectionType constructListTypeOf(Class<T> expectedClass) {
    return mapper.getTypeFactory().constructCollectionType(List.class, expectedClass);
  }
}

及用法:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

public class JsonApp {

  public static void main(String[] args) {
    JsonMapper mapper = new JsonMapper();
    System.out.println(mapper.deserialise("{\"id\":1233}", A.class));
    System.out.println(mapper.deserialiseList("[{\"id\":4567}]", A.class));
  }
}

class A {
  private int id;

  public int getId() {
    return id;
  }

  public void setId(int id) {
    this.id = id;
  }

  @Override
  public String toString() {
    return "A{" + "id=" + id + '}';
  }
}

上面的代码打印:

A{id=1233}
[A{id=4567}]

也可以看看:

  • 如何在 Java 中参数化响应解析?
  • 使用 Jackson 反序列化或序列化任何类型的对象 ObjectMapper 和处理异常
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用泛型进行反序列化的重构方法 的相关文章

随机推荐

  • 如何为 Azure AD B2C 配置 SSO?

    As per Azure AD B2C 文档我们可以为 Azure AD B2C 应用程序配置 SSO 我们希望用户自行注册应用程序 从而选择 AD B2C 但是 在创建 B2C 租户帐户并配置所有策略之后 我无法找到配置 SSO 的选项
  • 这个构造是什么意思“__builtin_expect(!!(x), 1)”

    具体来说 我问的是双 在 built in 的参数中 按照 C 语言 它是双重否定吗 The 简直就是两个 操作员彼此相邻 这是将任何非零值转换为的简单方法1 并离开0按原样 又名 布尔化 值 看 c 运算符 是两个 NOT 吗 对于一般逻
  • 获取视图或控制器中的当前区域名称

    如何获取视图或控制器中的当前区域名称 有没有类似的东西ViewContext RouteData Values controller 对于地区 从MVC2开始你可以使用ViewContext RouteData DataTokens are
  • Rails 3.1,由于缺少局部部分变量而导致内存泄漏(Ruby 1.9.2-p290)

    如果我像这样渲染部分 渲染 部分 gt event news item 对象 gt 事件 变量 gt true 然后参考variable在部分中触发了内存泄漏 Rails 似乎进入了递归 然后 我必须在内存使用量失控之前快速重新启动服务器
  • 如何获取亚马逊S3上文件的md5sum

    如果我在 Amazon S3 上有现有文件 那么无需下载文件即可获取其 md5sum 的最简单方法是什么 AWS 的文档ETag 截至 2023 年 11 月 17 日 说 实体标签 ETag 代表对象的特定版本 ETag 仅反映对象内容的
  • 使用 MinGW/MSYS 编译 freetype2 时出现问题

    用MinGW和MSYS编译freetype2好像有问题 我对 freetype 源代码的干净副本以及纯粹的 MinGW 和 MSYS 的尝试给出了 Andrew MCARDLE PC documents code cd freetype 2
  • 创建单独变量字典的更简单方法?

    我希望能够以字符串形式获取变量的名称 但我不知道 Python 是否具有那么多的自省功能 就像是 gt gt gt print my var name my var 我想这样做 因为我有一堆变量 我想把它们变成字典 例如 bar True
  • 无法调用分页dojo增强网格上的函数

    我尝试了所有可能的方法 但它不起作用 当我移动到 dojo dataGrid 中的另一个页面 分页期间 时 我想调用一个函数 我尝试了下面的代码 但它不起作用 方法一 nextPage function src alert going gr
  • 在loopback.io中进行连接查询

    我正在尝试使用 Loopback io 构建一个简单的应用程序作为我的学习过程 我已经设置了项目 创建的模型和 API 工作正常 现在我正在尝试创建一个自定义 api 它可以通过进行联接查询从两个不同的模型获取数据 所以我有两个模型 sto
  • axios post 请求成功后刷新表

    这是我来自 axios 的示例请求响应 var data id 1 name john username john doe birthdate 1999 05 21 age 20 email email protected id 2 nam
  • 将多个 hdf5 文件合并到一个 pytable 中

    我有一些hdf5文件 每个文件都具有相同的结构 我想创建一个pytable通过某种方式合并它们hdf5 files 我的意思是 如果 file1 中的数组的大小为 x 而 file2 中的数组的大小为 y 则结果数组pytable大小为 x
  • 我可以将 CSS 应用于 swing 文本组件吗?

    许多 swing 文本组件将解释 HTML 如果可能的话 我想使用 CSS 来设置 HTML 的样式 有人知道怎么做吗 The Jaxx框架允许您执行此操作
  • 从音频输入捕获原始音频以在 Mac 上进行实时处理的最简单方法

    从内置音频输入捕获音频并能够在请求时实时读取原始采样值 如 wav 中 的最简单方法是什么 就像从套接字读取一样 希望代码使用 Apple 的框架之一 音频队列 文档不是很清楚 我需要的是非常基础的 为此尝试使用 AudioQueue 框架
  • Google API 上未捕获异常“InvalidArgumentException”,带有消息“

    我已复制此网站上他们的文档中的代码 here 我已经更改了下面这些的 JSON 我已经在 Composer 上的 API 上生成了新文件 但仍然遇到一些问题 我不确定我做错了什么 这是否意味着他们的 API 漏洞太多 这是演示链接 demo
  • 使用嵌套视图时 Prism 7 抛出异常

    几个月前我发布了类似的问题使用 Prism 和 IsNavigationTarget 处理嵌套视图 可能返回 false 我仍然不确定正确的方法是什么 假设你有一个视图A 在这个视图A中你声明了一个区域A 然后你在这个区域A中注入了一个视图
  • 如何在窗口外触摸时取消 Activity 等主题的对话框?

    我有一个带有对话框主题的活动 当有人触摸此活动窗口之外的任何位置的屏幕时 我想关闭 完成 此活动 我怎样才能做到这一点 只是要指出的是is一种从以对话框为主题的活动中获得类似对话框的 触摸外部取消 行为的方法 尽管我还没有完全调查它是否有不
  • 正则表达式在多个多行字符串中查找列表值python

    我正在寻找一些帮助 以在具有多行但相似模式的字符串中搜索列表条件 每个子查询都有as and so as space and space 图案 我想搜索每个模式中的子标准并生成输出 sub apple apple event pear st
  • python、selenium 中切换帧的函数

    我正在寻找一个可以更轻松地在两个框架之间切换的功能 现在 每次我需要在帧之间切换时 我都会通过以下代码来完成此操作 driver switch to frame driver find element by css selector fra
  • Protovis 是否应该像 RaphaelJS 一样在 IE 7、8 和 9 上工作?

    我想Protovis可能在 IE 7 和 8 上工作 或者至少在 IE 9 上工作 但令我惊讶的是 我在所有 3 个浏览器上都尝试过它 但它在任何一个上都不起作用 对于那些示例页面 这是一个临时的 JS bug 它应该在 IE 上工作吗 比
  • 使用泛型进行反序列化的重构方法

    这是我要重构的方法 public static List