zoukankan      html  css  js  c++  java
  • MVC 模式和模型 2

    MVC框架

    一个实现 MVC 模式的应用包含模型、视图、控制器 3 个模块:

    模型:封装了应用的数据和业务逻辑,负责管理系统业务数据

    视图:负责应用的展示

    控制器:负责与用户进行交互,接收用户输入、改变模型、调整视图的显示

    基于MVC架构模式的 Java Web 开发

    采用了 Servlet + JSP + JavaBean 的技术实现

    基于MVC架构模式的 Java Web 开发步骤

    1. 定义一系列的 Bean 来表示数据

    2. 使用一个 Dispatcher Servlet 和控制类来处理用户请求

    3. 在 Servlet 中填充 Bean

    4. 在 Servlet 中,将 Bean 存储到 request、session、servletContext中

    5. 将请求转发到 JSP 页面

    6. 在 JSP 页面中,从 Bean 中提取数据。

    其中 Dispatcher servlet 必须完成如下功能:

    1. 根据 URI 调用相应的 action

    2. 实例化正确的控制器类

    3. 根据请求参数值来构造表单 bean

    4. 调用控制器对象的相应方法

    5. 转发到一个视图(JSP页面)

    每个 HTTP 请求都发送给控制器,请求中的 URI 标识出对应的 action。action 代表了应用可以执行的一个操作。一个提供了 Action 的 Java 对象称为 action 对象。

    控制器会解析 URI 并调用相应的 action,然后将模型对象放到视图可以访问的区域,以便服务器端数据可以展示在浏览器上。最后控制器利用 RequestDispatcher 跳转到视图(JSP页面),在JSP页面使用 EL 以及定制标签显示数据。

    注意:调用 RequestDispatcher.forward 方法并不会停止执行剩余的代码。因此,若 forward 方法不是最后一行代码,则应显示的返回。

    使用MVC模式的实例

     目录结构如下

    代码如下

    DispatcherServlet.java

    package app16c.servlet;
    
    import java.io.IOException;
    
    import javax.servlet.RequestDispatcher;
    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 app16c.controller.InputProductController;
    import app16c.controller.SaveProductController;
    
    @WebServlet(name = "DispatcherServlet", urlPatterns = {"/product_input.action", "/product_save.action"})
    public class DispatcherServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
           
        public DispatcherServlet() {
            super();
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            process(request, response);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
        
        private void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String uri = request.getRequestURI();
            int lastIndex = uri.lastIndexOf("/");
            String action = uri.substring(lastIndex + 1);
            String dispatcherUrl = null;
            if (action.equals("product_input.action")) {
                InputProductController controller = new InputProductController();
                dispatcherUrl = controller.handleRequest(request, response);
            } else if (action.equals("product_save.action")) {
                SaveProductController controller = new SaveProductController();
                dispatcherUrl = controller.handleRequest(request, response);
            }
            if (dispatcherUrl != null) {
                RequestDispatcher rd = request.getRequestDispatcher(dispatcherUrl);
                rd.forward(request, response);
            }
        }
    }

    Controller.java

    package app16c.controller;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public interface Controller {
        public abstract String handleRequest(HttpServletRequest request, HttpServletResponse response);
    }

    InputProductController.java

    package app16c.controller;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class InputProductController implements Controller {
    
        @Override
        public String handleRequest(HttpServletRequest request, HttpServletResponse response) {
            return "/WEB-INF/jsp/ProductForm.jsp";
        }
    }

    SaveProductController.java

    package app16c.controller;
    
    import java.util.List;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import app16c.domain.Product;
    import app16c.form.ProductForm;
    import app16c.validator.ProductValidator;
    
    public class SaveProductController implements Controller {
    
        @Override
        public String handleRequest(HttpServletRequest request, HttpServletResponse response) {
            ProductForm productForm = new ProductForm();
            productForm.setName(request.getParameter("name"));
            productForm.setDescription(request.getParameter("description"));
            productForm.setPrice(request.getParameter("price"));
            ProductValidator productValidator = new ProductValidator();
            List<String> errors = productValidator.validate(productForm);
            System.out.println(errors);
            if (errors.isEmpty()) {
                Product product = new Product();
                product.setName(productForm.getName());
                product.setDescription(productForm.getDescription());
                product.setPrice(Float.parseFloat(productForm.getPrice()));
                // insert code to save product to the database
                request.setAttribute("product", product);
                return "/WEB-INF/jsp/ProductDetails.jsp";
            } else {
                request.setAttribute("errors", errors);
                request.setAttribute("form", productForm);
                return "/WEB-INF/jsp/ProductForm.jsp";
            }
        }
    }

    ProductValidator.java

    package app16c.validator;
    
    import java.util.ArrayList;
    import java.util.List;
    import app16c.form.ProductForm;
    
    public class ProductValidator {
        public List<String> validate(ProductForm productForm) {
            List<String> errors = new ArrayList<>();
            String name = productForm.getName();
            if (name == null || name.trim().isEmpty()) {
                errors.add("Product must have a name");
            }
            String price = productForm.getPrice();
            if (price == null || price.trim().isEmpty()) {
                errors.add("Product must have a price");
            }else {
                try {
                    Float.parseFloat(price);
                } catch (NumberFormatException e) {
                    errors.add("Invalid price value.");
                }
            }
            return errors;
        }
    }

    Product.java

    package app16c.domain;
    
    import java.io.Serializable;
    
    public class Product implements Serializable { // 一个JavaBean 实现该接口,其实例可以安全的将数据保存到 HttpSession 中。
        private static final long serialVersionUID = 1L;
        private String name;
        private String description;
        private float price;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        public float getPrice() {
            return price;
        }
        public void setPrice(float price) {
            this.price = price;
        }
    }

    ProductForm.java

    package app16c.form;
    
    // 表单类与 HTML表单相映射,是HTML表单在服务端的代表
    public class ProductForm {  // 表单类不需要实现 Serializable 接口,因为表单对象很少保存在 HttpSession 中。
        private String name;
        private String description;
        private String price;
        
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        public String getPrice() {
            return price;
        }
        public void setPrice(String price) {
            this.price = price;
        }
    }

    ProductForm.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>  <!-- taglib指令用来引用标签库并设置标签库的前缀  -->
    
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Add Product Form</title>
        <link rel="stylesheet" type="text/css" href="css/main.css" />  <!-- 外部样式表 -->
    </head>
    <body>
        <div id="global">
            <c:if test="${requestScope.errors != null }">  <!-- EL表达式 -->
                <p id="errors">
                    Error(s)!
                    <ul>
                        <c:forEach var="error" items="${requestScope.errors }">  <!-- jstl 遍历 -->
                            <li>${error }</li>
                        </c:forEach>
                    </ul>
                </p>
            </c:if>
            <form action="product_save.action" method="post">
                <fieldset>
                    <legend>Add a product</legend>
                    <p>
                        <label for="name">Product Name: </label>
                        <input type="text" id="name" name="name" tabindex="1" />
                    </p>
                    <p>
                        <label for="description">Description: </label>
                        <input type="text" id="description" name="description" tabindex="2" />
                    </p>
                    <p>
                        <label for="price">Price: </label>
                        <input type="text" id="price" name="price" tabindex="3" />
                    </p>
                    <p id="buttons">
                        <input id="reset" type="reset" tabindex="4" />
                        <input id="submit" type="submit" tabindex="5" value="Add Product" />
                    </p>
                </fieldset>
            </form>
        </div>
    </body>
    </html>

    ProductDetails.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Save Product</title>
        <link rel="stylesheet" type="text/scc" href="css/main.css" />
    </head>
    <body>
        <div id="global">
            <h4>The product has been saved.</h4>
            <p>
                <h5>Details</h5>
                Product Name: ${product.name } <br />
                Description: ${product.description } <br />
                Price: $${product.price }
            </p>
        </div>
    </body>
    </html>

    测试结果

  • 相关阅读:
    LUA表的引用理解
    UNITY 打包安卓APK
    UNITY打包问题
    U3D 打包时找不到tag的问题
    break prefab instance的原理
    C#调用LUA函数
    LUA 利用#遍历表的问题
    U3D笔记11:47 2016/11/30-15:15 2016/12/19
    Unity3D 预设打包的注意事项
    回调 和 覆盖
  • 原文地址:https://www.cnblogs.com/0820LL/p/9949873.html
Copyright © 2011-2022 走看看