앞서만든 V3 버전은 반복적인 코드를 줄이고 매핑된 주소로 이동하는 방식도 쉽게 변경이 가능하게 만들었지만, 실제로 개발자가 추구해야하는 코드는 단순하고 실용적인 코드여야 한다. 앞서 V3의 코드들이 딱 그런 케이스라고 생각한다.
이번에 V4버전을 만들면서 좀더 편리하게 개발이 가능하게 바꿔보자.
앞서 V3와 다른점은 Controller에서 ModelView를 반환하는것이 아니라 ViewName을 반환하는 것 뿐이다.
먼저 인터페이스 Controller를 만들어보고 이전 인터페이스와 뭐가 다른지 봐보자.
public interface ControllerV4 {
/**
*
* @param paramMap
* @param model
* @return viewName
*/
String process(Map<String,String>paramMap,Map<String,Object>model);
}
이전에 V3에서 사용 된 인터페이스는 단순히 값을 각자의 컨트롤러에 사용하기 위한 객체인 paramMap만이 존재 했지만 이번에는 model이라는 객체도 같이 사용되었다. 이객체의 사용하는 모습은 각각의 컨트롤러에서 사용되는 모습을 보자.
- New-Form
public class MemberFormControllerV4 implements ControllerV4 {
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) {
return "new-form";
}
}
- Save-result
public class MemberSaveControllerV4 implements ControllerV4 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) {
String username = paramMap.get("username");
int age = Integer.parseInt(paramMap.get("age"));
Member member = new Member(username,age);
memberRepository.save(member);
model.put("member",member);
return "save-result";
}
}
- MemeberList
public class MemberListControllerV4 implements ControllerV4 {
private MemberRepository memberRepository = MemberRepository.getInstance();
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) {
List<Member> members = memberRepository.findAll();
model.put("members",members);
return "members";
}
}
이렇게만 보면 어떻게 사용되는지 아직은 모를수 있으니 Front-Controller를 봐보자.
@WebServlet(name="frontControllerServletV4",urlPatterns = "/front-controller/v4/*")
public class FrontControllerServletV4 extends HttpServlet {
private Map<String, ControllerV4> controllerMap = new HashMap<>();
public FrontControllerServletV4(){
controllerMap.put("/front-controller/v4/members/new-form",new MemberFormControllerV4());
controllerMap.put("/front-controller/v4/members/save",new MemberSaveControllerV4());
controllerMap.put("/front-controller/v4/members",new MemberListControllerV4());
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("frontControllerServletVdd4.service");
String requestURI = request.getRequestURI();
ControllerV4 controller = controllerMap.get(requestURI); // 해당 키 값의 value 추출
if(controller == null){
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
Map<String, String> paramMap = createParaaMap(request);
Map<String, Object> model = new HashMap<>();
String viewName = controller.process(paramMap,model);
MyView myView = viewResolver(viewName);
myView.render(model,request,response);
}
private static MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
private static Map<String, String> createParaaMap(HttpServletRequest request) {
Map<String ,String > paramMap = new HashMap<>();
request.getParameterNames().asIterator()
.forEachRemaining(paramName->paramMap.put(paramName, request.getParameter(paramName)));
return paramMap;
}
}
이전의 V3에서 사용된 Front-Controller와 차이점은 각각의 컨트롤러의 process를 사용하기 위해 model이라는 Map타입의 객체를 함께 보냈으며, 반환값으로 실제로 이동할 파일의 이름을 String 타입으로 반환한 모습이다.
간단하게 사용법을 설명하자면 이전까지 process에서 paramMap만 가지고갔을 때는 request로 받은 username과 age를 각각의 컨트롤러에서 ModelView에 존재하는 model 객체에 담아 viewPath와 함께 반환을 해서 Front-Controller에서 사용흘 햇다면 이번 V4에서는 paramMap와 model이라는 객체를 사용해 paramMap은 request로 받은 username과 age를 담아 각각의 컨트롤러에서 사용(저장)되었고, model이라는 객체를 통해 각 컨트롤러에서 저장된 객체를 담는데 사용이 된다.
즉 하나는 입력된 값을 사용하기 위해있고, 나머지 하나는 값을 담아서 오는데 사용된다고 보면 쉽다. 그런뒤 각각의 컨트롤러는 반환값으로 파일의 이름을 반환했기 때문에 String으로 반환을 받았으며 그 값을 이용해 viewName을 만들고 model에 담아온 값을 이용해 V3와 같이 reder한 모습을 볼 수 있다.
'spring' 카테고리의 다른 글
Front Controller (5-1) (0) | 2023.03.19 |
---|---|
Front Controller (5) (0) | 2023.03.19 |
Front Controller (3) (0) | 2023.03.18 |
Front Controller (2) (0) | 2023.03.16 |
Front Controller (1) (0) | 2023.03.16 |