实现简单的支持加、减、乘、除的计算器

复制一份Struts1Demo修改:Struts1Calc

方案1: Struts1Calc

创建ActionForm:

CalcForm extends ActionForm, num1 num2,生成getter setter;

创建4个Action,在页面中,通过JavaScript控制提交到不同的Action Bean。

AddAction:

public class AddAction extends Action {
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		CalcForm cf = (CalcForm) form;
		int result  = cf.getNum1()+cf.getNum2();
		request.setAttribute("result", result);
		return mapping.findForward("success");
	}
}

其他三个省略。。

在wen.xml的servlet

添加

    <load-on-startup>1</load-on-startup>

struts-config.xml里面的配置:

	<!-- Form -->
	<form-beans>
		<form-bean name="calcForm" type="com.demo.form.CalcForm"></form-bean>
	</form-beans>

	<!-- Action -->
	<action-mappings>
		<action name="calcForm" path="/add" type="com.demo.action.AddAction"
			scope="request">
			<forward name="success" path="/result.jsp"></forward>
			<forward name="input" path="/calc.jsp"></forward>
		</action>
	</action-mappings>

其他三个配置省略…

添加clac.jsp

  </head>
  <script type="text/javascript">
  	function calc(c){
  		document.getElementById("form").action=c+".do";
  		document.getElementById("form").submit();
  	}
  </script>
  <body>
	  <form id="form" action="#" method="post">
	  	第一个数:<input name="num1"><br/>
	  	第二个数:<input name="num2"><br/>
	  	<input type="button" value="加" onclick="calc('add')">
	  	<input type="button" value="减" onclick="calc('sub')">
	  	<input type="button" value="乘" onclick="calc('mul')">
	  	<input type="button" value="除" onclick="calc('div')">
	  </form>
  </body>

添加result.jsp



第一个数:${requestScope.calcForm.num1 }

<br /> 第二个数:${requestScope.calcForm.num2 }

<br /> 结构:${requestScope.result}

部署访问:

http://localhost:8080/Struts1Calc/calc.jsp

源码下载

http://pan.baidu.com/s/1kTDRVi3

方案2:

增加隐藏表单域,表示操作类型 ,在Action Bean中根据不同操作类型做不同处理。

在calc.jsp表单添加:

<input
id="oper"
name="oper" type="hidden"value="oper">

脚本修改为:

 <script type="text/javascript">
  	function calc(c){
  		/* document.getElementById("form").action=c+".do"; */
  		document.getElementById("oper").value=c;
  		document.getElementById("form").submit();
  	}
  </script>

将form的action修改为action="calc.do"

struts-config.xml里面的<action-mappings>的calcForm的path修改为calc 配置:

		<action name="calcForm" path="/calc" type="com.demo.action.CalcAction" scope="request">
			<forward name="success" path="/result.jsp"></forward>
			<forward name="input" path="/calc.jsp"></forward>
		</action>

在CalcForm添加

private String oper;

和getter和setter方法;

修改CalcAction

public class CalcAction extends Action {
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		CalcForm cf = (CalcForm) form;
		int result = 0;
		if("add".equals(cf.getOper())){
			result  = cf.getNum1()+cf.getNum2();
		}else if("div".equals(cf.getOper())){
			result = cf.getNum1()/cf.getNum2();
		}
		//....
		request.setAttribute("result", result);
		return mapping.findForward("success");
	}
}

部署访问:

http://localhost:8080/Struts1Calc2/calc.jsp 测试加和除;

源码:http://pan.baidu.com/s/1c0nbPsc

使用DispatchAction

以上两个方案说明:

方案1对每个操作都创建一个Action,系统规模变大时,容易混乱

方案2将相关操作组织在一个Action中,通过operate参数区分不同操作,但容易使Action中execute方法的代码过长,不易维护

使用DispatchAction实现计算机器的步骤:

复制上一个项目Struts1Calc2修改为:Struts1CalcDispatchAction

1. 创建CalcAction,继承自DispatchAction

2. 在CalcAction中创建加、减、乘、除四个方法

打ex 按alt+/  选择参数HttpServletResponse ... 然后将方法名改为add、div...

public ActionForward add(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		CalcForm cf = (CalcForm) form;
		int result = 0;
		result = cf.getNum1() + cf.getNum2();
		request.setAttribute("result", result);
		return mapping.findForward("success");
	}
		/*
		public ActionForward div  …
		public ActionForward sun   …
		public ActionForward mul   …
		*/

在struts-config.xml中配置CalcAction

在action-mapping里  parameter="oper"

		<action name="calcForm" path="/calc" type="com.demo.action.CalcAction"
			scope="request" parameter="oper">
			<forward name="success" path="/result.jsp"></forward>
			<forward name="input" path="/calc.jsp"></forward>
		</action>

Parameter里有oper, calc.jsp里面也要有对应



<input id="oper" name="oper" type="hidden" value="oper">







3. 编写页面代码

不修改页面;

Dispatch的运行原理

DispatchAction能够根据传入参数值自动选择Action中同名的方法执行

Parameter有点类似我们Struts2的method;

部署运行:

http://localhost:8080/Struts1CalcDispatchAction1/calc.jsp

源码:http://pan.baidu.com/s/1bnnJOIV

显示友好的报错信息

Struts提供了报错机制,用于提供友好的报错信息给用户

被除数为0,非数字等

新建属性文件 ApplicationResources.properties 在com.demo.resources下

通过在属性文件中定义errors.header和errors.footer属性设定错误信息格式

修改配置文件 struts-config

<message-resources parameter="com.demo.resources.ApplicationResources"></message-resources>

修改对应Action方法

输入的时候不是数字 和被除数是零的时候 ,这里只做div除

	public ActionForward div(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		CalcForm cf = (CalcForm) form;
		ActionMessages errors = new ActionMessages();
		if (!this.isFloat(cf.getNum1())) {
			errors.add("error1",
					new ActionMessage("error.valudate.inputnumber"));
		}
		if (this.isZero(cf.getNum2())) {
			errors.add("error2", new ActionMessage("error.valudate.number"));
		}
		if (!errors.isEmpty()) {
			super.saveErrors(request, errors);
			return mapping.findForward("input");
		}
		int result = 0;
		result = cf.getNum1() / cf.getNum2();
		request.setAttribute("result", result);
		return mapping.findForward("success");

	}

	private boolean isZero(int num2) {
		return num2 == 0;
	}

	private boolean isFloat(int i) {
		if (i==0)
			return false;
		else
			return true;
	}

在页面上显示报错信息

<%@ taglib prefix="html" uri="http://struts.apache.org/tags-html" %>

	  	第一个数:<input name="num1"><html:errors property="error1" /><br/>
	  	第二个数:<input name="num2"><html:errors property="error2" /><br/>

部署运行 被除数输入0 测试;http://localhost:8080/Struts1CalcDispatchAction1/calc.jsp

源码 http://pan.baidu.com/s/1eQcOx38

显示友好的报错信息第二种方式

添加到全局错误信息中,作用域是request

if (!this.isFloat(cf.getNum1())) {
			errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
					"error.valudate.inputnumber"));
			// errors.add("error1",new
			// ActionMessage("error.valudate.inputnumber"));
		}
		if (this.isZero(cf.getNum2())) {
			// errors.add("error2", new ActionMessage("error.valudate.number"));
			errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
					"error.valudate.number"));
		}

vlac.jap 里使用 <html:errors /> 显示所有错误信息;

使用动态Form简化开发

使用Struts框架开发时,对每一个页面提交的属性都要建立一个ActionForm属性

回顾计算器的ActionForm属性
1. 只有两个属性
2. 如果处理复杂的业务时,属性可能会非常的多
3. 容易漏改出错
4. 大量的“纯体力”代码充斥其中

解决问题 使用动态Form

以配置的方式创建Form  struts-config.xml:

<form-beans>
	<form-bean name="calcDynaForm" type="org.apache.struts.action.DynaActionForm">
		<form-property name="num1" type="java.lang.Integer" />
		<form-property name="num2" type="java.lang.Integer" />
	</form-bean>
</form-beans>

和使用普通Form一样

		<action name="calcDynaForm" parameter="oper" path="/calc"
			scope="request" type="com.demo.action.CalcAction">
			<forward name="success" path="/result.jsp"></forward>
			<forward name="input" path="/calc.jsp"></forward>
		</action>

Action代码

……

DynaActionForm cf =(DynaActionForm) form;

……

result =(Integer)cf.get("num1")/(Integer)cf.get("num2");

……

使用实体对象作为Form属性

  使用动态ActionForm的好处
  省去了编写ActionForm类
  页面提交数据变化时只须修改struts-config.xml中的配置
  使用动态ActionForm的缺陷
  Action中的代码并没有因此变得简单
  业务逻辑变化、数据库增减字段时,需要修改的地方包括实体类、动态ActionForm定义和Action 中相应代码
  容易漏掉某处而引入错误

使用实体对象作为Form属性

我们已经知道:

页面提交的表单数据,可以自动填充到ActionForm中





假如,ActionForm的代码是这样的:

public class UserForm 

extends ActionForm {

    private USER user = new USER();

    // getter and setter

}





假如,页面代码是这样的:

<input name="user.uname" />





表单域的值是否能够自动填充到Form中呢?

复制一份Struts1Demo,修改为Struts1Login

ActionForm代码

public class LoginForm extends ActionForm {
	private User user = new User();
	private String rePassword;

struts-config.xml

<struts-config>
	<!-- Form -->
	<form-beans>
		<form-bean name="userLoginForm" type="com.demo.form.LoginForm"></form-bean>
	</form-beans>

	<!-- Action -->
	<action-mappings>
		<action name="userLoginForm" path="/login" type="com.demo.action.LoginAction"
			scope="request">
			<forward name="success" path="/success.jsp"></forward>
			<forward name="input" path="/index.jsp"></forward>
		</action>
	</action-mappings>
</struts-config>

Action代码

if (userBiz.login(lf.getUser())) { ...

避免了“纯体力”型编码, 数据库字段增减时,无需修改Form和Action代码

源码:http://pan.baidu.com/s/1sjucV85

Struts1应用、实现简单计算器、使用DispatchAction、显示友好的报错信息、使用动态Form简化开发的更多相关文章

  1. ionic使用iframe时无法显示网页或报错

    ionic使用iframe时无法显示网页或报错 Uncaught DOMException: Blocked a frame with origin 在config.xml中添加 <access ...

  2. Ubuntu下开启php调试模式,显示报错信息

    在Ubuntu下php的缺省设置是不显示错误信息的,如果程序出错会显示“无法处理此请求的错误提示”,这在开发环境下非常不方便. 其实我们只要编辑下apache的配置文件就好 1.我的apache 配置 ...

  3. lamp 网站打不开,不显示也不报错,

    原因是该网站的编程员,习惯简写,<? ?>;而服务器版本的php.ini 默认不支持只支持<?php ?>这种格式. 解决方法vim /usr/loacl/php/etc/ph ...

  4. JUnit出错,却没有显示任何报错信息【待解答】

    JUnit测试代码如下: 原因分析: JUnit测试单元里,测试函数好像不能带参数? 解决办法: 发现测试函数testBookShopDaoUpdateBookStock(int isbn)里的参数i ...

  5. 简单记录一次REDO文件损坏报错 ORA-00333重做日志读取块出错

    一.故障描写叙述 首先是实例恢复须要用到的REDO文件损坏 二.解决方法 1.对于非当前REDO或者当前REDO可是无活动事务使用下面CLEAR命令: 用CLEAR命令重建该日志文件SQL>al ...

  6. springboot启动只显示图标不报错

    问题如下: 问题原因是:logback.xml文件中日志打印级别设置的有问题.设置不打印

  7. php大力力 [005节] php大力力简单计算器001

    2015-08-22 php大力力005. php大力力简单计算器001: 上网看视频,看了半天,敲击代码,如下: <html> <head> <title>简单计 ...

  8. py+selenium 自动判断页面是否报错并显示在自动化测试报告【原创】

    有需求就会去研究解决的路子. 现在需求就是,测试报告报错信息一堆,但却无法肉眼看出是什么问题,你只能知道定位不到元素或是超时,但你却不知道其实进入页面就报错了或是提交表单就报错了!也就是看到报错,需要 ...

  9. IIS7显示ASP的详细错误信息到浏览器

    服务端环境:Windows2008 + IIS7 客户端浏览器设置:取消“显示友好的HTTP错误信息” IIS7设置(GUI): 1. 网站->ASP->调试属性->将错误发送到浏览 ...

随机推荐

  1. XMLHTTPRequestObject获取服务器数据

    http://www.educity.cn/develop/526316.html 在Web客户端使用xmlhttp对象,可以十分方便的和服务器交换数据,我们可以获取和发送任何类型的数据,甚至二进制数 ...

  2. [Codeforces 933B]A Determined Cleanup

    Description 题库链接 给你两个正整数 \(p,k\) ,询问是否能够构造多项式 \(f(x)=\sum\limits_{i=0}^{d-1}a_ix^i\) ,使得存在多项式 \(q(x) ...

  3. [CODEVS 1288]埃及分数

    Description 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/ ...

  4. [SHOI2008]汉诺塔

    Description 汉诺塔由三根柱子(分别用A B C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上, 大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的 ...

  5. [SCOI2005]最大子矩阵

    题目描述 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注意:选出的k个子矩阵不能相互重叠. 输入输出格式 输入格式: 第一行为n,m,k(1≤n≤100,1≤m≤2 ...

  6. [BZOJ]4650: [Noi2016]优秀的拆分

    Time Limit: 30 Sec  Memory Limit: 512 MB Description 如果一个字符串可以被拆分为 AABBAABB 的形式,其中 AA 和 BB 是任意非空字符串, ...

  7. ●BZOJ 3238 [Ahoi2013]差异

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3238 题解: 后缀数组套路深. 问题转化为求出任意两个后缀的LCP之和 在计算贡献时,各种不 ...

  8. 【Bzoj 1835 基站选址】

    基站选址的区间里隐藏着DP优化的机密…… 分析:       不论是做过乘积最大还是石子合并,或者是其他的入门级别的区间DP题目的人呐,大米并认为读题后就能够轻松得出一个简洁明了的Dp转移方程.    ...

  9. SpringMVC 处理映射

    一.Spring MVC控制器名称处理映射 以下示例展示如何利用Spring MVC 框架使用控制器名称处理程序映射. ControllerClassNameHandlerMapping类是基于约定的 ...

  10. Python中模块之copy的功能介绍

    模块之copy的功能介绍 copy主要分两种: 1.浅拷贝 2.深拷贝 赋值: 在python中赋值算特殊的拷贝,其实赋值可以理解为同一个对象有两个名字,所以当其中一个发生变化,另一个也跟着会变化. ...