์ด์ ํฌ์คํธ
์ค์ฒฉ๋ JSON์ Java Object ๋ก ๋งคํํ๋ ๋ฐฉ๋ฒ1 (With Jackson)
์ ๋ฒ ํฌ์คํธ์์ ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์ค์ฒฉ๋ JSON
์ ์๋ฐ ์ค๋ธ์ ํธ๋ก ๋งคํํ๋ ๋ฐฉ๋ฒ์ ๋ค๋ฃจ์์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ๋ฌธ์ ๋ ์ ๊ฐ ๋งคํํด์ผํ JSON
์ ์ค์ฒฉ ๊น์ด๋ฅผ ๋ณด๋ฉด 1~2๋ ๋ฒจ ์ ๋๊ฐ ์๋์๋ค๋ ๊ฑฐ์ฃ .
"info": {
"gameCreation": 1662939391488,
"mapId": 11,
"participants": [
{
"assists": 3,
"baronKills": 0,
"basicPings": 1,
"bountyLevel": 0,
"challenges": {
"12AssistStreakCount": 0,
"abilityUses": 220,
},
"champExperience": 14906,
"champLevel": 16,
"perks": {
"statPerks": {
"defense": 5003,
"flex": 5008,
"offense": 5005
},
"styles": [
{
"description": "primaryStyle",
"selections": [
{
"perk": 8010,
(๋ค์ ํ๋ฒ ๋ฑ์ฅ )
์ ๋ฒ ํฌ์คํธ๋ฅผ ์ฝ์ผ์ ๋ถ๋ค์ ์์๊ฒ ์ง๋ง ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ๋งคํ ์, ๊ฐ ์ค์ฒฉ JSON
๋ง๋ค Map<String,Object>ํ์
์ ์ฌ์ฉํ์ฌ ๋งคํํ์์ต๋๋ค. ์ค์ฒฉ์ด ํ๋๊ฐ ์ ๋๋ฉด ๊ทธ๋ฅ ํธํ๊ฒ ์ฐ๊ฒ ์ง๋ง, ์ค์ฒฉ depth๊ฐ ์ฌ๋ฌ ๋ ๋ฒจ์ด ๋๋ฉด Map ์ธ์คํด์ค๋ฅผ ๊ณ์ ์์ฑํด์ผํ๋ ๋จ์ ์ด ์์์ต๋๋ค. ์ด๋ ํจ์จ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฒ์ด ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค. (์ ์๊ฐ์
๋๋ค. ๊ทธ๋ ๊ฒ ํฐ ๋ฌธ์ ๊ฐ ์๋๋ผ๋ฉด ๋๊ธ๋ก ์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.)
๋ฐ๋ผ์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์๋ํด๋ณด๋ ค๊ณ ํฉ๋๋ค. ์ ๊ฐ ์ค์ฒฉ๋ JSON์ JAVA ์ค๋ธ์ ํธ๋ก ๋งคํํ๋ ๋ฐฉ๋ฒ์ด 3๊ฐ์ง ์ ๋๊ฐ ์๋ค๊ณ ๋ง์๋๋ ธ์๋๋ฐ, ์ด๋ฒ์๋ ๊ทธ ์ค ๋๋ฒ์งธ ๋ฐฉ๋ฒ์ ๋ํด์ ์ค๋ช ํด๋ณด๊ฒ ์ต๋๋ค. 3๋ฒ์งธ ๋ฐฉ๋ฒ์ธ JsonDeserializer๋ฅผ ์ด์ฉํ ๋งคํ์, ์ง๊ธ ๋ค๋ฃฐ JsonNode ๋งคํ๊ณผ ์๋นํ ์ ์ฌํ์ฌ ๋ค๋ฃจ์ง ์๊ฒ ์ต๋๋ค.
(์คํฌํ์๋ฉด ๊ฒฐ๋ก ๋ถ์์ ์๊ฐ์ ๋ฐ๋๊ฒ ๋ฉ๋๋ค..)
<๋งคํํ๋ ๋ฐฉ๋ฒ 3๊ฐ์ง>
- ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ ๋งคํ
- JsonNode๋ฅผ ์ฌ์ฉํ ๋งคํ -> ์ด๋ฒ ํฌ์คํธ!
- ์ฌ์ฉ์๊ฐ ์ ์ํ JsonDeserializer๋ฅผ ์ด์ฉํ ๋งคํ
{
"nation": "Korea",
"name": "Minsu",
"address": {
"city": "Seoul",
"gu": "Songpa",
"apart": {
"apartName": "JsonApart",
"dong": "101",
"ho": "1501"
}
}
}
public class Person {
private String nation; //๊ตญ์
private String name; // ์ฌ๋ ์ด๋ฆ
private String city; // ์ฌ๋ ๋์
private String apartName; // ์ํํธ ์ด๋ฆ
}
์ ๋ฒ๊ณผ ๋๊ฐ์ด, ํ๊ตญ ๊ตญ์ ์ ์์ธ์ ์กํ๊ตฌ JsonApart 101๋ 1501ํธ ์ฌ๋ ๋ฏผ์๋ฅผ ๊ฐ์ ธ์ค๊ฒ ์ต๋๋ค. ๊ฐ์ฒด ๋ํ Person
๊ฐ์ฒด๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๊ฒ ์ต๋๋ค.
ObjectMapper
์ readTree
๋ฅผ ์ฌ์ฉํ ๊ฒ์
๋๋ค. ์ฝ๋ ๋จผ์ ๋ณด์์ฃ
@Test
public void whenUsingJsonNode_thenOk() throws IOException {
String SOURCE_JSON = "{"nation": "Korea","name": "Minsu","address": {"city": "Seoul","gu": "Songpa","apart": {"apartName": "JsonApart","dong": "101","ho": "1501"}}}";
JsonNode personNode = new ObjectMapper().readTree(SOURCE_JSON);
Person person = new Person();
person.setNation(personNode.get("nation").textValue());
person.setName(personNode.get("name").textValue());
person.setCity(personNode.get("address")
.get("city").textValue());
person.setApartName(personNode.get("address")
.get("apart").get("apartName").textValue());
assertEquals(person.getNation(), "Korea");
assertEquals(person.getName(), "Minsu");
assertEquals(person.getCity(), "Seoul");
assertEquals(person.getApartName(), "JsonApart");
}
์ ๋ฒ ์ฝ๋๋ณด๋ค ์ง๊ด์ ์ผ๋ก ์๋ฟ๋ ๋ถ๋ถ์ด ์์ต๋๋ค. ์ค๊ฐ์ setter
๋ฅผ ์ฌ์ฉํ๋ ๋ถ๋ถ์ ๋ง์ฝ Builder
ํจํด์ผ๋ก ๋์ฒด๊ฐ ๊ฐ๋ฅํ ๊ฒ ๊ฐ์ต๋๋ค.
์ด ์ฝ๋์ ํต์ฌ์ ์๋ฌด๋๋ ์ด ๋ถ๋ถ์ธ ๊ฒ ๊ฐ์ต๋๋ค.
JsonNode personNode = new ObjectMapper().readTree(SOURCE_JSON);
์์์ ์ฌ์ฉํ readTree ๋ฉ์๋์ ์ํ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
public <T extends TreeNode> T readTree(JsonParser p)
JSON์ ์ฝ์ด๋ค์ฌ, TreeNode
์ธํฐํ์ด์ค๋ฅผ ๋ฆฌํดํฉ๋๋ค. TreeNode
๋ JSON์ ํธ๋ฆฌ ํํ๋ก ๋ํ๋ธ ์ผ์ข
์ ์๋ฃ๊ตฌ์กฐ์
๋๋ค.
์ ๊ฐ ์ฌ์ฉํ ์ฝ๋์์๋ TreeNode
์ ๊ตฌํ์ฒด์ธ JsonNode
ํ์
์ ๋ฆฌํดํฉ๋๋ค.
๋ค์ ์ฝ๋๋ฅผ ๋ณด์์ฃ
Person person = new Person();
person.setNation(personNode.get("nation").textValue());
person.setName(personNode.get("name").textValue());
person.setCity(personNode.get("address")
.get("city").textValue());
๋จผ์ ์๋ก์ด Person ๊ฐ์ฒด๋ฅผ ๋ง๋ญ๋๋ค. JsonNode
ํ์
์ personNode์์ Person ํ๋์ ๋ง๋ ๋
ธ๋๋ค์ get() ๋ฉ์๋๋ก ๊บผ๋ด textValue() ๋ฉ์๋๋ก String ํ๋ณํ์ ํด์ฃผ๊ณ ์์ต๋๋ค.
์ด๋ ๊ฒ ๋ ๊ฐ์ง์ ๋งคํ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์์ต๋๋ค.
๋ค์ ํ๋ฒ ์ฝ๋๋ฅผ ๋ณด๊ณ , ๊ฐ๊ฐ์ ์ฅ๋จ์ ์ ์๊ฐํด์ ์ ๋ฆฌํด๋ณด๊ฒ ์ต๋๋ค.
public class Person {
private String nation;
private String name;
private String city;
private String apartName;
@SuppressWarnings("unchecked")
@JsonProperty("address")
private void unpackNested(Map<String,Object> address) {
this.city = (String)address.get("city");
Map<String,String> apart = (Map<String,String>)address.get("apart");
this.apartName = apart.get("apartName");
}
}
@Test
public void whenUsingAnnotations_thenOk() throws IOException {
Product product = new ObjectMapper()
.readerFor(Product.class)
.readValue(SOURCE_JSON); // ๋ฏผ์์ JSON์ด ๋์ด์ฌ ์์
}
@Test
public void whenUsingJsonNode_thenOk() throws IOException {
String SOURCE_JSON = "{"nation": "Korea","name": "Minsu","address": {"city": "Seoul","gu": "Songpa","apart": {"apartName": "JsonApart","dong": "101","ho": "1501"}}}";
JsonNode personNode = new ObjectMapper().readTree(SOURCE_JSON);
Person person = new Person();
person.setNation(personNode.get("nation").textValue());
person.setName(personNode.get("name").textValue());
person.setCity(personNode.get("address")
.get("city").textValue());
person.setApartName(personNode.get("address")
.get("apart").get("apartName").textValue());
}
- 0๋ ๋ฒจ depth์ ์ค์ฒฉ์ ์ฒ๋ฆฌํ ํ์๊ฐ ์๋ค (
ObjectMapper
๊ฐ ์์์ ํด์ค).- ํ๋ฒ
JAVA Object
์ ์ ์ํด๋์ผ๋ฉด ๊ทธ ๋ค์๋ถํฐ๋ObjectMapper.readValue
๋ก ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค.- ์ค๋ณต๋๋ ์ฝ๋๋ ์ด๋ ธํ ์ด์ ๋งคํ์ด ๋ํ๋ค.
- ์ฝ๋ ๋ ๋ฒจ์์ ํ๋์ ๋ค์ด์ค์ง ์๋๋ค.
Map
์ธ์คํด์ค๋ฅผ ์ค์ฒฉ ๊น์ด๋ง๋ค ์์ฑํด์ค์ผ ํ๋ค.- ์์ ํ์ง ์์ ์ ๋ค๋ฆญ ํ๋ณํ ์ผ์ด์ค๊ฐ ๋ฐ์ํ ์ ์๋ค. (๊ณ์ ๊ฒฝ๊ณ ๋ ๋จ๊ณ )
- ์ฝ๋ ๋ ๋ฒจ์์ ์ง๊ด์ ์ผ๋ก ์ดํดํ ์ ์๋ค.
JsonNode
์ธ์คํด์ค ํ๋๋ก ๋งคํ์ด ๊ฐ๋ฅํ๋ค.
JAVA Object
ํ๋ ๊ฐ์๊ฐ ๋ง์์ง ์๋กgetter
,setter
๋ฐ๋ณต์ด ์ฌํด์ง๋ค.- 0๋ ๋ฒจ depth์ ์ค์ฒฉ ๋ํ ์ผ์ผ์ด ๋งคํํด์ค์ผ ํ๋ค.
- ๋น๋ ํจํด์ ์ฌ์ฉํ์ง ์์ ์,
setter
๊ฐ ๊ฐ์ ๋ ์ ์๋ค.
ํ๋์ ํฌ์คํธ์์๋ ์๊ฒฌ์ด ์๋ค ๊ฐ๋ค ํ๋๋ฐ ์๊ธด๋ฐ.. ์ ๋ฆฌํ๊ณ ๋ณด๋ ์ด๋
ธํ
์ด์
๋งคํ์ด ๋ซ๊ฒ ๋ค ์ถ์ต๋๋ค. ์ง๊ธ Riot Api
์์ ์๋ต์ผ๋ก ๋ฐ์์์ ๋งคํํ Dto ํ๋ ๊ฐ์๊ฐ ์ฅ๋์ด ์๋๋ฐ์,
(๋ฌผ๋ก ๋ค์ฐ์ง ์๊ณ ํ์ํ ๊ฒ๋ง ๋ช๊ฐ ์ถ๋ฆด ์์ ์
๋๋ค....)
์ด๊ฑฐ๋ฅผ ์ธ์ ๋ค MatchNode.set().get()... ์ด๋ฐ ์์ผ๋ก ํด์ผํ ์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๋ํ, JsonNode
์ ์ฑ๋ฅ ๋ํ ๋ฌด์กฐ๊ฑด Map.get()
๋ณด๋ค ์ข๋ค๊ณ ํ ์ ์์ผ๋... (JsonNode
๊ฐ ์ด๋ค ๊ตฌ์กฐ์ธ์ง๋ ํ๋ฒ ์ฐพ์๋ด์ผํ ๊ฒ ๊ฐ์ต๋๋ค.) ํนํ ์ด๋
ธํ
์ด์
๋งคํ์ ์ฌ์ฉํ๋ฉด 0๋ ๋ฒจ ๊น์ด์ ์ค์ฒฉ property๋ ์ฒ๋ฆฌํ์ง ์์๋ ๋๋, ๋ฌด์กฐ๊ฑด ์ด๋
ธํ
์ด์
๋งคํ์ ์จ์ผํ ๊ฒ ๊ฐ์ต๋๋ค.
๊ทธ๋๋ ๋ ์ฌ์ด์ ๋น๊ต๋ฅผ ํ๊ณ ๋๋ ์ข ๋ ์ ํ์ ํ์ ์ด ์๋ ๋๋์ด๋ค์.. ๋คํ์ ๋๋ค!
ํ๋ฆฐ ๋ด์ฉ, ๋ง๋ถ์ผ ๋ด์ฉ ์์ผ์๋ฉด ๋๊ธ๋ก ๋ฌ์์ฃผ์ธ์!!
์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!!
https://www.baeldung.com/jackson-nested-values
https://www.baeldung.com/jackson-annotations
Thanks for sharing the information on how to map nested Java objects using annotations google feud.