Web/Servlet-JSP

Servlet-JSP MVC04 (2) - handlerMapping and viewResolver

now0204 2023. 6. 16. 11:40

 

- (1)번에서 만들었던 frontcontroller를 더 수정해보자. 

- frontcontroller의 역할을 다시한번 상기하자면, 

      > 요청받기, 공통부분처리, pojo 메서드호출, view연결이다.

- 이러한 역할들 중에 pojo를 호출하는 분기문을 handlerMapping을 적용하여 더 깔끔하게 정리해보도록하자.

- 또한 viewresolver를 적용해보자.

출처:https://devmoony.tistory.com/102

1. HandlerMapping 

 

-사용자 요청과 이를 처리할 pojo맵핑시켜주는 역할을 담당한다.

-이전에 분기문으로 사용자 요청을 확인하고, 이에 따라 적절한 pojo를 연결하는 작업을 frontcontroller내에서 했는데

이를 따로 떼어두는 것이다.

 

public class HandlerMapping{
 private HashMap<String,Controller> mappings = new HashMap<>();

 public HandlerMapping(){
 
 	mappings.put("/memberList.do",new MemberListController());
 	//...추가
 	}

  public getController(String key){
  	return mappings.get(key);
  }
}

 

- 생성자에 각 요청에 대한 url정보와 이를 처리할 pojo를 hashMap으로 연결한다.

- 컨트롤러 반환 메서드를 호출하면, key값에 맞는 controller를 return한다.

 

//FrontContrller 

 String url = request.getRequestURI();
 String context = request.getContextPath();
 //요청정보확인
 String command = url.substring(context.length());
 
 String nextPage =null;
 Controller cr = null;
 
 HandlerMapping mp = new HandlerMapping();//생성되면서, hashmap에 mapping정보 초기화
 cr = mp.getController(command); // 요청정보를 전달받아 이에 맞는 pojo return 
 nextPage = cr.requestHandler(request,response); //pojo메서드 호출한 뒤 nextPage return받음

HandlerMapping을 통해  FrontController의 분기문을 위와 같이 간결하게 처리할 수 있다.

 

2. ViewResolver

 

- 지금까지는 pojo에  다음 처리할 view의 path를 직접 적어두었다.

- 처리할  view의  이름은 자주 변하지 않지만,  폴더구조는 자주 변할 수 있다. 폴더 구조가 변하면 모든 pojo에 가서 다시 적어줘야하는데 매우 비효율적이다.

- 이러한 일을 간단하게 처리할 수 있도록 pojo는  view의 이름만 return하고, 나머지 폴더구조는 

한 곳에서만 관리하여, 폴더 구조가 변하면 한 곳만 수정하면 좋을 것이다.

- 이러한 역할을 해주는 것이 ViewResolver이다.

 

* viewresolver를 설정하기 전에 jsp파일을 모아둔 폴더는 WEB-INF로 옮겨두자

이는 클라이언트가 컨트롤러 요청 외 직접 jsp파일로 접근하지 못하게 하기 위해서이다. 

forward로 서버 내부 페이지 전환시에는 WEB-INF폴더에 접근할 수 있다.

 

public class ViewResolver{
	private static String prefix="/WEB-INF/member/";
    private static String postfix=".jsp";

	public static String getPath(String viewname){
    return prefix+viewname+postfix;
    }
}

접두사와 접미사를 붙여서 view이름을 return해주는 클래스를 만들었다.

이제 frontController내부에서 다음과 같이 처리할 수 있다.

// ... pojo로 메서드를 호출하고 nextPage를 return 받은 상황

if(nextPage !=null){

	if(nextPage.contain("redirect:"){
    	response.sendRedirect(nextPage.split(":")[1]);
    }else{
    	RequestDispatcher rd = request.getRequestDispatcher(ViewResolver.getPath(nextPage));
        re.forward(request,response);
    }

}

 

 

3. 추가 ContextPath가 변경시에도 동일하게 작동하도록 하기

 

 - ContextPath가 변경되면  ContextPath를 포함해서 지정해두었던 모든 view와 Controller를 수정해줘야할 것이다

(redirect, form태그에 action들

- ContextPath가 변경되어도 이를 자동반영하도록 수정해보자.

- frontController에서 request.getContextPath();얻은 것 처럼 하면 된다.

 

//contextPath가 필요한 pojo 상단에 추가
	//요청정보에따라 contextPath를 읽는다.
	String ctx = request.getContextPath();
    //..처리 
    
    // return할 nextPage에 기존 ContextPath였던 부분을 변수로 ctx로 고쳐준다.
    nextPage = "redirect:"+ctx+"/memberList.do";
//jsp

<c:set var="ctx" value="${pageContext.request.contextPath}"
//pageContext를 통해 request객체에 접근하여 contextPath를 읽어온다

EL을 통해 다음과 같이 읽어온 contextPath의 값을 경로에 집어넣는다.
<form action="${ctx}/memberUpdate.do" method="post">

위와 같이 request객체를 통해 contextPath를 읽어오고 이를 변수에 담은 뒤에 필요한 부분에 대입하면된다.

 

 

*contextPath나 폴더구조(뷰이름제외)등은 자주 변할 수 있으니 직접 적는 것은 피하고, 뷰리졸버나 변수를 통해 대입하자 

 

 

 

참고자료:

 

나프1탄(인프런) -박매일

https://www.inflearn.com/course/%EB%82%98%ED%94%84-mvc-1

 

[NarP Series] MVC 프레임워크는 내 손에 [나프1탄] - 인프런 | 강의

본 과정은 WEB MVC 프레임워크가 무엇이고 WEB MVC 프레임워크가 어떻게 변형이 되면서 Spring WEB MVC 프레임워크로 넘어가는지 TPC(생각하고-표현하고-코딩하고) 기법을 통해 단계적으로 학습하고 이

www.inflearn.com

 

https://devmoony.tistory.com/102

 

[Spring MVC] Dispatcher Servlet 이란? -(FrontController패턴 포함)

Dispatcher Servlet 이란? Dispatcher Servlet에서 dispatch는 "보내다" 라는 사전적 의미를 가지고 있습니다. 본격적으로 Dispatcher Servlet에 대해 설명하기 앞서 FrontController 패턴의 개념을 살펴보고 가겠습니다

devmoony.tistory.com