본문 바로가기
Develop/Spring+JPA

[스프링 MVC] @Controller, @RequestMapping

by 연로그 2021. 5. 27.
반응형

지난 게시글에서 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편 - 백엔드 웹 개발 핵심 기술' 강의를 구매 후 정리하기 위한 포스팅입니다.

내용을 임의로 추가, 수정, 삭제한 부분이 많으며 정확한 이해를 위해서 강의를 구매하시는 것을 추천 드립니다.

 

inf.run/B756

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., 원

www.inflearn.com

 

반응형