개주 훈련일지/🏋️ 전집중 호흡 훈련

검색/이동은 동기, 데이터 로딩은 비동기 > 역할 분리 설계

lshfood2 2025. 12. 28. 21:16

[ 구현 배경 ]

내가 작업하는 애니 리스트 페이지는 카드형 UI라서

한 화면에 많은 데이터를 한 번에 보여주지 않는다.


또한 검색(제목/줄거리), 정렬(최신/오래된/가나다),

페이지 이동이 함께 붙어 있기 때문에,

단순히 selectAll()로 전체를 내려보내는 방식은 금방 한계가 온다.

 

내가 선택한 방식을 요약하면 아래와 같다.

  • 페이지 진입/검색 요청은 동기
    → 서버가 화면으로 보내는 흐름
  • 페이지네이션으로 데이터 뽑는 건 비동기
    → JSON으로 필요한 부분만 가져오는 흐름

1. 전체 구조

구성 요소는 총 4개로 나뉜다.

 

1) AnimeListAction (동기)

- anime.jsp로 이동

- 검색인지 판단

- 검색인데 키워드 없으면 message.jsp 처리

- condition/keyword를 request로 넘겨서 “상태 유지”

 

2) anime.jsp (View)

- 화면 뼈대 렌더링

- JS에서 AnimeListDataAction을 AJAX로 호출

- 받은 JSON으로 카드 UI + 페이지바 생성

 

3) AnimeListDataAction (비동기)

JSON으로 “현재 페이지에 필요한 데이터만” 내려줌

검색/정렬/페이지네이션 계산까지 포함해서 내려줌

 

4) 기존 AnimeListFilter 제거 후 합침

정렬용 서블릿이 있었지만, 비동기 페이지네이션이 시작되면

정렬도 결국 같은 요청에서 처리하는 게 더 깔끔해서

AnimeListDataAction 에 합침


2. 왜 “검색/이동”은 동기로 두었나?

내 프로젝트에서 검색은 단순히 데이터만 바꾸는 게 아니라

“유효성 검증 + 상태 전환” 성격이 있었다.

 

1) 검색어 없는 검색 요청 차단

condition=ANIME_SEARCH_TITLE인데 keyword가 빈 값이면,
비동기에서 JSON으로 처리해도 되지만 UX/구조상 애매해진다.

 

나는 이 경우를 명확하게

  • “검색 요청 자체가 잘못된 요청”
    → AnimeListAction에서 동기로 차단
    → message.jsp로 안내

즉, 검색 요청의 유효성 검증을 서버 진입부에서 끝내고
정상 요청만 anime.jsp로 보내는 방식이 더 명확했다.

 

2) 상태 유지가 쉬움

동기 이동을 거치면 request에

  • condition (제목검색/줄거리검색/기본목록)
  • keyword

를 담아서 anime.jsp로 넘겨줄 수 있다.

 

그럼 JS는 이 값을 그대로 사용해서

첫 페이지 데이터를 바로 불러올 수 있다.


3. 왜 “페이지네이션 데이터 추출”은 비동기로 했나?

애니 리스트는 카드 UI라서 페이지 이동이 잦고,

데이터도 많아질 가능성이 크다.


동기 페이지네이션으로도 가능하지만

비동기의 이점이 확실했다.

 

1) 페이지 이동이 빠름

동기: 페이지 버튼 클릭 → 전체 HTML 다시 렌더링

비동기: 페이지 버튼 클릭 → JSON만 가져와서 카드 목록만 교체

 

2) 정렬/검색/페이지네이션을 “한 번의 API”로 통합 가능

처음엔 정렬용 서블릿(AnimeListFilter)을 따로 두려 했는데,
비동기 페이지네이션을 하게 되면 결국 요청은 이렇게 된다.

  • page=?
  • condition=?
  • keyword=?
  • sort=?

이 값들로 “현재 화면이 원하는 데이터”를 딱 가져오는 게 목표라서
정렬도 결국 페이지네이션 요청에 포함시키는 게 가장 깔끔했다.


4. 최종 책임 분리 요약

 

AnimeListAction (동기)

  • “화면 진입 담당”
  • 검색 요청 유효성 검증(키워드 없으면 차단)
  • condition/keyword 상태 전달
  • anime.jsp forward

 

AnimeListDataAction (비동기 JSON)

  • “데이터 제공 담당”
  • 검색 조건 반영
  • 정렬 반영
  • 페이지네이션 계산
  • 현재 페이지 데이터만 JSON으로 반환
    (animeList + paging)

5. JSON 응답 설계

비동기 페이지네이션은

“리스트만” 보내면 페이지바를 만들 수 없다.

그래서 응답은 두 덩어리로 나눴다.

1) animeList : 현재 페이지에 보여줄 데이터 목록

2) paging : 페이지바 구성에 필요한 메타정보

 

paging 안에는 이런 값들이 들어간다.

  • page / totalPage
  • startPage / endPage
  • hasPrev / hasNext
  • condition / keyword / sort (상태 유지용)

결국 View는 paging만 보고 페이지바를 그릴 수 있고,
animeList만 보고 카드 UI를 그릴 수 있다.


6. 마무리

이 구조의 핵심은 “책임을 분리한 것”이다.

  • 동기(페이지 이동/검증): 서버가 요청을 안전하게 정리
  • 비동기(JSON 데이터): 화면에 필요한 만큼만 빠르게 교체

이렇게 나누니까 기능이 늘어나도(정렬 추가, 검색 조건 추가)
컨트롤러가 “한 파일에 다 때려박는 구조”로 망가지지 않고 확장 가능해졌다.