1) 서블릿의 종속성 제거 - 요청 파라미터 정보를 자바의 Map으로 대신 넘기도록 하면 지금 구조에서는 컨트롤러가 서블릿 기술을 몰라도 동작할 수 있다. - 현재 구현된 컨틀로러가 서블릿 기술을 전혀 사용하지 않도록 변경 - HttpServletRequest가 제공하는 파라미터는 프론트 컨트롤러가 paramMap에 담아 호출 - 응답 결과로 뷰 이름과 뷰에 전달할 Model 데이터를 포함하는 Modelview 객체를 반환
2) 뷰 이름 중복 제거 - 컨트롤러에서 지정하는 뷰 이름에 중복이 있다. - 컨트롤러는 뷰의 논리 이름을 반환하고 실제 물리 위치의 이름은 프론트 컨트롤러에서 처리하도록 단순화
■ ModelView
- 지금까지는 컨트롤러에서 서블릿에 종속적인 HttpServletRequest를 사용 - Model도 request.setAttribute()를 통해 데이터를 저장하고 뷰에 전달 - 서블릿의 종속성을 제거하기 위해 Model를 직접 만들고, view 이름을 전달하는 객체를 생성 - 컨트롤러에서 뷰에 필요한 데이터를 key, value로 넣어준다.
import java.util.HashMap;
import java.util.Map;
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;
}
}
■ MemberSaveControllerV3 - 회원저장
- ModelView를 생성할 때 save-result라는 view의 논리적인 이름을 지정 - 실제 물리적인 이름은 프론트 컨트롤러에서 처리 - process() 메서드에 파라미터로 전달된 paramMap에는 파라미터 정보가 담겨있다.
import hello.servlet.domain.member.Member;
import hello.servlet.domain.member.MemberRepository;
import hello.servlet.web.frontcontroller.ModelView;
import hello.servlet.web.frontcontroller.MyView;
import hello.servlet.web.frontcontroller.v3.ControllerV3;
import org.springframework.ui.Model;
import java.util.Map;
public class MemberSaveControllerV3 implements ControllerV3 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public ModelView process(Map<String, String> paramMap) {
String username = paramMap.get("username");
int age = Integer.parseInt(paramMap.get("age"));
Member member = new Member(username, age);
memberRepository.save(member);
//Model에 데이터를 보관한다.
ModelView modelView = new ModelView("save-result");
modelView.getModel().put("member", member);
return modelView;
}
}
■ FrontControllerServletV3
- createParamMap() : HttpServletRequest에서 파라미터 정보를 꺼내서 Map으로 변환 - 생성된 해당 Map은 컨트롤러에 전달하면서 호출
- viewResolver() : 컨트롤러가 반환하는 논리 뷰 이름을 실제 물리 뷰 경로로 변경, 실제 물리 경로가 있는 MyView객체를 반환
- MyView의 render() 메서드는 모델 정보도 함께 받는다. - modelToRequestAttribute() 메서드는 전달받은 모델 정보를 HttpServletRequest에 담아 view에 전달하게 된다. - view에선 request.getAttribute() 를 통해 필요한 데이터를 화면에 렌더링한다.