使用符合MVC设计模式的自定义框架实现加法计算器
1.1自定义MVC框架
【示例1.1】使用符合MVC设计模式的自定义框架实现加法计算器,要求所有的请求都发送给控制器,控制器根据请求路径找到相应的Action(表示针对用户请求的一种处理操作)进行处理,Action调用模型执行业务操作并获取数据,最后将结果返回给视图。
使用自定义MVC框架开发加法器程序的结构图如图1-1所示。
此加法器程序需要用户在add.jsp页面中输入两个数,单击“加”按钮进行计算,计算结果在add_result.jsp页面显示,如图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做好充分的准备。