Десериализация JSON для перечисления из RestTemplate - PullRequest
0 голосов
/ 01 мая 2018

Попытка использовать вызов REST GitHub API для списка адресов электронной почты пользователя со следующими 2 классами:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.Objects;

/**
 * {@link GitHubEmail} class represents a description of an email address (and additional info about
 * that email address) as GitHub API stores it.
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class GitHubEmail {

  /**
   * Email address.
   */
  private String email;

  /**
   * Primary flag; denotes if the email address is primary one user uses. This is the one to email
   * to with the most confidence.
   */
  private boolean primary;

  /**
   * Flag that denotes if the email address has been verified by the user process.
   */
  private boolean verified;

  /**
   * If the email address is visible to the public, private, or no info (i.e., null)
   */
  private GitHubEmailVisibility visiblity;

  public String getEmail() {
    return email;
  }

  public void setEmail(String email) {
    this.email = email;
  }

  public boolean isPrimary() {
    return primary;
  }

  public void setPrimary(boolean primary) {
    this.primary = primary;
  }

  public boolean isVerified() {
    return verified;
  }

  public void setVerified(boolean verified) {
    this.verified = verified;
  }

  public GitHubEmailVisibility getVisiblity() {
    return visiblity;
  }

  public void setVisiblity(GitHubEmailVisibility visiblity) {
    this.visiblity = visiblity;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    GitHubEmail that = (GitHubEmail) o;
    return primary == that.primary &&
        verified == that.verified &&
        Objects.equals(email, that.email) &&
        visiblity == that.visiblity;
  }

  @Override
  public int hashCode() {

    return Objects.hash(email, primary, verified, visiblity);
  }

  @Override
  public String toString() {
    return "GitHubEmail{" +
        "email='" + email + '\'' +
        ", primary=" + primary +
        ", verified=" + verified +
        ", visiblity=" + visiblity +
        '}';
  }
}

А это GitHubEmailVisibility.java:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

/**
 * GitHub email visibility options.
 */
public enum GitHubEmailVisibility {

  PRIVATE,

  PUBLIC;

  @JsonValue
  public String toJson() {
    return name().toLowerCase();
  }

  @JsonCreator
  public static GitHubEmailVisibility fromValue(String value) {
    System.out.println("Is this ever even called?");
    if ("private".equalsIgnoreCase(value)) {
      return PRIVATE;
    } else if ("public".equalsIgnoreCase(value)) {
      return PUBLIC;
    }

    return null;
  }
}

Используя Spring RestTemplate, я звоню:

GitHubEmail[] gitHubEmails = rest.getForObject("https://api.github.com/user/emails?access_token={oAuthToken}&type=all&per_page=1000&page=1",
        GitHubEmail[].class, oAuthToken);
    Arrays.stream(gitHubEmails).forEach(gitHubEmail -> logger.info("GitHub email: " + gitHubEmail));

Однако visibility всегда возвращается как null, хотя в строке полезной нагрузки явно есть значения по крайней мере для одного из электронных писем в массиве, который возвращается.

Кроме того, я вижу, что мой оператор System.out.print в методе с @JsonCreator никогда не вызывается.

Вот вывод следующих строк вместе (первая, сериализация ответа в виде простой строки, просто чтобы убедиться, что visibility иногда возвращается):

String emails = rest.getForObject("https://api.github.com/user/emails?access_token={oAuthToken}&type=all&per_page=1000&page=1",
        String.class, oAuthToken);
logger.info("emails consumed as a string: " + emails);

GitHubEmail[] gitHubEmails = rest.getForObject("https://api.github.com/user/emails?access_token={oAuthToken}&type=all&per_page=1000&page=1",
        GitHubEmail[].class, oAuthToken);
Arrays.stream(gitHubEmails).forEach(gitHubEmail -> logger.info("GitHub email: " + gitHubEmail));

Вот журналы сервера для этих двух наборов операторов. Как видите, строковая версия имеет первое из 3-х писем, перечисленных с visibility: private. Однако все 3 электронных писем, десериализованных в объекты Java, имеют visibility как null:

2018-05-01 21:42:51.477  INFO 5828 --- [nio-8080-exec-6] j.p.w.controller.LoginSuccessController  : emails consumed as a string: [{"email":"...","primary":true,"verified":true,"visibility":"private"},{"email":"...","primary":false,"verified":true,"visibility":null},{"email":"...","primary":false,"verified":true,"visibility":null}]
2018-05-01 21:42:51.524  INFO 5828 --- [nio-8080-exec-6] j.p.w.controller.LoginSuccessController  : GitHub email: GitHubEmail{email='...', primary=true, verified=true, visiblity=null}
2018-05-01 21:42:51.524  INFO 5828 --- [nio-8080-exec-6] j.p.w.controller.LoginSuccessController  : GitHub email: GitHubEmail{email='...', primary=false, verified=true, visiblity=null}
2018-05-01 21:42:51.524  INFO 5828 --- [nio-8080-exec-6] j.p.w.controller.LoginSuccessController  : GitHub email: GitHubEmail{email='...', primary=false, verified=true, visiblity=null}

Как мне получить его для десериализации в эту модель Java POJO?

Я использую Spring Boot 2.0 и похоже, что это зависит от Jackson 2.9.4

1 Ответ

0 голосов
/ 01 мая 2018

Я принимал образец JSON на https://api.myjson.com/bins/1h6ngn

И использовал те же классы, он отлично работает.

    public static void main(String[] args) throws JsonProcessingException {

    RestTemplate rest = new RestTemplate();
    GitHubEmail[] gitHubEmails = rest.getForObject("https://api.myjson.com/bins/1h6ngn", GitHubEmail[].class);
    Arrays.stream(gitHubEmails)
        .forEach(gitHubEmail -> System.out.println(("GitHub email: " + gitHubEmail)));
}

выход

Is this ever even called?
Is this ever even called?
GitHub email: GitHubEmail{email='hemantsonu20@gmail.com', primary=false, verified=true, visiblity=PRIVATE}
GitHub email: GitHubEmail{email='another@gmail.com', primary=true, verified=false, visiblity=PUBLIC}

Просто поменяй свой покой на звонок

String gitHubEmails = rest.getForObject("https://api.github.com/user/emails?access_token={oAuthToken}&type=all&per_page=1000&page=1",
        String.class, oAuthToken);
System.out.println(gitHubEmails);

Проверьте, получаете ли вы "visiblity" узел в json или нет.

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