在Hashmap中使用JsonAnySetter和JsonAnyGetter与ArrayList

时间:2015-12-28 00:42:45

标签: 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循环,但是我不知道如何在没有东西循环的情况下循环遍历。

我完全不知道注释是如何工作的,以及如何继续,如果有任何帮助,我会感激不尽!

2 个答案:

答案 0 :(得分:1)

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

Jackson非常有能力在序列化和反序列化中使用Java Collections和Maps。您只需要告诉它集合的参数类型。

在您的情况下,我使用Map来捕获根元素,使其成为List DTO作为值的唯一键。我使用杰克逊的类型系统(TypeFactoryJavaType)告诉杰克逊所有通用类型。

这是我使用过的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]}

答案 1 :(得分:0)

以下是解析json的方法:

{{1}}