지난 게시글에서 OldController를 통해 기존의 Controller 동작 방식을 살펴봤었다.
이제 본격적으로 스프링 MVC의 편리한 기능들을 사용할 것이다.
컨트롤러를 작성하는데 키 포인트는 @Controller와 @RequestMapping 이 두 어노테이션이다.
이 두 가지에 대해 간단히 설명하고 코드를 작성하겠다.
@Controller
- 내부에 @Component 어노테이션이 존재해 컴포넌트 스캔의 대상
- 스프링이 자동으로 스프링 빈으로 등록
- 스프링 MVC에서 어노테이션 기반 컨트롤러로 인식하게 함
@RequestMapping
- 요청 정보를 매핑
- 해당 url이 호출되면 해당 메소드가 호출
- 어노테이션 기반 동작이기 때문에 메소드 이름은 자유
+ 핸들러 매핑과 핸들러 어댑터 중 가장 우선순위가 높은 것은 RequestMappingHandlerMapping, RequestMappingHandlerAdapter이다. @RequestMapping의 앞글자를 따서 만들어졌다.
이제 간단한 예제를 만들어보자.
SpringMemberFormControllerV1
@Controller
public class SpringMemberFormControllerV1 {
@RequestMapping("/springmvc/v1/members/new-form")
private ModelAndView process() {
return new ModelAndView("new-form");
}
}
- ModelAndView: 모델, 뷰 정보 담아서 반환
SpringMemberSaveControllerV1
@Controller
public class SpringMemberSaveControllerV1 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/springmvc/v1/members/save")
private ModelAndView process(HttpServletRequest req, HttpServletResponse res) {
String username = req.getParameter("username");
int age = Integer.parseInt(req.getParameter("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelAndView mv = new ModelAndView("save-result");
mv.addObject("member", member);
return mv;
}
}
- addObject(): 스프링이 제공하는 ModelAndView를 통해 Model 데이터 추가시 해당 메소드 사용
- mv는 이후 뷰를 렌더링 할 때 사용
SpringMemberListControllerV1
@Controller
public class SpringMemberListControllerV1 {
MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/springmvc/v1/members")
public ModelAndView process() {
List<Member> members = memberRepository.findAll();
ModelAndView mv = new ModelAndView("members");
mv.getModel().put("members", members);
return mv;
}
}
동작 과정에 대해서는 이전 게시글에서 자세히 설명한게 많으니 생략한다.
코드가 훨씬 간편해진 것이 보이지만 @RequestMapping이 클래스가 아닌 메소드 단위에 적용되어 있다.
컨트롤러 클래스를 좀 더 유연하게 통합해보자.
SpringMemberControllerV2
@Controller
@RequestMapping("/springmvc/v2/members")
public class SpringMemberControllerV2 {
MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/new-form")
private ModelAndView newForm() {
return new ModelAndView("new-form");
}
@RequestMapping
public ModelAndView members() {
List<Member> members = memberRepository.findAll();
ModelAndView mv = new ModelAndView("members");
mv.getModel().put("members", members);
return mv;
}
@RequestMapping("/save")
private ModelAndView save(HttpServletRequest req, HttpServletResponse res) {
String username = req.getParameter("username");
int age = Integer.parseInt(req.getParameter("age"));
Member member = new Member(username, age);
memberRepository.save(member);
ModelAndView mv = new ModelAndView("save-result");
mv.addObject("member", member);
return mv;
}
}
- 클래스 3개로 분리되었던 작업이 단 하나의 파일로 줄어들었다.
- RequestMapping이 클래스에도 붙고 메소드에도 붙는다.
- 위와 같은 경우에 save()를 부르려면 /spingmvc/v2/members/save로 접근하면 된다.
아직 좀 불편한 점이 남아있다.
ModelAndView를 매번 생성하고 반환해주는게 좀 번거롭게 느껴진다.
실무에서 사용하는 것과 가깝게 더 개선해보자.
SpringMemberControllerV3
@Controller
@RequestMapping("/springmvc/v3/members")
public class SpringMemberControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@RequestMapping("/new-form")
private String newForm() {
return "new-form";
}
@RequestMapping
public String members(Model model) {
List<Member> members = memberRepository.findAll();
model.addAttribute("members",members);
return "members";
}
@RequestMapping("/save")
private 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";
}
}
- String 형태로 반환. ModelAndView를 매번 생성하지 않아도 됨.
- @RequestParam: HttpServletRequest가 아니라 파라미터를 직접 받아올 수 있음
위 코드는 POST방식 GET 방식 구분 없이 모두 적용되고 있다.
만약 POST 방식만 사용하고 싶다면 @RequestMapping을 다음과 같이 수정하면 된다.
@RequestMapping(value = "/save", method = RequestMethod.POST)
하지만 개발자들은 여기서 더 간편하게 개발해낸 것이 있다.
@PostMapping("/save")
+ GET 메소드는 @GetMapping이 있다.
@PostMapping 어노테이션을 들어가보면 @RequestMapping이 존재하는 것을 확인할 수 있다.
위와 같이 여러개의 어노테이션을 조합하여 새로운 어노테이션을 생성하는 것이 가능하다.
본 게시글은 김영한 님의 '스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술' 강의를 구매 후 정리하기 위한 포스팅입니다.
내용을 임의로 추가, 수정, 삭제한 부분이 많으며 정확한 이해를 위해서 강의를 구매하시는 것을 추천 드립니다.
'Develop > Spring+JPA' 카테고리의 다른 글
[Spring] 헤더 조회 (0) | 2021.07.14 |
---|---|
[Spring] 요청 매핑 (0) | 2021.06.25 |
[스프링 MVC] 뷰 리졸버 (0) | 2021.05.26 |
[스프링 MVC] 핸들러 매핑, 핸들러 어댑터 (0) | 2021.05.24 |
[스프링 MVC] 스프링 MVC 구조, DispatcherServlet (0) | 2021.05.24 |