使用符合MVC设计模式的自定义框架实现加法计算器

1.1自定义MVC框架

  【示例1.1】使用符合MVC设计模式的自定义框架实现加法计算器,要求所有的请求都发送给控制器,控制器根据请求路径找到相应的Action(表示针对用户请求的一种处理操作)进行处理,Action调用模型执行业务操作并获取数据,最后将结果返回给视图。

  使用自定义MVC框架开发加法器程序的结构图如图1-1所示。

图1-1 加法器的MVC结构图

​  此加法器程序需要用户在add.jsp页面中输入两个数,单击“加”按钮进行计算,计算结果在add_result.jsp页面显示,如图1-2所示。

图1-2 加法器运行效果

1.1.1实现控制器

​  自定义的MVC框架的核心是控制器的实现:定义Action接口,实现Controller类。

​  开发工具为IntelliJ IDEA 2021.2.1

​  首先在com.dh.ch01.framework包中创建Action接口,代码如下:

public interface Action {
    //定义该接口的实现类必须实现的execute方法
    String execute(HttpServletRequest request,HttpServletResponse response);
}

  上述Action接口中定义了一个execute()方法,该方法有请求对象request和响应对象response两个参数;该方法返回一个字符串类型的值,表示执行完操作后要转发到的页面。Action接口对各种动作的执行方法进行统一,便于在控制器中进行调用和访问。

​  此处插入AddAction.java的部分代码,否则执行代码会出错。

​  然后在com.dh.ch01.framework包中创建一个名为Controller的Servlet,代码如下:

/**
 * 自定义MVC框架:基于servlet实现的控制器
 */
public class Controller extends HttpServlet {
    //声明由控制器Controller维护的Action映射,其中保存所有的Action实例
    private HashMap actionMap;

    /**
     * Servlet初始化方法
     */
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
        //初始化actionMap
        actionMap = new HashMap();
        //将AddAction对象放入到actionMap中
        actionMap.put("add", new AddAction());
    }

    /**
     * 根据path判断由哪个action执行操作
     */
    private Action determinActionByPath(String path) {
        //如:从http://localhost:8080/ch01/add.action中得到add
        String actionName = path.substring(path.lastIndexOf('/') + 1, path.length() - 7);
        //获得该请求对应的action对象
        Action ret = (Action) actionMap.get(actionName);
        return ret;
    }

    /**
     * 处理页面以get方式提交的请求
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //得到path
        String path = request.getServletPath();
        //找出Action
        Action action = (Action) this.determinActionByPath(path);
        //执行操作
        String resultView = action.execute(request, response);
        //控制页面转向
        if (null != resultView) {
            request.getRequestDispatcher(resultView).forward(request, response);
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //执行doGet方法
        doGet(request, response);
    }
}

​  上述的Contriller类是基于Servlet技术实现的一个控制器,在处理每次请求时,首先根据请求路径找到将要被执行的Action对象,然后调用Action对象中的execute()方法,最后根据execute()方法返回的路径转发到相应的页面。

  Controller类是一个Serblet,因此在web.xml中需要对其进行如下配置:

<servlet>
    <!-- 使用自定义的控制器 -->
    <servlet-name>Controller</servlet-name>
    <servlet-class>com.dh.ch01.framework.Controller</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Controller</servlet-name>
    <!-- 请求匹配类型 -->
    <url-pattern>*.action</url-pattern>
</servlet-mapping>

​  在上述Servlet配置中,所有以".action"结尾的请求全部派发到Controller类进行处理。因此Action接口和Controller类组成了自定义MVC框架中核心的控制器部分。

1.1.2 实现加法器功能

​  框架提供了控制器,也规定好了模型和视图的集成方式,这样在此自定义框架上开发加法器可按照如下4个步骤进行。

​  (1) 创建add.jsp页面,用于接收用户输入数据;

​  (2) 创建业务逻辑类Calculator,实现数据的算术运算;

​  (3) 创建AddAction类,该类实现Action接口。在execute()方法中获取add.jsp页面中的表单数据,并调用Calculator进行计算;

​  (4) 创建add_result.jsp页面,用于显示计算结果。

​  下面对实现加法器功能的4个步骤进行详细介绍

​  1. 创建add.jsp页面

​  在WebContent目录中创建add.jsp页面用于接收两个数值。页面代码如下:

<%@ page contentType="text/html;charset=GBK" language="java" %>
<html>
<head>
    <title>计算器</title>
</head>
<body bgcolor="#ffffc0">
<h1>算术计算器</h1>
<form id="calcForm" method="post" action="add.action">
<table>
    <tbody>
        <tr>
            <td>第一个数</td>
            <td><input type="text" name="num1"/></td>
        </tr>
        <tr>
            <td>第二个数</td>
            <td><input type="text" name="num2"/></td>
        </tr>
        <tr>
            <td><input type="submit" value="加"/></td>
        </tr>
    </tbody>
</table>
</form>
</body>
</html>

​  在上述页面中,表单的action属性值为"add.action",即表单提交给"add.action"处理。同时,因为,在web.xml中已经配置了所有以".action"结尾的请求全部派发到Controller进行处理,所以此表单会提交给Controller类处理。

​  2. 创建Calculator类

​  在com.dh.ch01.biz包中创建Calculator类,进行加减乘除运算。代码如下:

public class Calculator {
    /**
     * 实现算数加法
     */
    public double add(double a, double b) {
        return a + b;
    }

    /**
     * 实现算数减法
     */
    public double sub(double a, double b) {
        return a - b;
    }

    /**
     * 实现算数乘法
     */
    public double mul(double a, double b) {
        return a * b;
    }

    /**
     * 实现算数除法
     */
    public double div(double a, double b) {
        if (b == 0) {
            return 0;
        } else {
            return a / b;
        }
    }
}

​  3. 创建AddAction类

​  在com.dh.ch01.action包中创建AddAction类,该类实现Action接口,代码如下:

public class AddAction implements Action {
    //业务逻辑对象
    private Calculator biz = new Calculator();
    public String execute(HttpServletRequest request, HttpServletResponse response) {
        //获得页面输入
        double num1 = Double.parseDouble(request.getParameter("num1"));
        double num2 = Double.parseDouble(request.getParameter("num2"));
        //调用业务逻辑方法,获得返回值
        double result = biz.add(num1, num2);
        //将结果存放在request中,以便在页面中得到
        request.setAttribute("result", result);
        //返回将要转发的页面路径
        return "add_result.jsp";
    }
}

​  在上述AddAction类的execute()方法中,首先从request中获取表单数据并转换成double类型,然后调用Calculator类的对象"biz"中的add()方法进行计算,再将结果保存到request对象的属性中,最后返回将要转发的页面add_result.jsp。

​  4.创建add_result.jsp页面

​  在WebContent目录中创建add_result.jsp页面,显示计算结果值。代码如下:

<%@ page contentType="text/html;charset=GBK" pageEncoding="GBK" language="java" %>
<html>
<head>
<title>计算器</title>
</head>
<body bgcolor="#ffffc0">
<h1>算术计算器</h1>
<table>
    <tbody>
        <tr>
            <td>第一个数</td>
            <td>${param.num1}</td>
        </tr>
        <tr>
            <td>第二个数</td>
            <td>${param.num2}</td>
        </tr>
        <tr>
            <td>结果</td>
            <!-- 使用EL表达式显示结果 -->
            <td>${requestScope.result}</td>
        </tr>
    </tbody>
</table>
<button onclick="history.go(-1);">返回</button>
</body>
</html>

​  上述页面代码中使用EL表达式显示结果。程序的运行结果如图1-2所示。

  通过先自定义MVC框架然后用其开发加法器的过程,读者可以体会到在开发过程中使用框架所带来的便利和限制,初步了解框架的功能及作用,为学习Strust2做好充分的准备。

posted @ 2021-09-01 18:35  柳若絮  阅读(447)  评论(0编辑  收藏  举报