(笔记)Spring MVC学习指南_模型2和MVC模式

来源:互联网 发布:最好的网络云盘 编辑:程序博客网 时间:2024/05/17 02:04

2.模型2介绍
模型2基于模型——视图——控制器(MVC)模式。一个实现MVC模式的应用包含模型、视图和控制器3个模块。视图负责应用的展示。模型封装了应用的数据和业务逻辑。控制器负责接收用户输入,改变模型,以及调整视图的显示。
Servlet或者Filter都可以充当控制器。大部分都采用JSP页面作为应用的视图,当然也有其他技术。而模型则采用POJO。不同于EJB等,POJO是一个普通对象。实践中会采用一个JavaBean来持有模型状态,并将业务逻辑放到一个Action类中。
每个HTTP请求都发送给控制器,请求中的URI标识出对应的action。action代表了应用可以执行的一个操作。一个action类可以支持多个action,或者一个action。
控制器会解析URI并调用相应的action,然后将模型对象放到视图可以访问的区域(以便服务端数据可以展示在浏览器上)。最后,控制器利用RequestDispatcher跳转到视图(JSP页面)。在JSP页面中,用表达式语言以及定制标签显示数据。
3.模型2之Servlet控制器
ControllerServlet.java

package app02a.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 app02a.domain.Product;import app02a.form.ProductForm;/** * 这里遵从了一个约定:所有Servlet的类名称都带有servlet后缀。 */@WebServlet(name = "ControllerServlet", urlPatterns = {"/product_input.action",    "/product_save.action"})public class ControllerServlet extends HttpServlet{    private static final long serialVersionUID = 9111454017486497956L;    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException    {        process(req, resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException    {        process(req, resp);    }    private void process(HttpServletRequest request, HttpServletResponse response)        throws ServletException, IOException    {        String uri = request.getRequestURI();        int lastIndex = uri.lastIndexOf("/");        String action = uri.substring(lastIndex + 1);        if ("product_input.action".equals(action))        {            // no action class,there is nothing to be done        }        else if ("product_save.action".equals(action))        {            // create form            ProductForm productForm = new ProductForm();            productForm.setName(request.getParameter("name"));            productForm.setDescription(request.getParameter("description"));            productForm.setPrice(request.getParameter("price"));            // create model            Product product = new Product();            product.setName(productForm.getName());            product.setDescription(productForm.getDescription());            try            {                product.setPrice(Float.parseFloat(productForm.getPrice()));            }            catch (NumberFormatException e)            {}            // code to save product            // store model in a scope variable for the view            request.setAttribute("product", product);        }        String dispatchUrl = null;        if ("product_input.action".equals(action))        {            dispatchUrl = "/WEB-INF/jsp/ProductForm.jsp";        }        else if ("product_save.action".equals(action))        {            dispatchUrl = "/WEB-INF/jsp/ProductDetails.jsp";        }        if (dispatchUrl != null)        {            RequestDispatcher rd = request.getRequestDispatcher(dispatchUrl);            rd.forward(request, response);        }    }}

ProductDetails.jsp

<!DOCTYPE HTML><html><head><title>Save Product</title></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}<br />        </p>    </div></body></html>

4.解耦控制器代码
将业务逻辑代码提取到独立的被称为controller的类中。
DispatcherServlet.java

package app02b.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 app02b.controller.InputProductController;import app02b.controller.SaveProductController;/** * 这里遵从了一个约定:所有Servlet的类名称都带有servlet后缀。 */@WebServlet(name = "DispatcherServlet", urlPatterns = {"/product_input.action",    "/product_save.action"})public class DispatcherServlet extends HttpServlet{    private static final long serialVersionUID = 9111454017486497956L;    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException    {        process(req, resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp)        throws ServletException, IOException    {        process(req, resp);    }    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 dispatchUrl = null;        if ("product_input.action".equals(action))        {            InputProductController controller = new InputProductController();            dispatchUrl = controller.handleRequest(request, response);        }        else if ("product_save.action".equals(action))        {            SaveProductController controller = new SaveProductController();            dispatchUrl = controller.handleRequest(request, response);        }        if (dispatchUrl != null)        {            RequestDispatcher rd = request.getRequestDispatcher(dispatchUrl);            rd.forward(request, response);        }    }}

Controller.java

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

InputProductController.java

package app02b.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 app02b.controller;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import app02b.domain.Product;import app02b.form.ProductForm;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"));        // create model        Product product = new Product();        product.setName(productForm.getName());        product.setDescription(productForm.getDescription());        try        {            product.setPrice(Float.parseFloat(productForm.getPrice()));        }        catch (NumberFormatException e)        {}        // insert code to add product to the database        request.setAttribute("product", product);        return "/WEB-INF/jsp/ProductDetails.jsp";    }}

5.校验器
现代的MVC框架通常同时支持编程式和申明式两种校验方法。在编程式中,需要通过编码进行用户输入校验,而在申明式中,则需要提供包含校验规则的XML文档或者属性文件。
SaveProductController.java

package app02c.controller;import java.util.List;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import app02c.domain.Product;import app02c.form.ProductForm;import app02c.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"));        // validate ProductForm        ProductValidator productValidator = new ProductValidator();        List<String> errors = productValidator.validate(productForm);        if (errors.isEmpty())        {            // create Product from ProductForm            Product product = new Product();            product.setName(productForm.getName());            product.setDescription(productForm.getDescription());            product.setPrice(Float.parseFloat(productForm.getPrice()));            // no validation error,execute action method            // insert code to add 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";        }    }}

ProductForm.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><!DOCTYPE HTML><html><head><title>Add Product Form</title></head><body>    <div id="global">        <c:if test="${requestScope.errors != null}">            <p id="errors">Error(s)!            <ul>                <c:forEach var="error" items="${requestScope.errors}">                    <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>

web.xml

    <jsp-config>        <taglib>            <taglib-uri>http://java.sun.com/jstl/core</taglib-uri>            <taglib-location>/WEB-INF/c.tld</taglib-location>        </taglib>    </jsp-config>

下载jakarta-taglibs-standard-1.1.2.zip 包并解压,将jakarta-taglibs-standard-1.1.2/lib/下的两个jar文件:standard.jar和jstl.jar文件拷贝到/WEB-INF/lib/下。
官方下载地址:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/

0 0