You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RestTemplate JSON反序列化为枚举及GitHub API用户邮箱列表调用问题

1. 如何通过RestTemplate将JSON数据反序列化为枚举类型?

RestTemplate默认依赖Jackson处理JSON序列化/反序列化,所以搞定枚举反序列化本质就是配置Jackson对枚举的映射规则,分两种常见场景处理:

  • 场景1:JSON值和枚举名称完全匹配
    这种情况完全不用额外配置,Jackson会自动对应枚举名称。比如你定义了这样的枚举:

    public enum UserStatus {
        ACTIVE, INACTIVE, SUSPENDED
    }
    

    如果接口返回的JSON是{"status": "ACTIVE"},RestTemplate会直接把它转成UserStatus.ACTIVE,非常省心。

  • 场景2:JSON值和枚举名称不匹配(比如用自定义编码)
    这时候需要用Jackson的@JsonValue和@JsonCreator注解手动指定映射逻辑。举个例子:

    public enum UserStatus {
        ACTIVE("A"),
        INACTIVE("I"),
        SUSPENDED("S");
    
        private final String code;
    
        UserStatus(String code) {
            this.code = code;
        }
    
        @JsonValue // 序列化时输出这个code值
        public String getCode() {
            return code;
        }
    
        @JsonCreator // 反序列化时根据code找到对应枚举实例
        public static UserStatus fromCode(String code) {
            for (UserStatus status : values()) {
                if (status.code.equals(code)) {
                    return status;
                }
            }
            throw new IllegalArgumentException("无效的状态码: " + code);
        }
    }
    

    这样当JSON返回{"status": "A"}时,RestTemplate就能准确转成UserStatus.ACTIVE了。

另外,如果你的RestTemplate是自定义配置的,要确保Jackson消息转换器已经注册,否则上面的配置可能不生效:

RestTemplate restTemplate = new RestTemplate();
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(new ObjectMapper());
restTemplate.getMessageConverters().add(converter);

2. 调用GitHub API获取用户邮箱列表,解决调用与序列化问题

先看你给出的GitHubEmail类,已经加了@JsonIgnoreProperties(ignoreUnknown = true),这个做得很对——GitHub API返回的邮箱数据会包含一些我们没定义的字段,这个注解能让Jackson忽略那些未知字段,避免反序列化报错。

我先把这个类补全(原代码未完成,且Jackson反序列化需要无参构造器和getter/setter):

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

/**
 * {@link GitHubEmail}类表示GitHub API存储的邮箱地址(及相关附加信息)的描述。
 */
@JsonIgnoreProperties(ignoreUnknown = true)
public class GitHubEmail {
    /**
     * 邮箱地址。
     */
    private String email;
    /**
     * 主邮箱标识;表示该邮箱是否为用户的主邮箱
     */
    private boolean primary;
    /**
     * 邮箱是否已验证
     */
    private boolean verified;
    /**
     * 邮箱的可见性状态,比如"public"或"private"
     */
    private String visibility;

    // Jackson反序列化必须要有无参构造器
    public GitHubEmail() {}

    public GitHubEmail(String email, boolean primary, boolean verified, String visibility) {
        this.email = email;
        this.primary = primary;
        this.verified = verified;
        this.visibility = visibility;
    }

    // Getter和Setter方法
    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 String getVisibility() { return visibility; }
    public void setVisibility(String visibility) { this.visibility = visibility; }

    // 重写equals、hashCode和toString方便调试
    @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) && Objects.equals(visibility, that.visibility);
    }

    @Override
    public int hashCode() {
        return Objects.hash(email, primary, verified, visibility);
    }

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

接下来是调用GitHub API的代码,注意获取用户邮箱需要授权(属于用户私有数据),得用个人访问令牌(PAT),且令牌要勾选user:email权限:

import org.springframework.web.client.RestTemplate;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import java.util.List;

public class GitHubEmailClient {
    public static void main(String[] args) {
        // 替换成你自己的GitHub个人访问令牌
        String githubToken = "your-personal-access-token";

        RestTemplate restTemplate = new RestTemplate();

        // 设置请求头,添加Bearer授权
        HttpHeaders headers = new HttpHeaders();
        headers.setBearerAuth(githubToken);
        HttpEntity<Void> requestEntity = new HttpEntity<>(headers);

        // 调用GitHub API,注意要用ParameterizedTypeReference处理泛型列表
        String apiUrl = "https://api.github.com/user/emails";
        try {
            List<GitHubEmail> emailList = restTemplate.exchange(
                    apiUrl,
                    HttpMethod.GET,
                    requestEntity,
                    new ParameterizedTypeReference<List<GitHubEmail>>() {}
            ).getBody();

            // 打印获取到的邮箱列表
            if (emailList != null) {
                emailList.forEach(System.out::println);
            }
        } catch (Exception e) {
            System.err.println("调用API出错了: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

这里有几个关键注意点:

  • 授权令牌:一定要确保你的令牌有user:email权限,否则会返回403禁止访问。
  • 泛型反序列化:因为返回的是List<GitHubEmail>,不能直接用List.class作为响应类型(否则Jackson会把每个元素转成LinkedHashMap),必须用ParameterizedTypeReference指定具体泛型类型。
  • 异常处理:实际项目里要处理网络错误、API返回的错误码(比如401、404)等情况,上面的try-catch是最基础的处理方式。

内容的提问来源于stack exchange,提问作者user1902183

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:10:52