[Spring MVC]#2フレームワーク(2)分離ビューの作成


フロントエンドコントローラモードを採用した従来の構成では、各コントローラがビューに移動する部分に重複コードがある.
ビューを個別に処理するオブジェクトを作成し、重複コードを除去

ビューの切断


ビュー処理オブジェクトの追加



MyView

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);
    }
}
  • viewPathを呼び出すrender関数
  • controllerV2

    public interface ControllerV2 {
    
        MyView process(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException;
    }
  • は、従来と同様のインターフェース実装
  • である.
    は、
  • MyViewオブジェクト
  • を返します.

    会員登録コントローラ

    public class MemberFormControllerV2 implements ControllerV2 {
    
        @Override
        public MyView process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            return new MyView("/WEB-INF/views/new-form.jsp");
        }
    }
  • viewPathを使用してオブジェクトを作成し、返します.
  • 以前に比べてdispatcherの部分は転送されていないので非常に簡潔である.
  • 会員ストレージコントローラ

    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);
        }
    }
    記憶
  • マッピング情報は、以前と同じ
  • である.
  • Myviewオブジェクトのrender()を呼び出してバッチを実行します.
  • 各コントローラは、MyViewオブジェクト
  • を生成して返す.
  • 改善すべき点

  • では、モデル部分がまだ不足しています.
  • フロントエンドコントローラは、各コントローラの要求、応答を除去することができる.(テンプレート依存の除去)