Spring MVC-1 TIL (5)


[参考講座]金英漢のSpring MVC 1編-バックエンドWeb開発キーテクノロジー

💡 MVCフレームワークの作成


▼▼フロントエンドコントローラモード概要


図のようにフロントエンドコントローラを導入します.

Front Controlモードの特性

  • フロントエンドコントローラ単板機要求
  • フロントエンドコントローラ要求に適合するコントローラを見つけ、
  • を呼び出す.
  • 入口は一体😊
  • 汎用プロセッサ
  • フロントエンドコントローラ以外のコントローラは、アシストコントローラ
  • を使用する必要はない.
    SpringWeb MVCのDispatcherServiceletは、セグメントコントローラモードを採用しています.

    フロントエンドコントローラ-v 1の導入



    ControllerV1

    package hello.servlet.web.frontcontroller.v1;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
     
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public interface ControllerV1 {
          void process(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException;
    }
    サーブレットのようなコントローラインタフェースを導入します.各コントローラはこのインタフェースを実現することができます.
    フロントエンドコントローラは、このインタフェースを呼び出して、論理の一貫性を実装とは無関係にすることができます.
    会員登録コントロール、会員ストレージコントロール、会員リストコントロールは、既存のテンプレートとほぼ同じであり、上書きプロセスの違いのみ
    フロントコントローラを見てみましょう.😎

    FrontControllerServletV1

    @WebServlet(name = "frontControllerServletV1", urlPatterns = "/front-controller/v1/*")
    public class FrontControllerServletV1 extends HttpServlet {
    
        private Map<String, ControllerV1> controllerMap = new HashMap<>();
    
        public FrontControllerServletV1() {
            controllerMap.put("/front-controller/v1/members/new-form", new MemberFormControllerV1());
            controllerMap.put("/front-controller/v1/members/save", new MemberSaveControllerV1());
            controllerMap.put("/front-controller/v1/members", new MemberListControllerV1());
        }
    
        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("FrontControllerServletV1.service");
    
            String requestURI = request.getRequestURI();
    
            ControllerV1 controller = controllerMap.get(requestURI);
            if (controller == null) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
    
            controller.process(request, response);
    
        }
    }
    

    フロントエンドコントローラ解析


    urlPatterns
  • 2urlPatterns = "/front-controller/v1/*":/front-controller/v1を含むすべてのサブリクエストは、サーブレットに受け入れられる.
  • controllerMap

  • キー:マップURL
  • 値:呼び出されるコントローラ
  • service()


    まずrequestURIをクエリーし、controllerMapで実際に呼び出すコントローラを検索します.ない場合、404コードが返される.
    コントローラを見つけてコントローラprocess(request, response);対応するコントローラの実行を呼び出します.

    ▼▼View分離-v 2


    すべてのコントローラからビューに移動する部分には冗長性があり、清潔ではありません.
    String viewPath = "/WEB-INF/views/new-form.jsp";
    RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
    dispatcher.forward(request, response);

    MyView


    ビューオブジェクトは他のバージョンで使用されます.frontcontrollerの下に置いてあります.
     public class MyView {
          private String viewPath;
          
          public MyView(String viewPath) {
              this.viewPath = viewPath;
          }
          
          public void render(HttpServletRequest request, HttpServletResponse
      response) throws ServletException, IOException {
              RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
              dispatcher.forward(request, response);
          }
    }

    ControllerV2

    public interface ControllerV2 {
    
          MyView process(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException;
      }
     

    会員登録表

    public class MemberFormControllerV2 implements ControllerV2 {
    
        @Override
        public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
    
            MyView myView = new MyView("/WEB-INF/views/new-form.jsp");
            return myView;
        }
    }
    
    各コントローラは複雑なスケジューラです.forward()呼び出しを直接生成する必要はありません.MyViewオブジェクトを作成してビューと名前を付けて返すだけです.
    確かに重複データ削除です!😎

    メンバーの保存

    public class MemberSaveControllerV2 implements ControllerV2 {
    
        private MemberRepository memberRepository = MemberRepository.getInstance();
    
        @Override
        public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String username = request.getParameter("username");
            int age = Integer.parseInt(request.getParameter("age"));
    
            Member member = new Member(username, age);
            memberRepository.save(member);
    
            //Model에 데이터를 보관
            request.setAttribute("member", member);
    
            return new MyView("/WEB-INF/views/save-result.jsp");
        }
    }

    メンバー・リスト

    public class MemberListControllerV2 implements ControllerV2 {
    
        private MemberRepository memberRepository = MemberRepository.getInstance();
    
        @Override
        public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            List<Member> members = memberRepository.findAll();
            request.setAttribute("members", members);
            return new MyView("/WEB-INF/views/members.jsp");
        }
    }
    

    フロントエンドコントローラv 2

    @WebServlet(name = "frontControllerServletV2", urlPatterns = "/front-controller/v2/*")
    public class FrontControllerServletV2 extends HttpServlet {
    
        private Map<String, ControllerV2> controllerMap = new HashMap<>();
    
        public FrontControllerServletV2() {
            controllerMap.put("/front-controller/v2/members/new-form", new MemberFormControllerV2());
            controllerMap.put("/front-controller/v2/members/save", new MemberSaveControllerV2());
            controllerMap.put("/front-controller/v2/members", new MemberListControllerV2());
        }
    
        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            String requestURI = request.getRequestURI();
    
            ControllerV2 controller = controllerMap.get(requestURI);
            if (controller == null) {
                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                return;
            }
    
            MyView view = controller.process(request, response);
            view.render(request, response);
    
        }
    }
    コントローラV 2の戻りタイプはMyViewであるため、フロントエンドコントローラはコントローラ呼び出しの結果としてMyViewを返す.あとviewrender()を呼び出すと、JSPを実行するために順方向論理が実行されます.

    MyView.render()

     public void render(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            RequestDispatcher dispatcher = request.getRequestDispatcher(viewPath);
            dispatcher.forward(request, response);
        }
    
    フロントエンドコントローラの導入により、MyViewオブジェクトのレンダリング()呼び出し部分が一貫性を保つことができます.各コントローラはMyViewオブジェクトを作成して戻るだけです.

    次にモデルを追加~~~!