스프링 MVC 구조 이해
1. 스프링 MVC 전체 구조
스프링 MVC의 전체 구조는 기존에 서블릿으로 구현해봤던 MVC패턴과 같다.
[스프링 MVC 구조]
스프링 MVC에서 프론트 컨트롤러 역할은 DispatcherServlet이 담당한다.
스프링 MVC의 큰 강점은 DispatcherServlet 코드의 변경 없이, 원하는 기능을 변경하거나 확장할 수 있다는 점이다.
아래와 같은 주요 인터페이스만 구현해서 DispatcherServlet에 등록하면 나만의 컨트롤러도 만들 수 있다.
· 주요 인터페이스 목록
- 핸들러 매핑 : org.springframework.web.servlet.HandlerMapping
- 핸들러 어댑터 : org.springframework.web.servlet.HandlerAdapter
- 뷰 리졸버 : org.springframework.web.servlet.ViewResolver
- 뷰 : org.springframework.web.servlet.View
2. 핸들러 매핑과 핸들러 어댑터, 뷰 리졸버
스프링에는 필요한 핸들러 매핑과 핸들러 어댑터, 그리고 뷰 리졸버가 대부분 구현되어 있다.
스프링 부트가 자동 등록하는 핸들러 매핑과 핸들러 어댑터, 뷰 리졸버는 아래와 같다.
■ HandlerMapping
· RequestMappingHandlerMapping : 애노테이션 기반의 컨트롤러인 @RequestMapping에 사용
· BeanNameUrlHandlerMapping : 스프링 빈의 이름으로 핸들러를 찾는다.
순서대로 매핑 우선순위가 높다.
■ HandlerAdapter
· RequestMappingHandlerAdapter : 애노테이션 기반의 컨트롤러인 @RequestMapping에 사용
· HttpRequesetHandlerAdapter : HttpRequestHandler 처리
· SimpleControllerHandlerAdapter : 스프링 구 버전 Controller 인터페이스 처리
순서대로 핸들러 조회 우선순위가 높다.
■ ViewResolver
· BeanNameViewResolver : 빈 이름으로 뷰를 찾아서 반환한다.
· InternalResourceViewResolver : JSP를 처리할 수 있는 뷰를 반환.
- application.properties에 등록한 spring.mvc.view.prefix와 spring.mvc.view.suffix 설정 정보를 사용해 자동 등록
- application.properties에 경로와 확장자 설정해줘야 함
[JSP 뷰 리졸버 설정 예제]
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
3. 스프링 MVC 시작
■ @RequestMapping
애노테이션 기반의 컨트롤러를 사용할 때 쓰이는 애노테이션이다.
스프링에서 가장 우선순위가 높은 핸들러 매핑과 핸들러 어댑터인 RequestMappingHandlerMapping과 RequestMappingHandlerAdapter를 사용한다.
@RequestMapping을 사용해서 컨트롤러를 만들어 보자.
[회원 등록 폼 - 스프링 MVC]
@Controller
public class SpringMemberFormControllerV1 {
@RequestMapping("/springmvc/v1/members/new-form")
public ModelAndView process() {
return new ModelAndView("new-form");
}
}
· @Controller
- 스프링이 자동으로 스프링 빈으로 등록한다.
- 스프링 MVC에서 애노테이션 기반 컨트롤러로 인식한다.
· @RequestMapping
- 요청 정보를 매핑한다.
- 해당 URL이 호출되면 결과적으로 해당 메서드가 호출된다.
model과 View의 논리 이름이 저장된 ModelAndView를 반환 한다.
RequestMappingHandlerMapping은 스프링 빈 중에서 @RequestMapping 또는 @Controller가 클래스 레벨에 붙어 있는 경우에 매핑 정보로 인식한다.
@Controller을 사용하지 않고 직접 스프링 빈에 등록해도 된다. 단, 클래스 레벨에 @RequestMapping을 붙여주어야 매핑이 가능하다.
[회원 저장 폼 - 스프링 MVC]
@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;
}
}
스프링이 제공하는 ModelAndView를 통해 model 데이터를 추가할 때는 addObject()를 사용하면 된다.
4. 컨트롤러 통합
매핑 정보를 제공하는 @RequestMapping은 클래스 단위가 아니라 메서드 단위에 적용된다.
따라서 컨트롤러 클래스를 유연하게 하나로 통합 할 수 있다.
[통합 컨트롤러 - 스프링 MVC]
@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으로 상위 경로를 통합해서 나타낼 수 있다.
5. 실용적 방식의 컨트롤러
앞의 스프링을 사용한 컨트롤러는 ModelAndView를 직접 생성해야한다.
또한 서블릿으로 요청파라미터를 일일히 가공해야하는 불편함이 있다.
스프링 MVC는 개발자가 편리하게 개발할 수 있도록 수 많은 편의 기능을 제공한다.
[실용적인 컨트롤러 - 스프링 MVC]
@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, @PostMapping
- URL 매칭 뿐 아니라 HTTP Method도 함께 구분할 수 있다.
· Model 파라미터
- ModelAndView를 반환하지 않고 Model을 매개변수로 받아 사용할 수 있고 View의 논리 이름을 반환한다.
· @RequestParam
- HTTP 요청 파라미터를 @RequestParam으로 받을 수 있다.
- @RequestParam("username")은 request.getParameter("username")과 거의 같은 코드라고 생각하면 된다.
- GET 쿼리 파라미터, POST Form 방식 모두 지원한다.
'Spring > 스프링 MVC 기본' 카테고리의 다른 글
#7 스프링 MVC - 웹 페이지 만들기 (0) | 2021.07.08 |
---|---|
#6 스프링 MVC 기본 기능 (0) | 2021.07.07 |
#4 MVC 프레임워크 (0) | 2021.06.29 |
#3 JSP & MVC 패턴 적용 (0) | 2021.06.28 |
#2 서블릿 (0) | 2021.06.23 |
댓글