WEB/Java
역직렬화 후 추가 가공
hwahaha
2024. 6. 16. 16:52
기존 JSON 데이터 구조와 원하는 데이터 구조
기존 Json의 items[ item1,item2, ... , item5] 구조가 Thymeleaf로 바인딩할 때 마음에 들지 않아서 날짜 기준으로 그룹화하기로 했다
기존 구조 | 원하는 구조 |
"item" :{[ { "astroEvent": "화성 - 해왕성 최대근접(0°14′)", "astroTime": "06:00", "astroTitle": "", "locdate": 20150120, "seq": 1 }, { "astroEvent": "합삭", "astroTime": "22:15", "astroTitle": "", "locdate": 20150120, "seq": 2 } ] }. |
{locdate=2024-06-14 , events=[ AstroEventItem( astroEvent=상현달, astroTitle=, astroTime=14:18, locdate=20240614, formatLocdate=2024-06-14), AstroEventItem( astroEvent=달의 원지점(404,100km), astroTitle=, astroTime=22:35, locdate=20240614, formatLocdate=2024-06-14) ]} |
데이터 가공 방법 설계
우선 내가 원하는 데이터 가공형태를 생각해봤다.
위의 표 처럼 날짜 기준으로 그룹화 하는게 보기 좋을 듯 했다.
formatLocdate를 key, item을 value로 Map 에 담기위해 Collectors.groupingBy()를 이용했다.
소스코드
Map<String, List<AstroEventItem>> groupedItems = items.stream()
.collect(Collectors.groupingBy(AstroEventItem::getFormatLocdate));
결과
{2024-06-06=[AstroEventItem(astroEvent=합삭, astroTitle=, astroTime=21:38, locdate=20240606, formatLocdate=2024-06-06)], 2024-06-01=[AstroEventItem(astroEvent=해왕성식, astroTitle=, astroTime=13:12, locdate=20240601, formatLocdate=2024-06-01)], 2024-06-21=[AstroEventItem(astroEvent=하지, astroTitle=, astroTime=05:51, locdate=20240621, formatLocdate=2024-06-21)], 2024-06=[AstroEventItem(astroEvent=6월 28일 새벽 0시 30분 기준 달과 토성이 근접한다. 동쪽 하늘에서 달과 토성이 약 1.1도로 가까이 있는 모습을 볼 수 있다., astroTitle=6월 28일 달과 토성의 근접, astroTime=, locdate=202406 , formatLocdate=2024-06)], 2024-06-20=[AstroEventItem(astroEvent=달과 안타레스의 근접(0.4°), astroTitle=, astroTime=19:33, locdate=20240620, formatLocdate=2024-06-20)], 2024-06-05=[AstroEventItem(astroEvent=금성의 외합, astroTitle=, astroTime=01:00, locdate=20240605, formatLocdate=2024-06-05)], 2024-06-15=[AstroEventItem(astroEvent=수성의 외합, astroTitle=, astroTime=02:00, locdate=20240615, formatLocdate=2024-06-15)], 2024-06-14=[AstroEventItem(astroEvent=상현달, astroTitle=, astroTime=14:18, locdate=20240614, formatLocdate=2024-06-14), AstroEventItem(astroEvent=달의 원지점(404,100km), astroTitle=, astroTime=22:35, locdate=20240614, formatLocdate=2024-06-14)], 2024-06-02=[AstroEventItem(astroEvent=달의 근지점(368,100km), astroTitle=, astroTime=16:16, locdate=20240602, formatLocdate=2024-06-02)]} |
이대로 반환하면 순서 문제 및 데이터 구조만 봤을 때 뭘 뜻하는지 잘 모르겠다..
그래서 리스트 형태로 다시 반환했다
재가공
소스코드
List<Map<String,Object>> list = groupedItems.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(entry -> {
Map<String, Object> map = new HashMap<>();
map.put("locdate", entry.getKey());
map.put("events", entry.getValue());
return map;
})
.collect(Collectors.toList());
출력
{locdate=2024-06, events=[AstroEventItem(astroEvent=6월 28일 새벽 0시 30분 기준 달과 토성이 근접한다. 동쪽 하늘에서 달과 토성이 약 1.1도로 가까이 있는 모습을 볼 수 있다., astroTitle=6월 28일 달과 토성의 근접, astroTime=, locdate=202406 , formatLocdate=2024-06)]} {locdate=2024-06-01, events=[AstroEventItem(astroEvent=해왕성식, astroTitle=, astroTime=13:12, locdate=20240601, formatLocdate=2024-06-01)]} {locdate=2024-06-02, events=[AstroEventItem(astroEvent=달의 근지점(368,100km), astroTitle=, astroTime=16:16, locdate=20240602, formatLocdate=2024-06-02)]} {locdate=2024-06-05, events=[AstroEventItem(astroEvent=금성의 외합, astroTitle=, astroTime=01:00, locdate=20240605, formatLocdate=2024-06-05)]} {locdate=2024-06-06, events=[AstroEventItem(astroEvent=합삭, astroTitle=, astroTime=21:38, locdate=20240606, formatLocdate=2024-06-06)]} {locdate=2024-06-14, events=[AstroEventItem(astroEvent=상현달, astroTitle=, astroTime=14:18, locdate=20240614, formatLocdate=2024-06-14), AstroEventItem(astroEvent=달의 원지점(404,100km), astroTitle=, astroTime=22:35, locdate=20240614, formatLocdate=2024-06-14)]} {locdate=2024-06-15, events=[AstroEventItem(astroEvent=수성의 외합, astroTitle=, astroTime=02:00, locdate=20240615, formatLocdate=2024-06-15)]} {locdate=2024-06-20, events=[AstroEventItem(astroEvent=달과 안타레스의 근접(0.4°), astroTitle=, astroTime=19:33, locdate=20240620, formatLocdate=2024-06-20)]} {locdate=2024-06-21, events=[AstroEventItem(astroEvent=하지, astroTitle=, astroTime=05:51, locdate=20240621, formatLocdate=2024-06-21)]} |
최종 코드
최종 코드
GroupService.java
@Service
public class GroupService {
public List<Map<String, Object>> groupAstroEvents(List<AstroEventItem> items) {
Map<String, List<AstroEventItem>> groupedItems = items.stream()
.collect(Collectors.groupingBy(AstroEventItem::getFormatLocdate));
return groupedItems.entrySet().stream()
.sorted(Map.Entry.comparingByKey())
.map(entry -> {
Map<String, Object> map = new HashMap<>();
map.put("locdate", entry.getKey());
map.put("events", entry.getValue());
return map;
})
.collect(Collectors.toList());
}
}
KasiControllerAdvice.java
@ControllerAdvice
public class KasiApiControllerAdvice {
@Value("${KasiKey}")
private String openApiKey;
@Value("${AstroEventInfoUrl}")
private String astroEventInfoUrl;
private final ParamFormatService paramService;
private final JsonService jsonService;
private final GroupService groupService;
@ModelAttribute
public void callAstroEventInfo(Model model){
String urlStr = astroEventInfoUrl +"solYear="+this.paramService.getSolYear()+
"&solMonth="+this.paramService.getSolMonth()+"&serviceKey=" + openApiKey +
"&_type=json";
String result = this.jsonService.getJson(urlStr);
//역직렬화
AstroEventItems astroEventItems = this.jsonService.parseJson(result, AstroEventItems.class);
//그룹화
List<Map<String,Object>> response=this.groupService.groupAstroEvents(astroEventItems.getAstroEventItems());
model.addAttribute("astroEventInfo",response);
}}
main.html
<article class="m-2" th:each="eventGroup:${astroEventInfo}">
<h4 th:text="${eventGroup.locdate}">20150120</h4>
<ul >
<li th:each="event:${eventGroup.events}">
<div th:if="${event.astroTitle != ''}">
<span th:text="${event.astroTime}">01:00</span>
<h5 th:text="${event.astroTitle}">대형광학망원경 개발 및 은하진화 연구</h5>
<h5 th:text="${event.astroEvent}">거대마젤란망원경(Giant Magellan Telescope)은
한국, 미국, 호주 등이 공동으로 개발하는 세계 최대 광학망원경이다.</h5>
</div>
<div th:unless="${event.astroTitle !=''}">
<h5> <span th:text="${event.astroTime}">01:00</span> - <span th:text="${event.astroEvent}">지구 근일점</span></h5>
</div>
</li>
</ul>
</article>
전 후 비교
훨씬 깔끔해졌다!!
https://github.com/GyeonghwaKim/APSharing