이 글은 Velog에서 이전한 글입니다. Velog 원문 보기
*스프링이 제공하는 컨트롤러는 애노테이션 기반으로 동작해서, 매우 유연하고 실용적이다. *
@RequestMapping
스프링은 애노테이션을 활용한 매우 유연하고, 실용적인 컨트롤러를 만들었는데 이것이 바로@RequestMapping애노테이션을 사용하는 컨트롤러이다.
RequestMappingHandlerMappingRequestMappingHandlerAdapter
@ReqeustMapping 기반의 스프링 MVC Controller를 작성하면서 V1부터 V3까지 개선하는 과정을 작성해보려고 한다.
📌 V1 - 개선 전
✔︎ SpringMemberFormControllerV1 - 회원 등록 폼
package hello.servlet.web.springmvc.v1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class SpringMemberFormControllerV1 {
@RequestMapping("/springmvc/v1/members/new-form")
public ModelAndView process() {
return new ModelAndView("new-form");
}
}
@Controller
- 내부에
@Component애노테이션이 있어서 스프링이 자동으로스프링 빈으로 등록한다. Spring MVC에서 애노테이션 기반Controller로 인식한다.
RequestMappingHandlerMapping은 스프링 빈 중에서@RequestMappingor@Controller가 클래스 레벨에 붙어 있는 경우매핑 정보로 인식한다.
그러므로 다음 코드도 동일하게 동작한다.
package hello.servlet.web.springmvc.v1;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
@Component //Component Scan을 통해 스프링 빈으로 등록
@RequestMapping
public class SpringMemberFormControllerV1 {
@RequestMapping("/springmvc/v1/members/new-form")
public ModelAndView process() {
return new ModelAndView("new-form");
}
}
- - -
### ✔︎ SpringMemberSaveControllerV1 - 회원 저장
```java
package hello.servlet.web.springmvc.v1;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.ModelView;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
import java.util.Map;
@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;
}
}
mv.addObject("member", member)
- 스프링이 제공하는
ModelAndView를 통해Model데이터를 추가할 때는addObject()를 사용하면 된다. 이 데이터는 이후View를 렌더링 할 때 사용된다.
✔︎ SpringMemberListControllerV1 - 회원 목록
package hello.servlet.web.springmvc.v1;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.ModelView;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
@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;
}
}
V1은 각
Controller가 따로 분리되어 있어 한 눈에 파악하기가 어렵다. V2에서는 이 부분을개선해보겠다.
📌 V2 - 컨트롤러 통합
V1의 각
Controller의@RequestMapping를 보면 클래스 단위가 아닌메서드 단위에 적용되어 있다. 그러므로Controller Class를 유연하게 하나로통합할 수 있다.
package hello.servlet.web.springmvc.v2;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@Controller
@RequestMapping("/springmvc/v2/members")
public class SpringMemberControllerV2 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/new-form")
public ModelAndView newForm() {
return new ModelAndView("new-form");
}
@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;
}
@RequestMapping
public ModelAndView members() {
List<Member> members = memberRepository.findAll();
ModelAndView mv = new ModelAndView("members");
mv.addObject("members", members);
return mv;
}
}
클래스 단위에 @RequestMapping("/springmvc/v2/members")를 작성함으로서 중복되는 부분도 제거하였다. 그런데 여전히 개발자가 ModelView를 직접 생성해서 반환해야 한다는 불편한 부분이 존재한다. 개선할 방법이 없을까?
📌 V3 - 실용적인 방식
package hello.servlet.web.springmvc.v3;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@Controller
@RequestMapping("/springmvc/v3/members")
public class SpringMemberControllerV3 {
private 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";
}
}
V3에서는 V2의 불편한 부분을 개선하기 위해 다음과 같은 기능을 추가했다.
Model도입- 각 메소드가
ModelAndView객체가 아닌ViewName를 직접 반환 @GetMapping,PostMapping사용
Model 파라미터
save(),members()를 보면Model을 파라미터로 받는 것을 확인할 수 있다. Spring MVC도 이런 편의 기능을 제공한다.
ViewName 직접 반환
View의 논리 이름을 반환할 수 있다.
@GetMapping, @PostMapping
@GetMapping과@PostMapping은 다음 코드의 간략화 버전이다.@RequestMapping(value="/...", method = RequestMethod.Get) @RequestMapping(value="/...", method = RequestMethod.Post) //@RequestMapping은 URL만 매칭하는 것이 아니라, HTTP Method도 함께 구분할 수 있다.
'Backend > Spring MVC' 카테고리의 다른 글
| ✏️ 요청 매핑 (0) | 2026.07.18 |
|---|---|
| ✏️ Logging (0) | 2026.07.18 |
| ✏️ Front Controller 패턴, Adapter 패턴 (0) | 2026.07.18 |
| ✏️ MVC 패턴 (0) | 2026.07.18 |
| ✏️ HttpServlet 요청과 응답 (0) | 2026.07.18 |