【问题标题】:Java class implementation for JSON serialized using Jackson使用 Jackson 序列化的 JSON 的 Java 类实现
【发布时间】:2020-04-16 15:49:37
【问题描述】:

我正在尝试在 Java 应用程序中实现 Microsoft Teams API 的一部分,并且在使用 Jackson 库将 Java 对象序列化为 JSON 时,我正在寻找有关正确 Java 类结构和体系结构的建议。目标是在某些阶段完成后向 Teams 频道发送消息。

我有一个测试类,它可以序列化为我想要的确切 JSON,但基于我见过的其他实现,下面的代码感觉它的结构不正确且不灵活。

我希望得到的 JSON 结构如下:

{
  "@context": "http://schema.org/extensions",
  "@type": "MessageCard",
  "correlationId": "104443c6-7acc-11ea-bc55-0242ac130003",
  "summary": "test.complete",
  "themeColor": "0076D7",
  "sections": [
    {
      "activityTitle": "Test Notification"
    },
    {
      "title": "Execution Status",
      "facts": [
        {
          "name": "Build Number",
          "value": "1"
        },
        {
          "name": "Description",
          "value": "Test Pipeline Description"
        },
        {
          "name": "Execution Name",
          "value": "Test Pipeline Name"
        },
        {
          "name": "Stage Name",
          "Value": "Deploy"
        },
        {
          "name": "Status",
          "value": "complete"
        },
        {
          "name": "Summary",
          "value": "pipeline has completed successfully"
        }
      ]
    }
  ],
  "potentialAction": [
    {
      "@context": "http://schema.org",
      "@type": "ViewAction",
      "name": "View Execution",
      "target": [
        "https://testdomain.com"
      ]
    }
  ]
}

我的测试 Java 类如下:

import java.util.*;
import com.fasterxml.jackson.annotation.*;

public class JacksonSerializerTest {
  private static String ACTIVITY_TITLE = "Test Notifications";
  private static String FACTS_TITLE = "Execution Status";

  @JsonProperty("@context")
  public String context = "http://schema.org/extensions";

  @JsonProperty("@type")
  public String type = "MessageCard";

  public String correlationId;
  public String summary;
  public String themeColor;

  private transient HashMap<String, Object> metadata;

  public JacksonSerializerTest(HashMap<String, Object> metadata) {
    this.correlationId = this.createRandomUUID();
    this.summary = "test.complete";
    this.themeColor = "0076D7";

    this.metadata = metadata;
  }

  public List<HashMap> getSections() {
    List<HashMap> sections = new ArrayList<>();
    HashMap<String, Object> activityTitle = this.getSection("activityTitle", ACTIVITY_TITLE);

    sections.add(activityTitle);
    sections.add((HashMap)this.getFacts());

    return sections;
  }

  public HashMap<String, Object> getSection(String name, Object obj) {
    HashMap<String, Object> section = new HashMap<>();

    section.put(name, obj);

    return section;
  }

  private HashMap<String, Object> getFacts() {
    HashMap<String, Object> facts = new HashMap<>();
    List<HashMap> factsList = new ArrayList<>();

    factsList.add((HashMap)this.getFact("Build Number", (String)metadata.get("buildNumber")));
    factsList.add((HashMap)this.getFact("Description", (String)metadata.get("description")));
    factsList.add((HashMap)this.getFact("Execution Name", (String)metadata.get("executionName")));
    factsList.add((HashMap)this.getFact("Stage Name", (String)metadata.get("eventName")));
    factsList.add((HashMap)this.getFact("Status", (String)metadata.get("executionStatus")));
    factsList.add((HashMap)this.getFact("Summary", (String)metadata.get("executionSummary")));

    facts.put("title", FACTS_TITLE);
    facts.put("facts", factsList);

    return facts;
  }

  public HashMap<String, String> getFact(String name, String value) {
    HashMap<String, String> fact = new HashMap<>();

    fact.put("name", name);
    fact.put("value", value);

    return fact;
  }

  public List<HashMap> getPotentialAction() {
    List<HashMap> potentialAction = new ArrayList<>();
    HashMap<String, Object> action = new HashMap<>();
    ArrayList<String> targets = new ArrayList<>();

    targets.add((String)metadata.get("executionUrl"));

    action.put("@context", "http://schema.org");
    action.put("@type", "ViewAction");
    action.put("name", "View Execution");
    action.put("target", targets);

    potentialAction.add(action);

    return potentialAction;
  }

  private static String createRandomUUID() {
    return UUID.randomUUID().toString();
  }
}

根据我一直在阅读的内容,看起来我应该对部分和潜在操作元素使用嵌套类,但我一直在努力解决如何实现嵌套类以输出包含这些数组中不同哈希的数组.

到目前为止,我并不打算实现整个 API,而是希望获得一个特定的消息卡结构,如上面的 JSON 所示。不过,我们可能希望在以后添加其他功能或使用不同的消息类型。

如果我们确实需要添加基于 Teams API 的其他元素,如何改进这个类以及如何构造这个 Java 对象以使其更加灵活?

【问题讨论】:

    标签: java json serialization jackson microsoft-teams


    【解决方案1】:

    您可以从为 PotentialAction 和 Sections 创建单独的类开始。这是为了确保关注点分离。类似的东西:

    class PotentialAction { 
      private List<HashMap> potentialAction;
      //all business logic to generate Potential Action goes in this class
    }
    
    class Sections {
     private List<HashMap> sections;
     //all business logic to generate Sections goes in this class
    }
    

    然后你创建一个抽象类,它具有每个 api 的最低要求(如元数据)

    abstract class APICommon {
     //compulsory attributes required by all api's
     private String accessToken;
    }
    

    现在定义 API 特定的类来扩展该抽象类

    class API1 extends APICommon {
     // all the api specific attributes
      public String correlationId;
      public String summary;
      public String themeColor;
      private PotentialAction potentialAction;
      private Sections sections;
    }
    

    优点:

    1. 通过将潜在的动作和部分分成不同的类,现在将用于生成 JSON 不同部分的业务逻辑分开,这不仅使代码更干净,而且可以为不同的 api 重用。

      李>
    2. 如果您有其他要求并且需要支持新的 API,您只需从我们的抽象类 APICommon 扩展另一个类即可。这可以确保早期的实现不受影响,并使您的设计具有可扩展性。

    希望这会有所帮助:)

    【讨论】:

      猜你喜欢
      • 2020-07-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-08
      • 2023-03-04
      • 2018-07-14
      相关资源
      最近更新 更多