[Spring-MVC] 스프링 MVC - 구조 이해

나영·2023년 7월 26일

Spring-MVC

목록 보기
5/7
post-thumbnail

스프링 MVC 전체 구조

동작 순서는 다음과 같다.

  1. 핸들러 조회 : 핸들러 매핑을 통해 요청 URL 에 매핑된 핸들러 (컨트롤러) 조회
  2. 핸들러 어댑터 조회 : 핸들러를 실행할 수 있는 핸들러 어댑터 조회
  3. 핸들러 어댑터 실행 : 핸들러 어댑터 실행
  4. 핸들러 실행 : 핸들러 어댑터가 실제 핸들러를 실행
  5. ModelAndView 반환 : 핸들러가 반환하는 정보를 ModelAndView로 변환 해서 반환
  6. viewResolver 호출 : 뷰 리졸버를 찾고 실행
  7. View 반환 : 뷰의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할하는 뷰 객체 반환
  8. 뷰 렌더링 : 뷰를 통해 뷰를 렌더링

💡 @RequestMapping

  • RequestMappingHandlerMapping : 가장 우선순위가 높은 핸들러 매핑 (처리할 수 있는 핸들러 꺼내주고)
  • RequestMappingHandlerAdapter : 가장 우선순위가 높은 핸들러 어댑터 (어댑터가 처리)

코드

Spring MVC - 시작하기

SpringMemberFormControllerV1 - 회원 등록 폼

@Controller
public class SpringMemberFormControllerV1 {

    @RequestMapping("/springmvc/v1/members/new-form")
    public ModelAndView process() {
        return new ModelAndView("new-form");
    }

}
  • @Controller
    • 스프링이 자동으로 스프링 빈으로 등록 (내부에 @Component 애노테이션이 있어서 컴포넌트 스캔의 대상이 됨.)
    • 스프링 MVC 에서 애노테이션 기반 컨트롤러로 인식함.
  • @RequestMapping
    • 요청 정보 매핑 (해당 URL 이 호출되면 이 메서드가 호출됨. 메서드 이름은 임의로 지으면 됨.)
  • ModelAndView
    • 모델과 뷰 정보를 담아 반환

SpringMemberFormControllerV1 - 회원 등록 폼

@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;
    }

}
  • mv.addObject("member", member)
    • 스프링이 제공하는 ModelAndView 를 통해 Model 데이터를 추가할 때는 addObject() 를 사용한다. 이 데이터는 이후 뷰를 렌더링할 때 사용.

SpringMemberListControllerV1 - 회원 목록

@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;
    }

}

Spring MVC - 컨트롤러 통합

@RequestMapping 이 메서드 단위에 적용되었으므로 컨트롤러 클래스를 유연하게 하나로 통합해보자.

SpringMemberControllerV2

@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 mav = new ModelAndView("save-result");
        mav.addObject("member", member);
        return mav;
    }

    @RequestMapping
    public ModelAndView members() {
        List<Member> members = memberRepository.findAll();

        ModelAndView mav = new ModelAndView("members");
        mav.addObject("members", members);
        return mav;
    }

}
  • 클래스 레벨에 @RequestMapping("/springmvc/v2/members") 을 추가해 메서드 레벨과의 조합을 한다.

Spring MVC - 실용적인 방식

SpringMemberControllerV3

@Controller
@RequestMapping("/springmvc/v3/members")
public class SpringMemberControllerV3 {
    private MemberRepository memberRepository = MemberRepository.getInstance();

    @RequestMapping("/new-form")
    public String newForm() {
        return "new-form";
    }

    @RequestMapping("/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";
    }

    @RequestMapping
    public String members(Model model) {
        List<Member> members = memberRepository.findAll();

        model.addAttribute("members", members);
        return "members";
    }

}
  • Model 파라미터
    • save(), members() 를 보면 Model을 파라미터로 받는 것을 확인할 수 있다 ! (스프링의 편의 기능)
  • ViewName 직접 반환
    • 뷰의 논리 이름을 반환할 수 있다.
  • @RequestParam 사용
    • HTTP 요청 파라미터를 @RequestParam 으로 받을 수 있다.
    • @RequestParam("username") = request.getParameter("username")
  • @RequestMapping -> @GetMapping, @PostMapping
    • @RequestMapping 은 URL만 매칭하는 것이 아니라, HTTP Method 도 함께 구분할 수 있다 !

0개의 댓글