-
Notifications
You must be signed in to change notification settings - Fork 8
refactor: @PageableDefault 및 페이지 검증 로직을 ArgumentResolver로 개선 #247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
63714ef
c91aa31
8e1487c
d4f128a
c2f0d60
78ee605
e75eb46
a8731a3
7583459
c3c1330
53aabb8
1f4819c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| package com.example.solidconnection.custom.request; | ||
|
|
||
| import com.example.solidconnection.custom.exception.CustomException; | ||
| import lombok.Getter; | ||
| import org.springframework.data.domain.PageRequest; | ||
| import org.springframework.data.domain.Pageable; | ||
| import org.springframework.data.domain.Sort; | ||
|
|
||
| import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_PAGE; | ||
| import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_SIZE; | ||
|
|
||
| @Getter | ||
| public class CustomPageRequest { | ||
|
|
||
| public static final int MIN_PAGE = 1; | ||
| public static final int MIN_SIZE = 1; | ||
| public static final int MAX_SIZE = 50; | ||
|
|
||
| private final int page; | ||
| private final int size; | ||
| private Sort sort = Sort.unsorted(); | ||
|
|
||
| public CustomPageRequest(int page, int size) { | ||
| validatePageParameters(page, size); | ||
| this.page = page; | ||
| this.size = size; | ||
| } | ||
|
|
||
| public CustomPageRequest(int page, int size, Sort sort) { | ||
| this(page, size); | ||
| this.sort = sort; | ||
| } | ||
|
||
|
|
||
| // 1-based -> 0-based 변환 | ||
Gyuhyeok99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| public Pageable toPageable() { | ||
| return PageRequest.of(page - 1, size, sort); | ||
| } | ||
|
|
||
| private static void validatePageParameters(int page, int size) { | ||
| if (page < MIN_PAGE) { | ||
| throw new CustomException(INVALID_PAGE); | ||
| } | ||
| if (size < MIN_SIZE || size > MAX_SIZE) { | ||
| throw new CustomException(INVALID_SIZE); | ||
| } | ||
| } | ||
|
|
||
| public static CustomPageRequest of(int page, int size, Sort sort) { | ||
| return new CustomPageRequest(page, size, sort); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,82 @@ | ||
| package com.example.solidconnection.custom.resolver; | ||
|
|
||
| import com.example.solidconnection.custom.request.CustomPageRequest; | ||
| import jakarta.servlet.http.HttpServletRequest; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.core.MethodParameter; | ||
| import org.springframework.data.domain.Sort; | ||
| import org.springframework.stereotype.Component; | ||
| import org.springframework.web.bind.support.WebDataBinderFactory; | ||
| import org.springframework.web.context.request.NativeWebRequest; | ||
| import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
| import org.springframework.web.method.support.ModelAndViewContainer; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| @Component | ||
| @RequiredArgsConstructor | ||
| public class CustomPageRequestArgumentResolver implements HandlerMethodArgumentResolver { | ||
|
|
||
| private static final String PAGE_PARAMETER = "page"; | ||
| private static final String SIZE_PARAMETER = "size"; | ||
| private static final String SORT_PARAMETER = "sort"; | ||
| private static final String DESC = "desc"; | ||
| private static final String COMMA = ","; | ||
| private static final int DEFAULT_PAGE = 1; | ||
| private static final int DEFAULT_SIZE = 10; | ||
|
|
||
| @Override | ||
| public boolean supportsParameter(MethodParameter parameter) { | ||
| return CustomPageRequest.class.isAssignableFrom(parameter.getParameterType()); | ||
| } | ||
|
|
||
| @Override | ||
| public Object resolveArgument(MethodParameter parameter, | ||
| ModelAndViewContainer mavContainer, | ||
| NativeWebRequest webRequest, | ||
| WebDataBinderFactory binderFactory) { | ||
| HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); | ||
| int page = extractIntParameter(request, PAGE_PARAMETER, DEFAULT_PAGE); | ||
| int size = extractIntParameter(request, SIZE_PARAMETER, DEFAULT_SIZE); | ||
| Sort sort = extractSortParameter(request); | ||
| return CustomPageRequest.of(page, size, sort); | ||
| } | ||
|
|
||
| private int extractIntParameter(HttpServletRequest request, String paramName, int defaultValue) { | ||
| String paramValue = request.getParameter(paramName); | ||
| if (paramValue != null && !paramValue.isEmpty()) { | ||
| try { | ||
| return Integer.parseInt(paramValue); | ||
| } catch (NumberFormatException e) { | ||
| // 숫자로 변환할 수 없는 경우 기본값 사용 | ||
| } | ||
Gyuhyeok99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| return defaultValue; | ||
| } | ||
|
|
||
| private Sort extractSortParameter(HttpServletRequest request) { | ||
| String[] sortParams = request.getParameterValues(SORT_PARAMETER); | ||
| if (sortParams == null || sortParams.length == 0) { | ||
Gyuhyeok99 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return Sort.unsorted(); | ||
| } | ||
| List<Sort.Order> orders = new ArrayList<>(); | ||
| for (String sortParam : sortParams) { | ||
| addSortOrder(sortParam, orders); | ||
| } | ||
| return orders.isEmpty() ? Sort.unsorted() : Sort.by(orders); | ||
| } | ||
|
|
||
| private void addSortOrder(String sortParam, List<Sort.Order> orders) { | ||
| String[] parts = sortParam.split(COMMA); | ||
| if (parts.length < 1) { | ||
| return; | ||
| } | ||
| String property = parts[0]; | ||
| Sort.Direction direction = Sort.Direction.ASC; | ||
| if (parts.length >= 2 && DESC.equalsIgnoreCase(parts[1])) { | ||
| direction = Sort.Direction.DESC; | ||
| } | ||
| orders.add(new Sort.Order(direction, property)); | ||
| } | ||
| } | ||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.