Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
import org.springframework.http.HttpStatus;

import static com.example.solidconnection.application.service.ApplicationSubmissionService.APPLICATION_UPDATE_COUNT_LIMIT;
import static com.example.solidconnection.custom.resolver.CustomPageableHandlerMethodArgumentResolver.MAX_SIZE;
import static com.example.solidconnection.custom.resolver.CustomPageableHandlerMethodArgumentResolver.MIN_PAGE;
import static com.example.solidconnection.custom.resolver.CustomPageableHandlerMethodArgumentResolver.MIN_SIZE;
import static com.example.solidconnection.siteuser.service.SiteUserService.MIN_DAYS_BETWEEN_NICKNAME_CHANGES;
import static com.example.solidconnection.siteuser.service.MyPageService.MIN_DAYS_BETWEEN_NICKNAME_CHANGES;

@Getter
@AllArgsConstructor
Expand Down Expand Up @@ -99,10 +96,6 @@ public enum ErrorCode {
USER_DO_NOT_HAVE_GPA(HttpStatus.BAD_REQUEST.value(), "해당 유저의 학점을 찾을 수 없음"),
REJECTED_REASON_REQUIRED(HttpStatus.BAD_REQUEST.value(), "거절 사유가 필요합니다."),

// page
INVALID_PAGE(HttpStatus.BAD_REQUEST.value(), "페이지 번호는 " + MIN_PAGE + " 이상만 가능합니다."),
INVALID_SIZE(HttpStatus.BAD_REQUEST.value(), "페이지 크기는 " + MIN_SIZE + " 이상 " + MAX_SIZE + " 이하만 가능합니다."),

// general
JSON_PARSING_FAILED(HttpStatus.BAD_REQUEST.value(), "JSON 파싱을 할 수 없습니다."),
JWT_EXCEPTION(HttpStatus.BAD_REQUEST.value(), "JWT 토큰을 처리할 수 없습니다."),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.example.solidconnection.custom.resolver;

import com.example.solidconnection.custom.exception.CustomException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
Expand All @@ -11,21 +9,13 @@
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer;

import jakarta.servlet.http.HttpServletRequest;
import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_PAGE;
import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_SIZE;

@Component
public class CustomPageableHandlerMethodArgumentResolver extends PageableHandlerMethodArgumentResolver {

public static final int MIN_PAGE = 1;
public static final int MIN_SIZE = 1;
public static final int MAX_SIZE = 50;
private static final String PAGE_PARAMETER = "page";
private static final String SIZE_PARAMETER = "size";
private static final int DEFAULT_SIZE = 10;

public CustomPageableHandlerMethodArgumentResolver() {
setMaxPageSize(MAX_SIZE);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

처음엔 이 설정을 유지한 채

if (request != null) {
validateParameters(request);
}

이 부분을 없애면 음수나 문자열 같은 잘못된 값들이 부모쪽에서 다 처리를 해줄거라 생각했는데 size를 초과하는 값을 넣으면 기본값인 10이 아니라 최대 size로 반환을 하더라구요. 그래서 이건 지우고 따로 검증하는 방식으로 수정하였습니다.

setOneIndexedParameters(true);
setFallbackPageable(PageRequest.of(0, 10));
}
Expand All @@ -35,33 +25,10 @@ public Pageable resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) {
HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
if (request != null) {
validateParameters(request);
}
return super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
}

private void validateParameters(HttpServletRequest request) {
int page = extractIntParameter(request, PAGE_PARAMETER, 1);
int size = extractIntParameter(request, SIZE_PARAMETER, 10);
if (page < MIN_PAGE) {
throw new CustomException(INVALID_PAGE);
}
if (size < MIN_SIZE || size > MAX_SIZE) {
throw new CustomException(INVALID_SIZE);
}
}

private int extractIntParameter(HttpServletRequest request, String paramName, int defaultValue) {
String paramValue = request.getParameter(paramName);
if (StringUtils.isBlank(paramValue)) {
return defaultValue;
}
try {
return Integer.parseInt(paramValue);
} catch (NumberFormatException e) {
return defaultValue;
Pageable pageable = super.resolveArgument(methodParameter, mavContainer, webRequest, binderFactory);
if (pageable.getPageSize() > MAX_SIZE) {
return PageRequest.of(pageable.getPageNumber(), DEFAULT_SIZE, pageable.getSort());
}
return pageable;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.example.solidconnection.custom.resolver;

import com.example.solidconnection.custom.exception.CustomException;
import com.example.solidconnection.support.TestContainerSpringBootTest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
Expand All @@ -14,10 +13,8 @@

import java.lang.reflect.Method;

import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_PAGE;
import static com.example.solidconnection.custom.exception.ErrorCode.INVALID_SIZE;
import static com.example.solidconnection.custom.resolver.CustomPageableHandlerMethodArgumentResolver.MAX_SIZE;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;

@TestContainerSpringBootTest
@DisplayName("커스텀 페이지 요청 argument resolver 테스트")
Expand Down Expand Up @@ -87,63 +84,73 @@ void setUp() throws NoSuchMethodException {
}

@Test
void 페이지_파라미터가_최소값보다_작으면_예외_응답을_반환한다() {
void 페이지_파라미터가_최소값보다_작으면_기본값을_사용한다() {
// given
request.setParameter(PAGE_PARAMETER, "0");

// when & then
assertThatCode(() -> customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_PAGE.getMessage());
// when
Pageable pageable = customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null);

// then
assertThat(pageable.getPageNumber()).isEqualTo(DEFAULT_PAGE - 1);
assertThat(pageable.getPageSize()).isEqualTo(DEFAULT_SIZE);
}

@Test
void 페이지_파라미터가_음수이면_예외_응답을_반환한다() {
void 페이지_파라미터가_음수이면_기본값을_사용한다() {
// given
request.setParameter(PAGE_PARAMETER, "-1");

// when & then
assertThatCode(() -> customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_PAGE.getMessage());
// when
Pageable pageable = customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null);

// then
assertThat(pageable.getPageNumber()).isEqualTo(DEFAULT_PAGE - 1);
assertThat(pageable.getPageSize()).isEqualTo(DEFAULT_SIZE);
}

@Test
void 사이즈_파라미터가_최소값보다_작으면_예외_응답을_반환한다() {
void 사이즈_파라미터가_최소값보다_작으면_기본값을_사용한다() {
// given
request.setParameter(SIZE_PARAMETER, "0");

// when & then
assertThatCode(() -> customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_SIZE.getMessage());
// when
Pageable pageable = customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null);

// then
assertThat(pageable.getPageNumber()).isEqualTo(DEFAULT_PAGE - 1);
assertThat(pageable.getPageSize()).isEqualTo(DEFAULT_SIZE);
}

@Test
void 사이즈_파라미터가_최대값보다_크면_예외가_발생한다() {
void 사이즈_파라미터가_최대값보다_크면_기본값을_사용한다() {
// given
request.setParameter(SIZE_PARAMETER, String.valueOf(CustomPageableHandlerMethodArgumentResolver.MAX_SIZE + 1));
request.setParameter(SIZE_PARAMETER, String.valueOf(MAX_SIZE + 1));

// when & then
assertThatCode(() -> customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_SIZE.getMessage());
// when
Pageable pageable = customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null);

// then
assertThat(pageable.getPageNumber()).isEqualTo(DEFAULT_PAGE - 1);
assertThat(pageable.getPageSize()).isEqualTo(DEFAULT_SIZE);
}

@Test
void 사이즈_파라미터가_음수이면_예외_응답을_반환한다() {
void 사이즈_파라미터가_음수이면_기본값을_사용한다() {
// given
request.setParameter(SIZE_PARAMETER, "-1");

// when & then
assertThatCode(() -> customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null))
.isInstanceOf(CustomException.class)
.hasMessage(INVALID_SIZE.getMessage());
// when
Pageable pageable = customPageableHandlerMethodArgumentResolver
.resolveArgument(parameter, null, webRequest, null);

// then
assertThat(pageable.getPageNumber()).isEqualTo(DEFAULT_PAGE - 1);
assertThat(pageable.getPageSize()).isEqualTo(DEFAULT_SIZE);
}

private static class TestController {
Expand Down