프로젝트의 메인 페이지
, 식당 리뷰 페이지
, 내가 작성한 리뷰 목록 페이지
에서
페이징 기능을 사용하여 구현하였다. 모바일 환경인 점을 고려해 무한 스크롤 방식을 사용하였다.
무한 스크롤은 다음에 조회할 페이지가 있는지 내부적으로 체크한 다음, 클라이언트에게 다음 페이지 여부를 알려주는 방식으로 구현할 수 있다.
"last" 라는 속성을 통해 클라이언트에게 남은 페이지가 더 있는지 알려줄 수 있다.
/**
* 현위치를 받아와 동 이름이 일치하는 식당들 조회
*/
@PostMapping("/api/v1/location/restaurants")
public ResponseEntity<Slice<RestaurantDTO>> getCurrentLocation(@RequestBody LocationDTO locationDTO,
@PageableDefault Pageable pageable) {
float current_lat = locationDTO.getCurrent_lat();
float current_lng = locationDTO.getCurrent_lng();
String dongName = currentLocationService.getCurrentLocation(current_lat, current_lng);
//동 이름이 없을경우 404 Not Found 반환
if (dongName == null) {
return ResponseEntity.notFound().build();
}
Slice<Restaurant> restaurants = restaurantService.searchByCurrentRestaurant(dongName, pageable);
List<RestaurantDTO> restaurantDTOS = restaurants.getContent().stream()
.map(RestaurantDTO::convertToDTO)
.collect(Collectors.toList());
return ResponseEntity.ok(new SliceImpl<>(restaurantDTOS, restaurants.getPageable(), restaurants.hasNext()));
//content가 null일 경우 동과 일치하는 주소가 없는것 = 서울 이외의 지역인 경우
}
public String getCurrentLocation(float current_lat, float current_lng) {
String url = kakaoMapApi + "?x=" + current_lng + "&y=" + current_lat;
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Authorization", "KakaoAK " + kakaoApiKey)
.build();
try {
HttpResponse<String> response = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
String responseBody = response.body();
Gson gson = new Gson();
JsonObject responseJson = gson.fromJson(responseBody, JsonObject.class);
JsonArray documents = responseJson.getAsJsonArray("documents");
if (documents.size() > 0) {
String siName = documents.get(0).getAsJsonObject().get("region_1depth_name").getAsString();
String dongName = documents.get(0).getAsJsonObject().get("region_3depth_name").getAsString();
if (!siName.equals("서울특별시")) {
return null;
}
return dongName;
}
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
return null;
}
받아온 위도, 경도를 기반으로 URL을 생성하고 HttpRequest 객체에 URI와 인증 정보를 요청 헤더에 추가한다.
그리고 httpClient.send() 메서드를 사용해 HTTP 요청을 보내고 API응답을 받는다.
받은 Json 문자열을 Gson 라이브러리를 사용해 Java 객체로 변환해서 값을 꺼내온다.
//동이름으로 식당찾기
public Slice<Restaurant> searchByDongName(String dongName, Pageable pageable) {
List<Restaurant> restaurantList = em.createQuery("select r from Restaurant r where r.address_name like :dongName", Restaurant.class)
.setParameter("dongName", "%" + dongName + "%")
.setFirstResult((int) pageable.getOffset())
.setMaxResults(pageable.getPageSize())
.getResultList();
return new SliceImpl<>(restaurantList, pageable, restaurantList.size() >= pageable.getPageSize());
}
setFirstResult()
및setMaxResults()
를 사용하여 페이징을 적용한다.
첫 번째 결과의 위치와 최대 결과 수가 설정.
SliceImpl
을 사용하여 현재 페이지에 포함된 레스토랑 목록, 페이징 및 정렬 정보, 현재 페이지에 더 많은 결과가 있는지 여부를 나타내는 불리언 값을 전달.
이러한 방식으로 통합검색
, 식당 리뷰 페이지
, 내가 작성한 리뷰 목록 페이지
에서도 페이징 처리를 적용해 주었다.