使用Jackson序列化的JSON的Java类实现

我正在尝试在Java应用程序中实现Microsoft Teams API的一部分,在使用Jackson库将Java对象序列化为JSON时,我希望得到一些关于正确的Java类结构和体系结构的建议。目标是在特定阶段完成时向团队频道发送消息。

我有一个测试类,它可以序列化到我想要的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();
  }
}

根据我所阅读的内容,看起来我应该为sections和PotalAction元素使用嵌套类,但我一直在努力解决如何实现嵌套类以输出在这些数组中包含不同散列的数组。

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

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


解决方案

您可以从为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上重复使用。

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

希望这会有帮助:)

相关文章