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

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值