Реализация класса Java для JSON, сериализованная с использованием Джексона - PullRequest
0 голосов
/ 16 апреля 2020

Я пытаюсь реализовать часть API Microsoft Teams в приложении Java и ищу несколько советов о правильной структуре и архитектуре класса Java при использовании библиотеки Джексона для сериализации Java возражает против JSON. Цель состоит в том, чтобы отправить сообщение, когда определенные этапы завершены, в канал Команд.

У меня есть тестовый класс, который сериализуется с точностью до 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, но хочу получить конкретную c структуру карты сообщений, подобную той, что показана в JSON выше. Мы можем захотеть добавить дополнительные функции или иметь другие типы сообщений позднее.

Как можно улучшить этот класс и как должен быть структурирован этот объект Java, чтобы сделать его более гибким, если нам нужно добавить дополнительные элементы на основе API команд?

1 Ответ

0 голосов
/ 16 апреля 2020

Вы можете начать с создания отдельных классов для 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-классы c для расширения этого абстрактный класс

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. Разделив потенциальное действие и разделы на разные классы, бизнес-логика c для создания различных частей JSON теперь разделены, что не только делает код чистым, но и многократно используемым для различных API.

  2. Если у вас есть дополнительные требования и вам нужна поддержка новых API, вам нужно только продолжить. расширить другой класс из нашего абстрактного класса APICommon. Это гарантирует, что более ранние реализации остаются нетронутыми и делает ваш дизайн расширяемым.

Надеюсь, это поможет:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...