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

 

GitHub - GyeonghwaKim/APSharing: 천문 현상 정보 공유 사이트

천문 현상 정보 공유 사이트. Contribute to GyeonghwaKim/APSharing development by creating an account on GitHub.

github.com