gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 10:39:51 25 4
gpt4 key购买 nike

所以我正在尝试使用 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/

25 4 0