[MVC 프레임워크 구조]
FrontController → DispatcherServlet
handlerMappingMap → HandlerMapping
MyHandlerAdapter → HandlerAdapter
ModelView → ModelAndView
viewResolver → ViewResolver
MyView → View
1. 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
2. 핸들러 어댑터 조회: 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
3. 핸들러 어댑터 실행: 핸들러 어댑터를 실행한다.
4. 핸들러 실행: 핸들러 어댑터가 실제 핸들러를 실행한다.
5. ModelAndView 반환: 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환한다.
6. viewResolver 호출: 뷰 리졸버를 찾고 실행한다. JSP의 경우: InternalResourceViewResolver 가 자동 등록되고, 사용
7. View 반환: 뷰 리졸버는 뷰의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할을 담당하는 뷰 객체를 반환.
8. 뷰 렌더링: 뷰를 통해서 뷰를 렌더링
[DispatcherServlet]
스프링 부트는 DispacherServlet 을 서블릿으로 자동으로 등록. 모든 경로( urlPatterns="/" )에 대해서 매핑.
DispatcherServlet 의 부모인 FrameworkServlet 에서 service() 를 오버라이드.
FrameworkServlet.service() 를 시작으로 여러 메서드가 호출되면서 DispacherServlet.doDispatch() 가 호출.
서블릿이 호출되면 HttpServet이 제공하는 service()호출→
[doDispatch]
1.핸들러 조회
2.핸들러 어댑터 찾고
3.핸들러 어댑터 실행을 하면 4.핸들러 어댑터를 통해 핸들러 실행
5.ModelAndView 반환
6.뷰 리졸버로 뷰 찾기 7.뷰 반환
8.뷰 렌더링
<과거 버전 스프링 컨트롤러>
@Component("/springmvc/old-controller")
public class OldContoroller implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("OldController.handleRequest");
return new ModelAndView("new-form"); }
}
스프링빈 이름을 url로 맞춤
1. 핸들러 매핑으로 핸들러 조회
2. 핸들러 어댑터 조회
3. 핸들러 어댑터 실행
OR <HttpRequestHandler>
public class MyHttpRequestHandler implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("MyHttpRequestHandler.handleRequest");
}
}
[뷰 리졸버]
<application.properties>에 spring.mvc.view.prefix=/WEB-INF/views/ spring.mvc.view.suffix=.jsp 추가
1. 핸들러 어댑터 호출 핸들러 어댑터를 통해 new-form 이라는 논리 뷰 이름을 획득
2. ViewResolver 호출 new-form 이라는 뷰 이름으로 viewResolver를 순서대로 호출한다. BeanNameViewResolver 는 new-form 이라는 이름의 스프링 빈으로 등록된 뷰를 찾아야 하는데 없다. InternalResourceViewResolver 가 호출된다.
3. InternalResourceViewResolver 이 뷰 리졸버는 InternalResourceView 를 반환한다.
4. 뷰 - InternalResourceView InternalResourceView 는 JSP처럼 포워드 forward() 를 호출해서 처리할 수 있는 경우에 사용
5. view.render() view.render() 가 호출되고 InternalResourceView 는 forward() 를 사용해서 JSP를 실행
[@RequestMapping]
이 어노테이션이 있으면 RequestMappingHandlerMapping과 RequestMappingHandlerAdaptor이 사용됨
@Controller 가 돼있으면 → 그림1의 RequestMappingHandlerMapping가 핸들러를 꺼내주고, 2,3번의 RequestMappingHandlerAdaptor는 핸들러매핑이 준애를 처리할 수 있음
<SpringMemberFormControllerV1> - 회원 등록 폼
//@Controller를 사용하거나 밑에 구대를 같이 사용하거나
@Component
@RequestMapping
public class SpringMemberFormControllerV1 {
@RequestMapping("/springmvc/v1/members/new-form")
public ModelAndView process() {
return new ModelAndView("new-form");
}
}
*@Controller :
1. 스프링이 자동으로 스프링 빈으로 등록 (내부에 @Component 애노테이션이 있어서 컴포넌트 스캔의 대상이 됨)
2. 스프링 MVC에서 애노테이션 기반 컨트롤러로 인식 (RequestMappingHandlerMapping 은 스프링 빈 중에서 @RequestMapping 또는 @Controller 가 클래스 레벨에 붙어 있는 경우에 매핑 정보로 인식).
*@RequestMapping : 요청 정보를 매핑한다. 해당 URL이 호출되면 이 메서드가 호출된다. 애노테이션을 기반으로 동작(RequestMappingHandlerMapping 은 스프링 빈 중에서 @RequestMapping 또는 @Controller 가 클래스 레벨에 붙어 있는 경우에 매핑 정보로 인식)
*ModelAndView : 모델과 뷰 정보를 담아서 반환하면 된다
물론 컴포넌스 스캔 없이 다음과 같이 스프링 빈으로 직접 등록.
@RequestMapping public class SpringMemberFormControllerV1 { @RequestMapping("/springmvc/v1/members/new-form") public ModelAndView process() { return new ModelAndView("new-form"); } }
+
ServletApplication //스프링 빈 직접 등록
@Bean TestController testController() { return new TestController(); }
<SpringMemberSaveControllerV1> - 회원 저장
@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);
System.out.println("member = " + member);
memberRepository.save(member);
ModelAndView mv = new ModelAndView("save-result");
mv.addObject("member", member);
return mv;
}
}
<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;
}
}
[컨트롤러 통합]
<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;
}
}
[어노테이션 기반 spring] v3->v4, 인터페이스반환해도 되고 문자를 반화해도 되고
<SpringMemberControllerV3>
/**
* v3
* Model 도입
* ViewName 직접 반환
* @RequestParam 사용
* @RequestMapping -> @GetMapping, @PostMapping
*/
@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";
}
}
'Spring 강의 > springMVC' 카테고리의 다른 글
springMVC 활용 - (8) HTTP응답 (0) | 2022.05.12 |
---|---|
springMVC 활용 - (7) 스프링 기능 (0) | 2022.05.11 |
springMVC 활용 - (5) mvc 프레임워크 만들기 (0) | 2022.04.13 |
springMVC 활용 - (4) 회원관리 웹 애플리케이션 (0) | 2022.03.26 |
springMVC 활용 - (2) 서블릿 & Request (0) | 2022.03.26 |