기존 모델을 request로 썼었다.
이제는 컨트롤러에서 호출 시 MyView가 아닌 Model과 View가 섞인 ModelView를 반환, 또 바뀐점은 컨트롤러는 이제 /WEB-INF/views/save-result.jsp 이런 full path가 아닌 save-result논리 경로만 생각한다.
그리고, viewResolver를 호출하면 MyView를 반환. 이 viewResolver에서 full path를 만들어서 반환해서 MyView로 반환해 준다.
@WebServlet(name="frontControllerServletV3", urlPatterns = "/front-controller/v3/*")
public class FrontControllerServletV3 extends HttpServlet {
private Map<String, ControllerV3> controllerMap = new HashMap<>();
public FrontControllerServletV3(){
controllerMap.put("/front-controller/v3/members/new-form",new MemberFormControllerV3());
controllerMap.put("/front-controller/v3/members/save",new MemberSaveControllerV3());
controllerMap.put("/front-controller/v3/members",new MemberListControllerV3());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ControllerV3 controller = controllerMap.get(request.getRequestURI());
if(controller == null){
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
Map<String, String> paramMap = createParamMap(request);
ModelView mv = controller.process(paramMap);
MyView view = viewResolver(mv.getViewName());
view.render(mv.getModel(), request, response);
}
private static 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;
}
public MyView viewResolver(String viewName){
String viewPath = "/WEB-INF/views/" +viewName+".jsp";
return new MyView(viewPath);
}
}
기존이랑 비슷하고,
원래 기존에는 컨트롤러에게 전달할 때 유저요청의 파라미터라든지 그런 게 필요해서 request, 혹은 response 등 굉장히 servlet에 종속적이었다.
이제 이거를 paramMap 이라고 만들어 거기다 유저요청의 파라미터만 저장해두고,
그걸 컨트롤러에 넘긴다.
public class MemberSaveControllerV3 implements ControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String ,String> paramMap) {
String name = paramMap.get("username");
int age = Integer.parseInt(paramMap.get("age"));
Member member = new Member(name,age);
Member savedMember = memberRepository.save(member);
ModelView mv = new ModelView("save-result");
mv.addData("member", savedMember);
return mv;
}
}
넘겨진 파라미터는 저렇게 사용되어진다.
저렇게 만들고, 논리경로와 함께 ModelView를 만들어 준 다음, view(jsp)에게 전할 데이터를 Model에 넣어준 뒤, ModelView를 return 시켜준다.
ModelView는 View에 표시할 정보들을 Model에 담는거기 때문에 같이 한 듯.
viewResolve는 프론트컨트롤러에서 만들어줬다. 이제 저기서 MyView를 return해준다.
그리고, view를 render() 해 줄때, model도 같이 보내준다.
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 static void modelToRequestAttribute(Map<String, Object> model, HttpServletRequest request) {
model.forEach((key, value)-> request.setAttribute(key,value));
}
이런 식으로 오버로드 해 줬다.
모델이 있을경우, 그냥 그걸 request.setAttribute로 담아준다. jsp는 request.getAttribute()를 사용하기 때문이다.
public class ModelView {
private String viewName;
private Map<String, Object> model = new HashMap<>();
public ModelView(String viewName) {
this.viewName = viewName;
}
public void addData(String key, Object obj){
model.put(key, obj);
}
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;
}
}
getter, setter까지 추가해줬다.
addData는 내가 기존 밸류 건드리는거 막으려고 해놨다.
'스프링 > 3. 스프링 MVC' 카테고리의 다른 글
28. 유연한 컨트롤러 (0) | 2023.08.07 |
---|---|
27. 단순화 (0) | 2023.08.06 |
25. 프론트 컨트롤러 공통로직(뷰 추가) (0) | 2023.08.06 |
24. 프론트 컨트롤러 도입. (0) | 2023.08.06 |
23. 프론트 컨트롤러 (0) | 2023.08.06 |