@RequestMapping https://onepunchprogram.tistory.com/89 참고 가장 우선순위가 높은 핸들러 매핑과 핸들러 어댑터는 RequestMappingHandlerMapping RequestMappingHandlerAdapter이다. `@RequestMapping` 의 앞글자를 따서 만든 이름인데, 이것이 바로 지금 스프링에서 주로 사용하는 애노테이션 기반의 컨트롤러를 지원하는 핸들러 매핑과 어댑터이다. 실무에서는 99.9% 이 방식의 컨트롤러를 사용한다.
회원 등록 폼
@Controller
public class SpringMemberFormControllerV1 {
@RequestMapping("/springmvc/v1/members/new-form")
public ModelAndView process(){
return new ModelAndView("new-form");
}
}
1. @Controller: - @Controller 애노테이션은 Spring의 컴포넌트 스캔을 통해 해당 클래스를 스프링 빈으로 등록한다. - 주로 MVC 패턴에서 컨트롤러로 사용되는 클래스에 붙인다. - 스프링 빈으로 등록된 후, 이 클래스는 요청을 처리하는 메소드들을 포함하게 된다.
2. @RequestMapping: - @RequestMapping 애노테이션은 클래스나 메소드에 붙여서 특정 URL 패턴을 해당 클래스나 메소드와 매핑한다. - 클래스 레벨에 붙으면, 해당 클래스 내의 모든 메소드에 공통적으로 적용되는 URL 패턴을 정의한다. - 메소드 레벨에 붙으면, 특정 HTTP 요청을 처리하기 위해 URL 패턴을 정의한다.
3. RequestMappingHandlerMapping: - 스프링의 핵심 컴포넌트 중 하나로, 핸들러 매핑 정보를 관리한다. - 애플리케이션 컨텍스트에서 스캔한 모든 스프링 빈 중 @RequestMapping이나 @Controller가 클래스 레벨에 붙어 있는 경우, 이 정보를 기반으로 요청 URL과 실제 처리 메소드를 매핑한다. - 특정 URL 패턴에 대해 어떤 컨트롤러의 메소드가 호출될지를 결정하는 역할을 한다.
4. ModelAndView: - ModelAndView는 Spring MVC에서 데이터와 뷰 정보를 함께 전달하기 위해 사용하는 객체이다. - 모델(Model)에는 뷰로 전달할 데이터가 포함되고, 뷰(View)는 데이터를 표시할 템플릿 이름을 포함한다. - 컨트롤러 메소드에서 ModelAndView 객체를 반환하면, Spring MVC는 모델 데이터를 설정하고 지정된 뷰를 사용하여 응답을 생성한다.
전체 흐름 설명: 1. 스프링 빈 등록: - @Controller 애노테이션이 붙은 클래스는 스프링의 컴포넌트 스캔에 의해 자동으로 스프링 빈으로 등록된다.
2. 매핑 정보 인식: - RequestMappingHandlerMapping은 스프링 컨텍스트 내에서 @Controller 또는 @RequestMapping이 붙은 클래스를 찾아 해당 클래스를 처리할 수 있는 메소드와 URL 패턴을 매핑 정보로 인식한다.
3. 요청 처리: - 클라이언트가 특정 URL로 HTTP 요청을 보내면, DispatcherServlet은 RequestMappingHandlerMapping을 사용해 해당 URL에 매핑된 컨트롤러 메소드를 찾고, 그 메소드를 호출하여 요청을 처리한다.
회원 저장
@Controller
public class SpringMemberSaveControllerV1 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/springmvc/v1/members/save")
public ModelAndView process(HttpServletRequest request ,HttpServletResponse response) {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelAndView mv = new ModelAndView("save-result");
mv.addObject("member", member);
return mv;
}
}
회원 목록 조회
@Controller
public class SpringMemberListControllerV1 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/springmvc/v1/members")
public ModelAndView process() {
List<Member> members = memberRepository.findAll();
ModelAndView mv = new ModelAndView("members");
mv.addObject("members", members);
return mv;
}
}
모든 코드가 같은 방식으로 만들어진 것을 알 수 있다.
스프링 MVC - 컨트롤러 통합
@RequestMapping을 잘 보면 클래스 단위가 아니라 메서드 단위에 적용된 것을 확인할 수 있다. 따라서 컨트롤러 클 래스를 유연하게 하나로 통합할 수 있다.
@Controller
@RequestMapping("/springmvc/v2/members") // v1 경로 중복 제거
public class SpringMemberControllerV2 {
MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/new-form")
public ModelAndView newForm(){
return new ModelAndView("new-form");
}
@RequestMapping
public ModelAndView members() {
List<Member> members = memberRepository.findAll();
ModelAndView mv = new ModelAndView("members");
mv.addObject("members", members);
return mv;
}
@RequestMapping("/save")
public ModelAndView save(HttpServletRequest request , HttpServletResponse response) {
String username = request.getParameter("username");
int age = Integer.parseInt(request.getParameter("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelAndView mv = new ModelAndView("save-result");
mv.addObject("member", member);
return mv;
}
}
스프링 MVC - 실용적인 방식
/**
* v3
* Model 도입
* ViewName 직접 반환
* @RequestParam 사용
* @RequestMapping -> @GetMapping, @PostMapping */
@Controller
@RequestMapping(value = "/springmvc/v3/members")
public class SpringMemberControllerV3 {
MemberRepository memberRepository = MemberRepository.getInstance();
@GetMapping("/new-form")
public String newForm(){
return "new-form";
}
@PostMapping("/save")
public String save(
@RequestParam("username") String username,
@RequestParam("age") int age,
Model model) {
Member member = new Member(username,age);
memberRepository.save(member);
model.addAttribute("member",member);
return "save-result";
}
@GetMapping
public String members(Model model) {
List<Member> members = memberRepository.findAll();
model.addAttribute("members",members);
return "members";
}
}
SpringMemberControllerV2 방식
특징:
@RequestMapping 애노테이션을 사용하여 모든 HTTP 메소드(GET, POST 등)를 처리할 수 있는 멀티 메소드 매핑을 한다.
ModelAndView 객체를 사용하여 뷰와 모델을 함께 처리한다.
HttpServletRequest 객체를 통해 요청 파라미터를 직접 추출하고 처리한다.
SpringMemberControllerV3 방식
특징:
@GetMapping과 @PostMapping 애노테이션을 사용하여 각각 GET과 POST 요청을 명시적으로 처리한다.
반환 타입으로 뷰 이름을 직접 반환하고, Model 객체를 통해 모델 데이터를 설정한다.
@RequestParam 애노테이션을 사용하여 메소드 파라미터로 직접 요청 파라미터를 바인딩한다.
비교 정리
요청 매핑 방식:
V2: @RequestMapping을 사용하여 모든 HTTP 메소드에 대한 요청을 처리한다.
V3: @GetMapping과 @PostMapping을 사용하여 HTTP 메소드별로 명시적으로 처리한다.
모델과 뷰 처리 방식:
V2: ModelAndView 객체를 사용하여 뷰와 모델을 함께 처리한다.
V3: 반환 타입으로 뷰 이름을 직접 반환하고, Model 객체를 통해 모델 데이터를 설정한다.
요청 파라미터 처리:
V2: HttpServletRequest 객체를 통해 요청 파라미터를 직접 추출한다.
V3: @RequestParam 애노테이션을 사용하여 메소드 파라미터로 직접 요청 파라미터를 바인딩한다.