일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- MVC
- 유연한 컨트롤러1 - v5
- n+1
- spring MVC
- Testcode
- java.lang.AssertionError
- 인터셉터의 정의
- 세션vs쿠키
- SpringMVC
- optional
- controller
- filter vs interceptor
- @Controller
- 필터vs인터셉터
- 쿠키란
- 김영한
- spring
- .orelseThrow
- application-properties
- jpa
- Validation
- 필터의 정의
- 401오류
- springSecurityFilterChain 오류
- BindingResult
- 쿠키의 정의
- 구글 보안 api 활용
- 세션의 정의
- abap value in field Data Class error
- 세션이란
- Today
- Total
ABAP DUMP ERROR 24시
Spring Boot의 Handler의 과정 본문
# 인프런 김영한의 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술을 개인적으로 정리한 글입니다.
정리
1. @RequestMapping 왜써?
Spring boot는 HanlderMapping과 HandlerAdapter를 탑재하고있어
HandlerMapping과 HandlerAdapter를 구현하기위해서 사용해!
HandlerMapping 과 HanlderAdapter는 RequestMappingHandlerxxx 시리즈를 가장 먼저 탐색하는데
@RequestMapping이 RequestMappingHandlerxxx 시리즈를 가지고 있어!
(핸들러 기능과 아답터 기능을 보유)
2. @Controller는 왜 사용할까?
Spring boot는 ViewResolver를 탑재하고있어
저기 viewResolver 보이지?
1순위로 BeanNameViewResolver를 찾는데
@Controller는 @component를 포함하고 있어서 Bean을 스프링 부트가 관리하게 도와주는 역할을 하거든!
그래서 사용하는거야.
Bean을 등록해서 빈 이름으로 뷰를 찾아서 반환시키기 위함이지!
살펴보기
과거 이렇게 일일히 작성했던 코드들...
@WebServlet(name = "frontControllerServletV5", urlPatterns = "/front-controller/v5/*")
public class FrontControllerServletV5 extends HttpServlet {
private final Map<String, Object> handlerMappingMap = new HashMap<>();
private final List<MyHandlerAdapter> handlerAdapters = new ArrayList<>();
public FrontControllerServletV5() {
initHandlerMappingMap(); // 핸들러 매핑 초기화
initHandlerAdapters(); // 어댑터 초기화
}
private void initHandlerMappingMap() {
handlerMappingMap.put("/front-controller/v5/v3/members/new-form", new MemberFormControllerV3());
handlerMappingMap.put("/front-controller/v5/v3/members/save", new MemberSaveControllerV3());
handlerMappingMap.put("/front-controller/v5/v3/members", new MemberListControllerV3());
handlerMappingMap.put("/front-controller/v4/members/new-form", new MemberFormControllerV4());
handlerMappingMap.put("/front-controller/v4/members/save", new MemberSaveControllerV4());
handlerMappingMap.put("/front-controller/v4/members", new MemberListControllerV4());
}
private void initHandlerAdapters() {
handlerAdapters.add(new ControllerV3HandlerAdapter()); //ControllerV3 아답터 탑재
handlerAdapters.add(new ControllerV4HandlerAdapter()); // ControllerV4 아답터 탑재
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object handler = getHandler(request); // handler 조회
if (handler == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
MyHandlerAdapter adapter = getHandlerAdapter(handler); // 핸들러 처리할수 있는 핸들러 아답터 조회 + 핸들러 호출
ModelView mv = adapter.handle(request, response, handler); // 호출된 handler를 ModelView로 반환
MyView view = viewResolver(mv.getViewName()); //viewResolver를 호출 후 Myview를 반환
view.render(mv.getModel(), request, response); // myview에서 HTML 응답.
}
// Handler 조회
private Object getHandler(HttpServletRequest request) {
String requestURI = request.getRequestURI();
System.out.println("requestURI = " + requestURI);
return handlerMappingMap.get(requestURI);
}
private MyHandlerAdapter getHandlerAdapter(Object handler) {
for (MyHandlerAdapter adapter : handlerAdapters) {
if (adapter.supports(handler)) {
return adapter;
}
}
throw new IllegalArgumentException("handler adapter를 찾을 수 없습니다. handler=" + handler);
}
private MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
}

다음과 같이 간편하게 바뀌었다.
package hello.servlet.web.springmvc.v3;
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
@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);
return "members";
}
}
기본 JAVA로 Handler 를 호출하고
Adapter를 호출하고
따로 dispater를 만들어서 FrontController의 역할을 하던
복잡했던 코드가.
@Controller , @RequestMapping , @RequestParam 이라는 어노테이션들로 간단히 압축되어 나타난다.
어떻게 이렇게 간편하게 바뀔수 있었을까?
오늘 주목할점은 Spring Boot의 Handler의 과정이다.
옛 코드와 같이 HandlerMapping 과 HandlerAdapter의 기능들은 Spring boot에서 지원한다.
HandlerMapping 과 HandlerAdatper를 사용하기 위해서는
RequestMappingHandlerMapping , RequestMappingHandlerAdapter
가 필요한데
그 기능을 @RequestMapping이 가지고 있다.
HandlerMapping과 HandlerMapping을 구현하기위해서는
@RequestMapping이라는 어노테이션을 통해 사용하자.
이렇게 처리한 Mapping된 정보들을 ViewResolver로 보내게 되는데...
이때 1순위는 Bean을 통해 추출하므로
@Controller를 통해 스프링이 자동으로 스프링 빈으로 등록하게 도와준다.
'[WEB]Back-end > Spring MVC' 카테고리의 다른 글
스프링 서버에서 요청 데이터 만들기 (0) | 2022.02.16 |
---|---|
스프링 서버에서 응답 데이터 만들기 (0) | 2022.02.16 |
@RestController vs @Controller 간단 정리 (0) | 2022.02.13 |
Java 로 SpringMVC 기능 구현하기. Try First (0) | 2022.02.12 |
GET URL 쿼리 파라미터, POST HTML Form 형식 비교 (0) | 2022.02.07 |