리다이렉트 경로 상수화 및 중복 제거

- "redirect:/", "redirect:/login?reason=auth" 상수로 치환
- 중복된 문자열 정의 제거 및 가독성 개선
This commit is contained in:
Rinjae
2026-08-18 14:50:08 +09:00
parent f26aae296a
commit bf63701e68
@@ -37,23 +37,27 @@ import org.springframework.web.servlet.mvc.support.RedirectAttributes;
@RequiredArgsConstructor @RequiredArgsConstructor
public class PortalGlobalExceptionHandler { public class PortalGlobalExceptionHandler {
private static final String REDIRECT_PREFIX = "redirect:";
private static final String REDIRECT_HOME = REDIRECT_PREFIX + "/";
private static final String REDIRECT_LOGIN_AUTH = REDIRECT_PREFIX + "/login?reason=auth";
private final Logger log = LoggerFactory.getLogger(getClass()); private final Logger log = LoggerFactory.getLogger(getClass());
private final PortalProperties portalProperties; private final PortalProperties portalProperties;
private final Environment environment; private final Environment environment;
@ExceptionHandler(value = NotFoundException.class) @ExceptionHandler(value = NotFoundException.class)
public ModelAndView handleINotFoundException(HttpServletRequest request, NotFoundException ex) { public ModelAndView handleINotFoundException(HttpServletRequest request, NotFoundException ex) {
return new ModelAndView("redirect:/"); return new ModelAndView(REDIRECT_HOME);
} }
@ExceptionHandler(value = MethodArgumentTypeMismatchException.class) @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
public ModelAndView handleMethodArgumentTypeMismatchException(HttpServletRequest request, MethodArgumentTypeMismatchException ex) { public ModelAndView handleMethodArgumentTypeMismatchException(HttpServletRequest request, MethodArgumentTypeMismatchException ex) {
return new ModelAndView("redirect:/"); return new ModelAndView(REDIRECT_HOME);
} }
@ExceptionHandler(value = UserNotLoginException.class) @ExceptionHandler(value = UserNotLoginException.class)
public ModelAndView handleUserNotLoginException(HttpServletRequest request, UserNotLoginException ex) { public ModelAndView handleUserNotLoginException(HttpServletRequest request, UserNotLoginException ex) {
return new ModelAndView("redirect:/login?reason=auth"); return new ModelAndView(REDIRECT_LOGIN_AUTH);
} }
@ExceptionHandler(value = AccessDeniedException.class) @ExceptionHandler(value = AccessDeniedException.class)
@@ -62,7 +66,7 @@ public class PortalGlobalExceptionHandler {
if (!SecurityUtil.isAuthenticated()) { if (!SecurityUtil.isAuthenticated()) {
// 원래 요청 페이지를 세션에 저장 → 로그인+2FA 완료 후 LoginFinalizer 가 복귀시킨다. // 원래 요청 페이지를 세션에 저장 → 로그인+2FA 완료 후 LoginFinalizer 가 복귀시킨다.
savePostLoginRedirect(request); savePostLoginRedirect(request);
return new ModelAndView("redirect:/login?reason=auth"); return new ModelAndView(REDIRECT_LOGIN_AUTH);
} }
log.warn("접근 권한 없음: loginId={}, uri={}", StringMaskingUtil.maskLoginId(SecurityUtil.getCurrentLoginId()), request.getRequestURI()); log.warn("접근 권한 없음: loginId={}, uri={}", StringMaskingUtil.maskLoginId(SecurityUtil.getCurrentLoginId()), request.getRequestURI());
ModelAndView modelAndView = new ModelAndView("error"); ModelAndView modelAndView = new ModelAndView("error");
@@ -137,7 +141,7 @@ public class PortalGlobalExceptionHandler {
String target = ex.getRedirectPage(); String target = ex.getRedirectPage();
if (!isSafeRedirectTarget(target)) { if (!isSafeRedirectTarget(target)) {
log.warn("허용되지 않은 리다이렉트 대상 - uri={}, target={}", request.getRequestURI(), target); log.warn("허용되지 않은 리다이렉트 대상 - uri={}, target={}", request.getRequestURI(), target);
return new ModelAndView("redirect:/"); return new ModelAndView(REDIRECT_HOME);
} }
return new ModelAndView(target); return new ModelAndView(target);
} }
@@ -148,8 +152,8 @@ public class PortalGlobalExceptionHandler {
return false; return false;
} }
String path = target; String path = target;
if (path.startsWith("redirect:")) { if (path.startsWith(REDIRECT_PREFIX)) {
path = path.substring("redirect:".length()); path = path.substring(REDIRECT_PREFIX.length());
} else if (path.startsWith("forward:")) { } else if (path.startsWith("forward:")) {
path = path.substring("forward:".length()); path = path.substring("forward:".length());
} }
@@ -172,7 +176,7 @@ public class PortalGlobalExceptionHandler {
public ModelAndView handleHttpRequestMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException ex) { public ModelAndView handleHttpRequestMethodNotSupportedException(HttpServletRequest request, HttpRequestMethodNotSupportedException ex) {
log.error(ex.getMessage()); log.error(ex.getMessage());
ModelAndView modelAndView = new ModelAndView(); ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect:/"); modelAndView.setViewName(REDIRECT_HOME);
return modelAndView; return modelAndView;
} }
@@ -216,7 +220,7 @@ public class PortalGlobalExceptionHandler {
public ModelAndView handleInvalidFileException(HttpServletRequest request, RedirectAttributes redirectAttributes, InvalidFileException ex) { public ModelAndView handleInvalidFileException(HttpServletRequest request, RedirectAttributes redirectAttributes, InvalidFileException ex) {
ModelAndView modelAndView = new ModelAndView(); ModelAndView modelAndView = new ModelAndView();
redirectAttributes.addFlashAttribute("error", ex.getMessage()); redirectAttributes.addFlashAttribute("error", ex.getMessage());
modelAndView.setViewName("redirect:" + request.getRequestURI()); modelAndView.setViewName(REDIRECT_PREFIX + request.getRequestURI());
return modelAndView; return modelAndView;
} }
@@ -227,7 +231,7 @@ public class PortalGlobalExceptionHandler {
String errorMessage = "파일 크기가 허용된 최대 용량(" + maxSize + ")을 초과했습니다."; String errorMessage = "파일 크기가 허용된 최대 용량(" + maxSize + ")을 초과했습니다.";
redirectAttributes.addFlashAttribute("error", errorMessage); redirectAttributes.addFlashAttribute("error", errorMessage);
ModelAndView modelAndView = new ModelAndView(); ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("redirect:" + request.getRequestURI()); modelAndView.setViewName(REDIRECT_PREFIX + request.getRequestURI());
return modelAndView; return modelAndView;
} }
} }