Java Web 学习(3) —— MVC
MVC
一、 MVC 模式
MVC 代表 Model-View-Controller (模型-视图-控制器) 模式。
- Model:模型代表 DAO (Data Access Object 数据访问对象) 或 POJO(Plain Ordinary Java Object 普通 JavaBeans)。是应用程序中用于处理应用程序数据逻辑的部分。
- View:视图将数据可视化。
- Controller:应用程序中处理用户交互的部分。控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。控制器分离了视图与模型。
二、 Model 2
Java Web 应用开发中有两种设计模型,Model 1 和 Model 2。
Model 1 的中心是 JSP 页面,由 JSP 调用业务逻辑,显示页面,适合于小应用开发。
由 JSP 充当 视图和控制器,JavaBeans 充当模型。
Model 2 基于 MVC 模式,几乎所有现代 Web 框架都是 Model 2 的实现。
由 JSP 充当视图,Servlet 或 Filter 充当控制器,JavaBeans 充当模型。
每个HTTP 请求都发送给控制器,请求中的 URI 标识出对应的 action。action 代表了应用可以执行的一个操作。
控制器会解析 URI 并调用相应的 action,然后将模型对象放到视图可以访问的区域。
最后,控制器利用 RequestDispatcher 或者 HttpServletResponse.sendRedirect 方法跳转到视图。在 JSP 页面中,用表达式语言以及定制标签显示数据。
三、 Servlet 控制器
@WebServlet(name="ControllerServlet", urlPatterns={"/input-product", "/save-product"}) public class Controllerservlet extends HttpServlet{ private static final long serialVersionUID=1579L; @Override public void doGet(HttpServletRequest request, HttpServletResponse response throws IOException, ServletException { process(request, response); } @Override public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { process(request, response); } // 通过 process 方法处理所有输入请求 private void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException{ // 获取 action String uri = request.getRequestURI(); // uri = /contextName/resourceName 或 /resourceName int lastIndex = uri.lastIndexOf("/"); String action = uri.substring(lastIndex +1); // 转发 url String dispatchUrl = null; // 处理 action if("input-product".equals(action)){ dispatchUrl = "/jsp/ProductForm.jsp"; } else if("save-product".equals(action)){ // 创建模型 product = new Product(); product.setName(request.getParameter("name")); product.setDescription(request.getParameter("description")); product.setPrice(Integer.parseInt(request.getParameter("price"))); // 业务逻辑 保存模型等 SaveProductAction saveProductAction = new SaveProductAction(); saveProductAction.save(product); // 将模型添加到 request 属性中 以便视图访问 request.setAttribute("product", product); dispatchUrl = "/jsp/ProductDetails.jsp"; } // 转发 if(dispatchUrl != null){ RequestDispatcher rd = request.getRequestDispatcher(dispatchUrl); rd.forward(request, response); } } }
<%--ProductForm.jsp--%> <form method="post" action="save-product"> <h1>Add Product</h1> <label> <span>Product Name:</span> <input id="name" type="text" name="name"> </1abel> <label> <span>Description:</span> <input id="description" type="text" name="description"> </label> <label> <span>Price:</label> <input id="price" name="price" type="number" step="any"> </label> <label> <span> :</span> <input type="submit"> </label> </form>
三、 Filter 分发器
@WebFilter(filterName="DispatcherFilter", urlPatterns={"/*"}) public class DispatcherFilter implements Filter{ @Override public void init(Filterconfig filterconfig) throws ServletException { } @Override public void destroy() { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; String uri = req.getRequestURI(); // ... 与 Servlet Controller 一致 if (dispatchUrl! = null){ RequestDispatcher rd = request.getRequestDispatcher(dispatchUrl); rd.forward(request, response); } else { // 过滤器过滤包括静态目标在内的所有网址 如果没有 action 则继续传递下去 filterChain.doFilter(request, response); } } }