일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 김영한
- controller
- 세션이란
- 세션vs쿠키
- jpa
- BindingResult
- SpringMVC
- 쿠키의 정의
- 구글 보안 api 활용
- application-properties
- java.lang.AssertionError
- Testcode
- springSecurityFilterChain 오류
- 인터셉터의 정의
- MVC
- .orelseThrow
- Validation
- 401오류
- @Controller
- 세션의 정의
- spring
- filter vs interceptor
- 필터의 정의
- spring MVC
- 쿠키란
- n+1
- 필터vs인터셉터
- abap value in field Data Class error
- optional
- 유연한 컨트롤러1 - v5
- Today
- Total
ABAP DUMP ERROR 24시
Java 로 SpringMVC 기능 구현하기. Try First 본문
# 인프런 김영한의 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술을 개인적으로 정리한 글입니다.
과정
0. 클라이언트로 HTTP요청이 온다.
1. FrontController에서 고객의 Need를 어떤 Handler를 사용해서 제공해야하는지 조회해본다.
3. 핸들러를 처리할수 있는 핸들러 어댑터를 조회한다.
4. 핸들러 어댑터를 가져온다.
5. 핸들러 어댑터에서 핸들러의 정보를 가져온다. == 핸들러를 호출한다.(v3 와 v4 handler를 Adapter가 가져올것이다)
6. 핸들러의 정보들을 ModelView 형식으로 반환한다.
7. viewResolver에서 완성된 MyView를 반환한다.
8. MyView에서 반환된 정보에 render 함수를 이용하여 HTML을 반환한다.

머릿속에 잘 들어 오지 않아 다음 코드를
수십번 같은 코드를 반복학습하였다.
1. viewName, String과 Object를 받는 model을 생성 하는 객체 ModelView 만들기
public class ModelView {
private String viewName;
private Map<String, Object> model = new HashMap<>();
public ModelView(String viewName) {
this.viewName = viewName;
}
public String getViewName() {
return viewName;
}
public void setViewName(String viewName) {
this.viewName = viewName;
}
public Map<String, Object> getModel() {
return model;
}
public void setModel(Map<String, Object> model) {
this.model = model;
}
}
2. 클라이언트에게 HYML을 응답해주는 객체 MyView 만들기 // ModelView의 DATA를 활용
public class MyView {
private String viewPath;
public MyView(String viewPath) {
this.viewPath = viewPath;
}
public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
}
public void render(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
modelToRequestAttribute(model, request);
RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
dispatcher.forward(request,response);
}
private void modelToRequestAttribute(Map<String, Object> model, HttpServletRequest request) {
model.forEach((key, value) -> request.setAttribute(key, value));
}
}
3. ModelView로 paramMap을 반환하는 interface ControllerV3 추가하기.
package hello.servlet.web.frontcontroller.v3;
import hello.servlet.web.frontcontroller.ModelView;
import java.util.Map;
public interface ControllerV3 {
ModelView process(Map<String, String> paramMap);
}
4.ModelView로 paramMap과 Model을 반환하는 interface ControllerV4 추가하기.
public interface ControllerV4 {
/**
*
* @param paramMap
* @param model
* @return viewname
*/
String process(Map<String,String> paramMap, Map<String, Object> model);
}
5. supports 라는 기능, handle이라는 기능을 지원하는데 Modelview로 반환시켜주라는
interface MyHandlerAdapter
public interface MyHandlerAdapter {
boolean supports(Object handler);
ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException , IOException;
}
6.ControllerV3를 적용할수 있는 HandlerAdapter 만들기.
public class ControllerV3HandlerAdapter implements MyHandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof ControllerV3);
} //이코드가 ControllerV3를 포함하고 있어? Yes or No 반환해
@Override
public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler){
ControllerV3 controller = (ControllerV3) handler; // handler가 V3를 Casting 받아.
Map<String, String> paramMap = createParamMap(request); //request에서 파라미터 정보를 받아서
// paramMap으로 전달.
ModelView mv = controller.process(paramMap); // /ModelView로 paramMap에 전달된 내용들을 반환시켜 보내.
return mv;
}
//HttpServletRequest에서 파라미터 정보를 꺼내서 Map으로 변환한다.
// 그리고 해당 Map( paramMap )을 컨트롤러에 전달하면서 호출한다.
private Map<String, String> createParamMap(HttpServletRequest request){
Map<String , String> paramMap = new HashMap<>();
request.getParameterNames().asIterator()
.forEachRemaining(paramName -> paramMap.put(paramName, request.getParameter(paramName)));
return paramMap;
}
}
7.ControllerV4를 적용할수 있는 HandlerAdapter 만들기.
public class ControllerV4HandlerAdapter implements MyHandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof ControllerV4);
}
@Override
public ModelView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
ControllerV4 controller = (ControllerV4) handler; // handler가 V4를 Casting 받아.
Map<String , String> paramMap = createParamMap(request);//request에서 파라미터 정보를 받아서
// paramMap으로 전달.
HashMap<String, Object> model = new HashMap<>(); //Model 정보를 받을 HashMap생성
String viewName = controller.process(paramMap, model);// viewName을 paramMap과 model을 통해서 값을 받음 // 여기서 model은 빈 값
ModelView mv = new ModelView(viewName); // viewName을 가지고 ModelView로 변환.
mv.setModel(model); //modelView에 model값을 넣는다.
return mv;
}
private Map<String, String> createParamMap(HttpServletRequest request){
Map<String, String> paramMap = new HashMap<>();
request.getParameterNames().asIterator().forEachRemaining(paramName -> paramMap.put(paramName, request.getParameter(paramName)));
return paramMap;
}
}
8.ControllerV3, ControllerV4 를 적용할수 있는 FrontControllerServletV5 생성하기
@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");
}
}
아직도 완벽하게는 모르겠다...
계속 그림을 보면서 코드를 반복학습 하자
'[WEB]Back-end > Spring MVC' 카테고리의 다른 글
Spring Boot의 Handler의 과정 (0) | 2022.02.14 |
---|---|
@RestController vs @Controller 간단 정리 (0) | 2022.02.13 |
GET URL 쿼리 파라미터, POST HTML Form 형식 비교 (0) | 2022.02.07 |
HTTP 데이터 요청 대표적 3가지(GET방식, POST방식, HTTP메세지바디 ) 정리 (0) | 2022.02.07 |
HTML, HTTP API, CSR, SSR의 정리 (0) | 2022.02.07 |