java - 从 RestTemplate 将 JSON 反序列化为枚举
问题描述
尝试使用 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 +
'}';
}
}
这是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
. 但是,反序列化为 Java 对象的所有visibility
3 封电子邮件都具有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
解决方案
我在https://api.myjson.com/bins/1h6ngn托管了一个示例 json
并使用相同的类,它运行良好。
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);
验证您是否在 json 中获得“可见性”节点。
推荐阅读
- java - 为具有多个关系的表创建 Hibernate 条件查询
- c# - 用C#修改xml文件
- php - 如何使用 Codeigniter 中的 id 从 ajax 获取所有记录结果
- django - 新创建的 Django 项目不会生成迁移
- git - Git孤儿删除历史
- r - 用 ggplot2 躲避哑铃图
- data-visualization - 在 Amazon QuickSight 中生成折线图,根据最终用户的需求比较 2 周或 2 个月或 2 年的数据
- search - 如何在 hugo dot 主题中实现搜索框?
- python - 如何保存用 CNN 正确分类的图像?
- java - Java - Recycleview viewholder.category_name.settext 不起作用