[Spring MVC]#2フレームワークの作成(3)モデルの追加


以前はviewを分離した構造では,各コントローラに不要な要求,応答があった.
モデルを追加して、テンプレートの依存関係を削除します.また、ビュー名の重複を解消しようとすることもできます.

修正が必要な部分


1.テンプレート依存関係の削除
  • コントローラの場合、HttpServeretRequest、HttpServeretResponseは不要です.
  • 要求パラメータ情報をMapに転送し、タブレット技術を使用することなく操作できます.
  • リクエストオブジェクトをモデルとして使用するのではなく、個別のモデルオブジェクトを作成して返します.
    2.ビュー名重複除外
  • コントローラにビューの論理名を返し、フロントエンドコントローラが実際の物理的位置を処理する名前を簡略化します.
  • これにより、後でビュー内のフォルダ位置が変更されても、フロントエンドコントローラ部分を変更するだけで済みます.

    モデルの追加


    こうぞう



    ModelView

    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;
        }
    }
  • テンプレート依存性
  • を解消するために、モデルを直接作成してビュー名に渡すオブジェクトを作成する.
  • ModelViewクラスのメンバー変数には、ビューの論理名とモデルロールのマッピングがあります.
  • ControllerV3

    public interface ControllerV3 {
    
        ModelView process(Map<String, String> paramMap);
    }
  • インタフェース
  • HttpServeretRequest、簡単にHttpServeretResponseを必要としません.
  • 会員登録コントローラ

    public class MemberFormControllerV3 implements ControllerV3 {
    
        @Override
        public ModelView process(Map<String, String> paramMap) {
            return new ModelView("new-form");
        }
    }
  • viewの論理名のみ入力します.
  • 会員ストレージコントローラ

    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);
    
            ModelView mv = new ModelView("save-result");
            mv.getModel().put("member", member);
            return mv;
        }
    }
  • 要求パラメータの値はMapから取得される.
  • メンバーオブジェクトをModelViewのモデルに格納します.
  • メンバーリストコントローラ

    public class MemberListControllerV3 implements ControllerV3 {
    
        private MemberRepository memberRepository = MemberRepository.getInstance();
        @Override
        public ModelView process(Map<String, String> paramMap) {
            List<Member> members = memberRepository.findAll();
            ModelView mv = new ModelView("members");
            mv.getModel().put("members", members);
            return mv;
        }
    }

    フロントエンドコントローラV 3

    @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 {
    
            String requestURI = request.getRequestURI();
    
            ControllerV3 controller = controllerMap.get(requestURI);
            if (controller == null){
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
    
            //paramMap을 넣어주어야함
            Map<String, String> paramMap = createParamMap(request);
            ModelView mv = controller.process(paramMap);
    
            String viewName = mv.getViewName();
            MyView view = viewResolver(viewName);
            view.render(mv.getModel(), 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;
        }
    }
  • paramMapに要求に含まれる情報を追加する必要があります.
  • viewResolverで、ビューの論理名を物理名に変更します.
  • モデルパラメータを
  • render関数に追加する必要があるため、render関数をMyViewにロードします.
    ⚠▼関数の記号が違うのでoverridingではありません
  • render関数は、モデル内のデータをすべて要求として格納します.
    リクエストに応答するライフサイクルが終了するまで、ビューに渡すとモデルの役割を果たします.
  • createParamMap要求パラメータから情報を抽出してMapに変換
  • メソッド抽出は、内部でのみ使用されるため、プライベート処理が行われる.
  • 改善すべき点

  • 各コントローラでModelViewを作成して戻す部分は不便
  • です.