우와한 개발자

[Spring] Spring MVC Controller(핸들러) - 어노테이션과 파라미터

by 우와한개발자

[ Spring MVC Controller ]

  • 요청에 따라 수행할 메서드를 선언하고 비즈니스 로직 수행
  • 컨트롤러를 핸들러라고도 부름
  • return "뷰이름" → forward 방식 (기본값)
  • return "redirect:뷰이름" → redirect 방식 (Spring이 문자열 앞의 접두어를 보고 자동으로 특수 처리함)
구분 @Controller @RestController
용도 JSP 등 화면(View) 반환 JSON/XML 데이터 반환
반환값 처리 ViewResolver 거쳐 JSP 렌더링 MessageConverter 거쳐 JSON 변환
@ResponseBody 메서드마다 직접 붙여야 함 클래스 전체에 자동 적용
주 사용 환경 Spring MVC (JSP) REST API
@Controller
public class MemberController {

    @GetMapping("/home")
    public String home(Model model) {
        model.addAttribute("msg", "안녕하세요");
        return "home"; // /WEB-INF/views/home.jsp 로 forward
    }

    @PostMapping("/login")
    public String login(@ModelAttribute User user, HttpSession session) {
        session.setAttribute("loginUser", user.getId());
        return "redirect:/home"; // redirect
    }
}

 

1.  @RequestMapping 계열 어노테이션

  • value 속성 하나만 넣을 경우 "value=" 생략 가능하고 중괄호{}로 URL 여러개 매핑 가능
  • method 속성으로 HTTP 메서드 명시 가능하나 잘 사용하지 않음
  • 경로 설정시 /(슬래시)로 시작하는 절대경로 권장
  • /(슬래시)는 프로젝트의 컨텍스트 루트
  • @RequestMapping 계열 어노테이션이 붙은 메서드는 "핸들러 메서드"라고 부름
어노테이션 설명 스프링 버전
@RequestMapping("경로") 모든 HTTP 메서드 요청 처리 3.x
@GetMapping("경로") GET 요청만 처리 4.3 이상
@PostMapping("경로") POST 요청만 처리 4.3 이상
// method 속성
@RequestMapping(value = "/home", method = RequestMethod.GET)
public String home() {
    return "home";
}

@RequestMapping(value = "/login", method = {RequestMethod.GET, RequestMethod.POST})
public String login() {
    return "login";
}

// URL 여러개 매핑
@RequestMapping(value = {"/home", "/main"})
public String home() {
    return "home";
}

 

2. 핸들러 메서드의 파라미터 주요 어노테이션

어노테이션 / 타입 받는 값 예시
@RequestParam 쿼리스트링, form 파라미터 ?id=1, name=kim
@PathVariable URL 경로 변수 /detail/10
@ModelAttribute 요청 파라미터를 객체로 바인딩 name=kim&age=20 → User
@RequestBody 요청 body 데이터(JSON/XML 등) JSON → User
@RequestHeader HTTP 요청 헤더 값 User-Agent, Authorization
@CookieValue 쿠키 값 JSESSIONID

 

1) @RequestParam

  • 쿼리스트링, form 파라미터 값을 받음
  • required(필수값), defaultValue(기본값) 속성을 지님
  • defaultValue는 항상 쌍따옴표("")로 감싸야 함
  • 요청 파라미터의 키와 메서드 파라미터명이 같으면 생략 가능. (단, String이나 int 같은 단순 타입일 때만 해당)
@GetMapping("/test")
public String test(@RequestParam(value = "id", required = false, defaultValue = "0") int id) {
    return "view";
}

 

2) @PathVariable

  • URL 경로 변수(중괄호{})를 받음
  • @GetMapping의 {} 안의 변수명과 파라미터명이 같으면 value 생략 가능
@GetMapping("/detail/{id}")
public String detail(@PathVariable("id") int id) {
    return "view";
}

 

3) @ModelAttribute

  • 요청 파라미터를 객체로 바인딩
  • Spring이 setter 또는 생성자를 통해 자동으로 값을 주입함.
  • HTML form의 name 속성값과 클래스 필드명이 일치하거나 객체 타입일 때 생략 가능
@PostMapping("/join")
public String join(@ModelAttribute Member member) {
    return "view";
}

 

4) @RequestBody

  • 요청 body의 JSON/XML 데이터를 객체로 변환
  • 주로 REST API에서 JSON 데이터를 받을 때 사용
  • MessageConverter가 자동으로 변환 처리
@PostMapping("/api/join")
public String join(@RequestBody Member member) {
    return "view";
}

 

5) @RequestHeader

  • HTTP 요청 헤더 값을 받음
  • required, defaultValue 속성 사용 가능
@GetMapping("/test")
public String test(@RequestHeader("User-Agent") String userAgent) {
    return "view";
}

 

6) @CookieValue

  • 쿠키 값을 받음
  • required, defaultValue 속성 사용 가능
@GetMapping("/test")
public String test(@CookieValue(value = "JSESSIONID", required = false) String sessionId) {
    return "view";
}

 

3. 핸들러 메서드의 파라미터 타입

  • Spring이 핸들러 메서드 파라미터 타입을 보고 자동으로 주입해줌
타입 의미 예시
HttpServletRequest 요청 전체 객체 URI, 파라미터, 헤더 조회
HttpServletResponse 응답 객체 쿠키 저장, 헤더 설정
Model 뷰로 보낼 데이터 저장 model.addAttribute()
Map, ModelMap 모델 데이터 저장 화면에 값 전달
HttpSession 세션 객체 세션값 사용
RedirectAttributes redirect 시 데이터 전달 addAttribute(), addFlashAttribute()

 

1) HttpServletRequest

  • 요청 전체 객체, URI / 파라미터 / 헤더 조회 가능
@GetMapping("/test")
public String test(HttpServletRequest request) {
    String name = request.getParameter("name");
    return "view";
}

 

2) HttpServletResponse

  • 응답 객체, 쿠키 저장 / 헤더 설정 가능
@GetMapping("/test")
public String test(HttpServletResponse response) {
    response.setHeader("Content-Type", "text/html");
    return "view";
}

 

3) Model / Map / ModelMap

  • 뷰로 보낼 데이터를 저장하는 객체
@GetMapping("/test")
public String test(Model model) {
    model.addAttribute("name", "kim");
    return "view";
}

 

4) HttpSession

  • 세션 객체, 세션 값 저장 및 조회
@GetMapping("/test")
public String test(HttpSession session) {
    session.setAttribute("loginUser", user);
    return "view";
}

 

5) RedirectAttributes

  • redirect 시 데이터 전달
  • addAttribute() : redirect URL 뒤에 쿼리스트링으로 붙어서 전달됨. URL에 노출되고 새로고침해도 유지됨
  • addFlashAttribute() : 세션에 임시 저장했다가 redirect 후 딱 1번 사용되면 자동으로 삭제됨. URL에 노출되지 않음. 주로 "저장 완료", "삭제 완료" 같은 1회성 알림 메시지 전달에 사용
@PostMapping("/join")
public String join(RedirectAttributes rttr) {
    rttr.addFlashAttribute("msg", "가입 완료");
    return "redirect:/home";
}

 

4. 핸들러 메서드의 반환 타입

  • 핸들러 메서드가 String 반환 시에도 Model에 담은 데이터는 자동으로 View까지 전달됨
  • Spring은 컨트롤러 메서드의 반환 타입과 어노테이션을 보고 ViewResolver를 거칠지, 아닐지 판단
반환 타입 / 방식 ViewResolver prefix/suffix 사용 경우
String O O JSP 화면 이동
ModelAndView O O 화면과 데이터 함께 전달
void O O 요청 경로로 View 이름 추론
View O X View 객체 직접 지정
redirect: 으로 시작하는 문자열 O X 다른 URL로 리다이렉트
forward: 으로 시작하는 문자열 O X 다른 URL로 포워드
@ResponseBody + 객체 X X REST API 응답
ResponseEntity<T> X X REST API 응답 + 상태코드/헤더 제어

 

1) String

  • ViewResolver를 거쳐 prefix(예: /WEB-INF/views/)/suffix(예 : .jsp)를 조합해 JSP 화면으로 이동
@GetMapping("/home")
public String home(Model model) {
    model.addAttribute("name", "kim");
    return "home"; // → /WEB-INF/views/home.jsp
}

 

2) ModelAndView

  • 화면 이름과 데이터를 함께 전달
@GetMapping("/home")
public ModelAndView home() {
    ModelAndView mav = new ModelAndView();
    mav.setViewName("home");
    mav.addObject("name", "kim");
    return mav;
}

 

3) void

  • 반환값 없이 요청 경로로 View 이름 추론
@GetMapping("/home")
public void home(Model model) {
    model.addAttribute("name", "kim");
    // 요청 경로 /home → /WEB-INF/views/home.jsp
}

 

4) redirect:으로 시작하는 문자열

  • ViewResolver를 거치지 않고 다른 URL로 리다이렉트
@PostMapping("/join")
public String join() {
    return "redirect:/home";
}

 

5) forward:으로 시작하는 문자열

  • ViewResolver를 거치지 않고 다른 URL로 포워드
@PostMapping("/join")
public String join() {
    return "forward:/home";
}

 

6) @ResponseBody + 객체

  • ViewResolver를 거치지 않고 객체를 JSON으로 변환해 응답
  • 주로 REST API에서 사용
@ResponseBody
@GetMapping("/api/user")
public Member getUser() {
    return new Member("kim", 20);
}

 

7) ResponseEntity<T>

  • REST API 응답 + 상태코드 / 헤더까지 직접 제어 가능
@GetMapping("/api/user")
public ResponseEntity<Member> getUser() {
    Member member = new Member("kim", 20);
    return ResponseEntity.ok(member); // 200 OK
}

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기