java - 在 Hashmap 中将 JsonAnySetter 和 JsonAnyGetter 与 ArrayList 一起使用

标签 java json jackson

所以我正在尝试使用 Jackson Annotations,并且我正在针对 Riot 的 API 发出请求。这是我得到的回复:http://jsonblob.com/568079c8e4b01190df45d254 。其中,summonerId (38584682) 之后的数组可以具有不同的长度。

每次的唯一召唤者ID也会不同。

我想将此响应映射到 DTO。

对于类似的情况,我正在执行不同的调用:

@JsonIgnore
protected Map<String, SingleSummonerBasicDTO> nonMappedAttributes;

@JsonAnyGetter
public Map<String, SingleSummonerBasicDTO> getNonMappedAttributes() {
    return nonMappedAttributes;
}

@JsonAnySetter
public void setNonMappedAttributes(String key, SingleSummonerBasicDTO value) {
    if (nonMappedAttributes == null) {
        nonMappedAttributes = new HashMap<String, SingleSummonerBasicDTO>();
    }
    if (key != null) {
        if (value != null) {
            nonMappedAttributes.put(key, value);
        } else {
            nonMappedAttributes.remove(key);
        }
    }
}

来自这里的答案。我的想法是为数组中的每个元素执行一个 for-each 循环,但我不知道如何在没有要循环的内容的情况下循环某些内容。

我完全不知道注释如何工作以及如何继续,如果有帮助,请帮忙!

最佳答案

首先,@JsonAnySetter 的目的是处理不同属性的情况,而不是不同长度的 json 数组。

Jackson 非常擅长在序列化和反序列化中使用 Java Collections 和 Maps。您只需告诉它集合的参数类型即可。

在您的例子中,我使用了 Map 来捕获根元素,使其成为唯一的键,并以 DTO 的 List 作为值。我使用 Jackson 的类型系统( TypeFactoryJavaType )来告诉 Jackson 所有泛型类型。

这是我使用过的DTO:

public class SingleSummonerBasicDTO
{
    public String name;
    public String tier;
    public String queue;
    public List<SingleSummonerBasicDTOEntry> entries;

    @Override
    public String toString() {
        String toString = "\nSingleSummonerBasicDTO: " + name + " " + tier + " " + queue;
        for (SingleSummonerBasicDTOEntry entry : entries) {
            toString += "\n" + entry.toString();
        }
        return toString;
    }

    public static class SingleSummonerBasicDTOEntry
    {
        public String playerOrTeamId;
        public String playerOrTeamName;
        public String division;
        public int leaguePoints;
        public int wins;
        public int losses;
        public boolean isHotStreak;
        public boolean isVeteran;
        public boolean isFreshBlood;
        public boolean isInactive;

        @Override
        public String toString() {
            return "Entry: " + playerOrTeamId + " " + playerOrTeamName + " " + division + " " + leaguePoints + " " + wins + " " + 
                    losses + " " + isHotStreak + " " + isVeteran + " " + isInactive;
        }
    }

这是反序列化的方法:

public static void main(String[] args)
{
    ObjectMapper mapper = new ObjectMapper();
    TypeFactory factory = mapper.getTypeFactory();
    // type of key of response map
    JavaType stringType = factory.constructType(String.class);
    // type of value of response map
    JavaType listOfDtosType = factory.constructCollectionLikeType(ArrayList.class, SingleSummonerBasicDTO.class);
    // create type of map
    JavaType responseType = factory.constructMapLikeType(HashMap.class, stringType, listOfDtosType);

    try (InputStream is = new FileInputStream("C://Temp/xx.json")) {
        Map<String, List<SingleSummonerBasicDTO>> response = new ObjectMapper().readValue(is, responseType);
        System.out.println(response);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

输出:

{38584682=[
SingleSummonerBasicDTO: Viktor's Masterminds PLATINUM RANKED_SOLO_5x5
Entry: 38584682 Lazrkiller V 64 291 295 false true false, 
SingleSummonerBasicDTO: Renekton's Horde SILVER RANKED_TEAM_5x5
Entry: TEAM-ff7d0db0-78ca-11e4-b402-c81f66dba0e7 Y U NO BABAR II 0 4 2 false false false, 
SingleSummonerBasicDTO: Pantheon's Chosen SILVER RANKED_TEAM_5x5
Entry: TEAM-d32018f0-d998-11e4-bfd2-c81f66dba0e7 Lose and Throw Away I 66 7 0 false false false, 
SingleSummonerBasicDTO: Jayce's Duelists SILVER RANKED_TEAM_5x5
Entry: TEAM-6c8fc440-a8ac-11e4-b65b-c81f66db920c TopBlokesNeverToke III 0 20 18 false false false]}

关于java - 在 Hashmap 中将 JsonAnySetter 和 JsonAnyGetter 与 ArrayList 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34486409/

相关文章:

java - 如何根据引用的实体交换@JsonBackReference和@JsonManagedReference

java - 如何配置特定 FileHandler 的属性

java - 如何在 Web API 中使用 Spring Security?

java - 使用 Java 泛型和工厂模式返回类型的最佳实践是什么

javascript - 从嵌套对象的属性生成代码字符串

java - Android 应用程序进行 JSON 调用从服务器获取意外数据,但相同的调用在浏览器中有效

java - Jackson 反序列化为默认子类型

java - 如何排除 findbugs 中的构造函数?

java - 通过注解获取java bean属性值

json - 是否可以在不安装 Play 的情况下使用 JSON 库?