단순하고 실용적인 컨트롤러 - v4를 만들어 보자.
- v3 컨트롤러는 서블릿 종속성을 제거하고 뷰 경로의 중복을 제거하는 등, 잘 설계된 컨트롤러이지만
- 컨트롤러 인터페이스를 구현하는 입장에서 항상 ModelView 객체를 생성하고 반환해야 하는 부분이 번거롭다.
- 프레임워크가 좋다는 거는 아키텍져도 좋지만 실제 개발자가 편리하게 사용하고 실용성이 있어야 한다.
- v3를 조금 변경해서 개발자들이 편리하게 개발가능한 v4 버전을 개발해보자.
v4 package에서 ControllerV4를 만들어주자.
package hello.setvlet.web.frontcontroller.v4;
import java.util.Map;
public interface ControllerV4 {
/**
*
* @param paramMap
* @param model
* @return
*/
String process(Map<String, String> paramMap, Map<String, Object> model);
}
MemberFormControllerV4에서 는 modelvie가 필요가 없다
// MemberFormControllerV4
package hello.setvlet.web.frontcontroller.v4.controller;
import hello.setvlet.web.frontcontroller.v4.ControllerV4;
import java.util.Map;
public class MemberFormControllerV4 implements ControllerV4 {
@Override
public String process(Map<String, String> paramMap, Map<String, Object> model) {
return "new-form";
}
}
MemberFormControllerV3와 비교를 해보자.
// MemberFormControllerV3
package hello.setvlet.web.frontcontroller.v3.controller;
import hello.setvlet.web.frontcontroller.ModelView;
import hello.setvlet.web.frontcontroller.v3.ControllerV3;
import java.util.Map;
public class MemberFormControllerV3 implements ControllerV3 {
@Override
public ModelView process(Map<String, String> paramMap) {
// 논리적인 이름을 넣어주자
return new ModelView("new-form");
}
}
MemberSaveControllerV4도 마찬가지로 굉장히 심플해졌다.
package hello.setvlet.web.frontcontroller.v4.controller;
import hello.setvlet.domain.member.Member;
import hello.setvlet.domain.member.MemberRepository;
import hello.setvlet.web.frontcontroller.v4.ControllerV4;
import java.util.Map;
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";
}
}
MemberListControllerV4도 보자 굉장히 심플하다.
package hello.setvlet.web.frontcontroller.v4.controller;
import hello.setvlet.domain.member.Member;
import hello.setvlet.domain.member.MemberRepository;
import hello.setvlet.web.frontcontroller.v4.ControllerV4;
import java.util.List;
import java.util.Map;
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("member", members);
return "members";
}
}
FrontControllerServletV4도 만들어주자. viewName을 만들어서 넘겨주자.
String viewName = controller.process(paramMap, model);
MyView view = viewResolver(viewName);
view.render(model, request, response);
package hello.setvlet.web.frontcontroller.v4;
import hello.setvlet.web.frontcontroller.ModelView;
import hello.setvlet.web.frontcontroller.MyView;
import hello.setvlet.web.frontcontroller.v4.controller.MemberFormControllerV4;
import hello.setvlet.web.frontcontroller.v4.controller.MemberListControllerV4;
import hello.setvlet.web.frontcontroller.v4.controller.MemberSaveControllerV4;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@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 {
String requestURI = request.getRequestURI();
ControllerV4 controller = controllerMap.get(requestURI);
if (controller == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
return;
}
Map<String, String> paramMap = createParamMap(request);
Map<String, Object> model = new HashMap<>(); // 추가
String viewName = controller.process(paramMap, model);
MyView view = viewResolver(viewName);
view.render(model, request, response);
}
private MyView viewResolver(String viewName) {
return new MyView("/WEB-INF/views/" + viewName + ".jsp");
}
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;
}
}
실행을 해주면 v4회원목록에 목록이 안나오고 v3 회원목록으로 다 넘어간다... 해결중이다...
정리하면
- 이번의 컨트롤러는 단순하고 실용적인데 기존에 구조에서 모델을 파라미터로 넘기고, 뷰의 논리 이름을 반환한다는 작은 아이디어를 적용함으로써
- 컨트롤러는 구현하는 개발자 입장에서 군더더기 없는 코드를 작성할 수 있다.
- 또 여기까지 한번에 온것이 아닌 프레임워크가 점진적으로 발전하는 과정에서 이런 방법도 찾을 수 있었다.
- => 프레임워크나 공통 기능이 수고로워야 개발자가 편리해진다.
<출처 김영한: 스프링 MVC 1편 - 벡앤드 웹 개발 핵심 기술>
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-1/dashboard
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의
웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -
www.inflearn.com
'Spring > SpringMVC' 카테고리의 다른 글
유연한 컨트롤러2 - v5 (0) | 2022.04.25 |
---|---|
유연한 컨트롤러1 - v5 (0) | 2022.04.25 |
Model 추가 - v3 (0) | 2022.04.24 |
View 분리 - v2 (0) | 2022.04.24 |
프론트 컨트롤러 도입 - v1 (0) | 2022.04.24 |