[Spring Boot] Controller 관련

김광일·2024년 9월 24일

SpringBoot

목록 보기
9/19
post-thumbnail

[1] 코드

package com.example.demo.controller.page;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/user")
@Controller
public class UserController {
    @GetMapping("/{page}")
    public String page(@PathVariable String page){
        return "user/" + page;
    }

    @GetMapping("/{page}/{id}")
    public String page2(@PathVariable String page, @PathVariable String id){
        return "user/" + page;
    }
}

[2] 경로에 대한 설명

1) 첫 번째 경로: @GetMapping("/{page}")

: 이 경로는 URL에서 page 값을 받아서 동적으로 경로를 반환하는 방식이다.

  • 경로: /user/{page}
  • 예시
    • /user/profile 요청 시, profile이 page로 전달되어서 return "user/profile";을 반환하게 된다.
      (즉, 뷰 파일이 user/profile 경로에 있다고 가정하고, 해당 템플릿을 렌더링한다.)
    • /user/settings 요청 시, settings이 전달되어 user/settings 템플릿이 반환된다.

2) 두 번째 경로: @GetMapping("/{page}/{id}")

: 이 경로는 page와 id 두 개의 경로 변수를 사용하여 처리한다. URL에서 두 번째 값인 id를 받아 경로를 동적으로 설정한다.

  • 경로: /user/{page}/{id}
  • 예시
    • /user/profile/123 요청 시, profile과 123이 각각 page와 id로 전달되며, "user/profile" 템플릿을 반환한다. 이때 id 값은 경로의 일부로 사용되지만 뷰 경로에는 영향을 미치지 않는다.
    • /user/settings/456 요청 시, settings이 page로 전달되고, "user/settings" 템플릿이 반환한다. id는 추가적인 정보로 전달되지만 템플릿 경로에는 반영되지 않는다.

3) 경로 동작 정리

  • /user/{page}: URL에서 {page} 자리에 들어가는 값에 따라 해당 템플릿을 반환한다.
    • 예: /user/profile → user/profile 템플릿 반환.
  • /user/{page}/{id}: {page}와 {id}가 URL에 포함되지만, 템플릿 경로는 {page}만 사용된다.
    • 예: /user/profile/123 → user/profile 템플릿 반환.

-> 이렇게 동적으로 URL을 매핑하여 하나의 컨트롤러에서 다양한 페이지를 처리할 수 있다.


[3] Return에 "/user" + page;가 아닌, "user"+page;인 이유

1) 슬래시(/) 사용의 의미

: Spring MVC에서 return문에 지정한 문자열은 뷰의 논리적 이름이다. 이 이름을 기반으로 ViewResolver가 실제 파일 경로를 찾아 렌더링한다.

  • 예시
return "user/" + page;

: 위 코드는 page 값이 profile이라면, user/profile이라는 뷰 이름을 반환하게 된다.. ViewResolver는 설정에 따라 이를 실제 파일 경로로 변환한다. 보통 src/main/resources/templates/user/profile.html과 같은 경로에 해당 파일이 위치하게 된다.

2) 왜 앞에 /를 붙이지 않는가?

: 뷰 리졸버는 논리적인 경로를 처리하는 데 있어서, 맨 앞에 /를 붙이지 않는다. 즉, 경로는 파일 시스템이나 웹의 절대 경로와 달리 상대 경로로 처리된다. 만약 앞에 /를 붙이면, 뷰 리졸버가 이를 잘못 해석할 수 있다.

  • 차이점
    • "user/" + page: 상대 경로를 사용하여 템플릿 파일을 찾습니다.
      예: user/profile → templates/user/profile.html
    • "/user/" + page: 절대 경로로 해석될 수 있어 예상치 못한 문제가 발생할 수 있습니다.

3) 상대 경로로 처리되는 이유

: Spring의 뷰 리졸버는 기본적으로 상대 경로를 이용해 파일을 찾는다. 예를 들어, Thymeleaf를 사용할 경우, 상대 경로로 지정된 템플릿은 src/main/resources/templates 디렉토리 내에서 탐색된다.

  • 예시
    • return "user/profile";의 경우, 기본 경로가 templates/이므로 templates/user/profile.html 파일을 찾습니다.
    • 반면에 return "/user/profile";이라고 하면, 잘못된 경로로 해석될 수 있으며, 애플리케이션 설정에 따라 에러를 발생시킬 가능성이 높습니다.

4) 결론

: "user/" + page와 같은 방식으로 경로를 작성하는 이유는 Spring MVC에서 상대적인 뷰 경로를 사용하기 때문입니다. 맨 앞에 /를 붙이지 않음으로써 Spring이 기본적으로 설정된 템플릿 경로 하에서 파일을 찾을 수 있게 됩니다.


[4] RequestMapping에서 "/user"로 되어 있는데, "user/"이라는걸 추가하는 이유

: @RequestMapping("/user")로 이미 경로를 지정했음에도 불구하고, return "user/" + page;처럼 뷰 경로에 "user/"를 추가하는 이유는 컨트롤러의 요청 경로와 뷰 템플릿 경로가 별개로 처리되기 때문입니다.

1) RequestMapping 경로와 뷰 경로의 차이

: @RequestMapping으로 설정한 경로는 클라이언트가 서버에 요청할 때의 URL 경로를 의미한다.. 예를 들어, @RequestMapping("/user")는 사용자가 브라우저에서 /user 경로로 요청을 보내면 이 컨트롤러가 그 요청을 처리한다는 뜻이다.

: 반면, return으로 반환하는 경로는 뷰 템플릿 파일의 경로이다. 이 경로는 사용자가 요청하는 URL 경로와는 전혀 다른 개념으로, 서버가 클라이언트에게 응답할 때 보여줄 HTML 파일 등의 위치를 가리킨다.

  • @RequestMapping("/user"): /user로 시작하는 URL 요청을 처리.
  • return "user/" + page: 뷰 리졸버가 찾아야 할 템플릿 파일의 경로.

2) 뷰 템플릿 경로의 구조

: Spring에서는 뷰 템플릿 파일들이 보통 특정 디렉토리 구조를 따른다. 예를 들어, Thymeleaf를 사용할 경우, 기본적으로 src/main/resources/templates/ 디렉토리 아래에 템플릿 파일들이 위치한다. 이를 구조화된 방식으로 관리하기 위해, 예를 들어 user와 관련된 템플릿은 templates/user/ 디렉토리 아래에 저장해 관리하는 것이 일반적이다.

그래서 return "user/" + page;처럼 작성하여, 템플릿 경로가 user/profile.html 또는 user/settings.html 같은 형식으로 처리되도록 만든다.

3) 경로를 분리하는 이유

: RequestMapping("/user")와 "user/" + page로 처리하는 뷰 경로는 의도적으로 분리된 관심사이다. 이렇게 하면 URL 경로와 뷰 파일 시스템 경로를 독립적으로 관리할 수 있어 유연성이 커진다.

  • 요청 경로: 클라이언트의 요청을 처리하는 논리적인 URL (e.g., /user/profile)
  • 뷰 경로: 서버가 클라이언트에게 응답할 때 사용하는 HTML 파일 등의 경로 (e.g., templates/user/profile.html)

4) 유지보수성 및 구조화

: 이렇게 구조화하면 프로젝트가 커졌을 때, 예를 들어 사용자 관련 템플릿은 templates/user/ 디렉토리에, 상품 관련 템플릿은 templates/product/ 디렉토리에 각각 관리할 수 있어 코드와 파일이 훨씬 깔끔하고 유지보수가 용이해진다.

5) 요약

  • @RequestMapping("/user")는 URL 요청 경로를 의미하고, 사용자가 /user/...로 요청할 때 이 컨트롤러가 처리한다.
  • return "user/" + page는 뷰 템플릿 파일 경로를 의미하며, user와 관련된 템플릿을 templates/user/ 아래에서 관리하기 위해 사용된다.
  • 이 방식은 경로와 파일을 체계적으로 관리하고 유지보수하기 쉽게 해준다.
profile
안녕하세요, 사용자들의 문제 해결을 중심으로 하는 프론트엔드 개발자입니다. 티스토리로 전환했어요 : https://pangil-log.tistory.com

0개의 댓글