개주 훈련일지/🔥 히노카미 코구라(오류 수정)

오류내역) 스프링 404 발생 PathVariable vs RequestParam 혼용(Handler Mapping 실패)

lshfood2 2026. 2. 4. 23:15

[ Whitelabel Error Page ]

애니 상세 페이지에서 ‘수정’ 버튼을 눌렀는데

수정 페이지로 이동하지 않고 404가 발생했다.

 

브라우저

: 'Whitelabel Error Page'

 

서버 로그

: 'No mapping for GET /animeEditPage/3'

: 또는 핸들러를 찾지 못했다는 형태의 메시지

 

핵심은 요청은 들어오는데 스프링이 해당 요청을 처리할

컨트롤러 메서드를 찾지 못해 매핑이 실패한 케이스다.


원인 후보(의심 지점) 포착)

이 상황에서 제일 먼저 의심할 지점은 2가지다.

  1. URL 경로가 컨트롤러 매핑과 다름(주소 불일치)
  2. URL 패턴은 같아 보이는데 PathVariable 방식과
    RequestParam 방식이 서로 섞여 있음(패턴 불일치)

이 중에서 이번 케이스는 2번이었다.

  • PathVariable
    : URL 경로 자체에 값이 들어감.
    : 예) /animeEditPage/3
  • RequestParam
    : 쿼리스트링으로 값이 들어감.
    : 예) /animeEditPage?animeId=3

[ 가설 수립: jsp의 '요청 URL'이 잘못됐다 ]

‘JSP에서 보내는 요청 형태’와

‘컨트롤러가 받으려는 형태’가 다르면

스프링은 아예 다른 URL로 인식한다.

 

즉,

  • JSP 요청: /animeEditPage/3
  • 컨트롤러 기대: /animeEditPage?animeId=3

이 상태면 스프링 입장에서는

‘매핑된 핸들러가 없음’이 되어 404가 발생한다.


[ 확인 : animeEdit 컨트롤러 매핑 검증 ]

확인 방법은 단순하다.

  1. 브라우저 주소창에서 실제 호출 URL 확인
  2. 컨트롤러의 @GetMapping 패턴 확인
  3. 둘이 완전히 같은 형태인지 비교

이 비교에서 딱 어긋나면 ‘핸들러 매핑 실패’가 난다.

 

오류를 야기한 코드(혼용 케이스)

JSP는 PathVariable 형식으로 보냈는데

<a href="${cp}/animeEditPage/${animeData.animeId}">수정</a>

 

컨트롤러는 RequestParam 형식으로 받으려고 함

@GetMapping("/animeEditPage")
public String animeEditPage(
        @RequestParam("animeId") int animeId,
        HttpSession session,
        Model model
) {
    // ...
}

 

실제 요청 URL vs 기대 URL 불일치 문제

  • JSP 요청: /animeEditPage/3
  • 컨트롤러 기대: /animeEditPage?animeId=3

→ 결과: Handler Mapping 실패(404 / No mapping)


[ 해결 : 요청과 기대 URL 방식 통일 ]

해결은 ‘한 방식으로 통일’이다.

아래 2가지 중 하나로만 고정하면 정상 동작한다.

 

1) 정상 동작 패턴 A: PathVariable 방식으로 통일

(정상) JSP 요청 코드

<c:if test="${sessionScope.memberRole eq 'ADMIN'}">
  <a href="${cp}/animeEditPage/${animeData.animeId}">수정</a>
</c:if>

 

(정상) 컨트롤러 매핑 코드

@GetMapping("/animeEditPage/{animeId}")
public String animeEditPage(
        @PathVariable("animeId") int animeId,
        HttpSession session,
        Model model
) {
    // ...
    return "animeedit";
}

 

(정상) 실제 요청 URL 형태

/animeEditPage/3

@PathVariable은 'URL 경로에 포함된 값'

컨트롤러 파라미터에 바인딩하는 방식이다.

 

 

2) 정상 동작 패턴 B: RequestParam 방식으로 통일

(정상) JSP 요청 코드

<c:if test="${sessionScope.memberRole eq 'ADMIN'}">
  <a href="${cp}/animeEditPage?animeId=${animeData.animeId}">수정</a>
</c:if>

 

(정상) 컨트롤러 매핑 코드

@GetMapping("/animeEditPage")
public String animeEditPage(
        @RequestParam("animeId") int animeId,
        HttpSession session,
        Model model
) {
    // ...
    return "animeedit";
}

 

(정상) 실제 요청 URL 형태

/animeEditPage?animeId=3

@RequestParam은 'URL의 쿼리 파라미터(요청 파라미터) 값'

컨트롤러 파라미터에 바인딩하는 방식이다.

 

이번 케이스는 이 방식으로 통일해서 해결했다.


[ 결론 ]

이번 오류의 이름을 한 줄로 정리하면

요청 매핑 불일치 오류
  • URL 패턴 불일치로 인한 핸들러 매핑 실패
  • PathVariable/RequestParam 혼용으로 발생한
    URL 매핑 불일치(Handler Mapping 실패)

추가로, 비슷하게 404가 나는 케이스로는

‘HTTP 메서드 불일치’도 자주 있으니

(= GET으로 호출했는데 컨트롤러는 POST만 열어둔 경우)

 

404가 뜨면, URL 패턴 + HTTP 메서드까지

같이 확인하는 게 정석이다.