简体   繁体   English

从RestTemplate将JSON反序列化为枚举

[英]Deserialization of JSON to enum from RestTemplate

Trying to consume GitHub API REST call for a user's list of emails with the following 2 classes: 尝试使用GitHub API REST调用以下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 +
        '}';
  }
}

And this is the GitHubEmailVisibility.java : 这是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;
  }
}

Using Spring's RestTemplate, I make the call: 使用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));

However, the visibility always comes back as null even though the payload string clearly has values for at least one of the emails in the array that comes back. 但是,即使有效负载字符串明显具有返回数组中至少一封电子邮件的值, visibility总是返回为null

Also, I see that my System.out.print statement in the method with @JsonCreator never gets called. 另外,我看到我的@JsonCreator方法中的System.out.print语句从未被调用。

Here is the output of the following lines together (first one, serializing the response as simple string, just to verify that visibility does get returned sometimes): 这是以下各行的输出(第一行,将响应序列化为简单字符串,只是为了验证有时是否返回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));

Here is the server logs for those 2 sets of statements. 这是这两组语句的服务器日志。 As you can see, the string version has the first of 3 emails listed with visibility: private . 如您所见,字符串版本列出了3封电子邮件中的第一封邮件,并具有visibility: private However, all 3 emails deserialized into Java objects have visibility as null : 但是,反序列化为Java对象的所有 3封电子邮件的visibilitynull

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}

How do I get it to get deserialized into this Java POJO model? 如何获得反序列化到此Java POJO模型的信息?

I am using Spring Boot 2.0 and it looks like it depends on Jackson 2.9.4 我正在使用Spring Boot 2.0,它看起来取决于Jackson 2.9.4

I hosted a sample json at https://api.myjson.com/bins/1h6ngn 我在https://api.myjson.com/bins/1h6ngn托管了一个示例json

And used the same classes, it runs fine. 并使用相同的类,它运行良好。

    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)));
}

Output 产量

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}

Just change your rest call 只需更改您的休息电话

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);

Verify whether you are getting "visiblity" node in the json or not. 验证您是否在json中获得“可见性”节点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM