ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

手写tomcat(四)-WEB服务器测试-网银转账系统

2020-02-06 17:03:33  阅读:280  来源: 互联网

标签:WEB tomcat ps 网银 sql print import balance out


1.引言

在前几章我们已经设计并完成了 WEB 服务器的研发,接下来我们开发一个简单的网银转账系统对 WEB 服务器进行测试。 以下我们的开发角色都是 WebApp 的开发人员。 我们给该 Web 应用起名为bank。

2.mytomcat【准备工作】

大家是否还记得在 WEB 服务器开发阶段,有这样一段代码是写死的,如下图所示:
在这里插入图片描述
看上图中的 BootStrap 类,该类是 WEB 服务器开发人员开发,在服务器启动阶段解析每个 WebApp的 web.xml 文件,程序中我们将 WebApp 的名字固定写入,显然设计不够合理,这里我们就不再解决了,大家可以想一想怎么解决这个问题。不过我们要新建一个 WebApp,并且起名为 bank,所以我们需要在字符串数组中添加新的 WebApp,如下图所示:

//解析服务中包含的web.xml配置文件
String[] webAppNames = {"oa","bank"};

接下来 WebApp 开发人员开始进行准备工作,创建一个符合规范的 WebApp 的目录结构,并编写
合法的 web.xml 文件,如下图所示:
在这里插入图片描述
接下来我们简单的设计一下该系统的功能,该系统主要功能是完成银行账户转账,但是转账之前必须先进行开户操作,所以该系统一共两个功能,

第一:开户功能,
第二:转账功能。

这两个功能其实用户群不同,开户功能实际上是银行业务员使用的。转账功能是银行账户持有者使用的。 我们这里就不再分系统角色了。只要简单的实现这两个功能即可。

完成以上功能,先进行数据库的设计,我们这里就使用学过的 MySQL 数据吧,数据库设计一张表即可,该表叫做账户表 t_act,该账户表中存储银行账户信息,该表的字段简单设计包括:唯一标识(id)、账号(actno)、余额(balance),数据库账户表建表语句如下图所示:

DROP TABLE IF EXISTS t_act;

CREATE TABLE t_act (
	id INT (10) PRIMARY KEY auto_increment,
	actno VARCHAR (32) NOT NULL UNIQUE,
	balance DOUBLE (7, 2)
)

创建表完成之后,将连接数据库的 MySQL 驱动 jar 包配置到环境变量当中,如下图所示:
在这里插入图片描述

2.mytomcat【实现开户】

2.1 准备开户页面

<html>
	<head>
		<title>银行帐户-开户</title>
		<meta content="text/html;charset=utf-8"/>
	</head>
	<body>
		<form name="actOpenForm" action="/bank/act/open" method="get">
			银行帐户:
				<input type="text" name="actno"/>
				<br><br>
			开户金额:
				<input type="text" name="balance"/>
				<br><br>
				<input type="submit" value="确认开户"/>
				<input type="reset" value="重置"/>
		</form>
	</body>
</html>

在这里插入图片描述
启动 服务器,打开浏览器输入以下 URL,发送请求,访问结果如下图所示:
在这里插入图片描述

2.2 编辑配置文件 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    <servlet>
        <servlet-name>actOpenServlet</servlet-name>
        <servlet-class>org.bruceliu.bank.servlet.ActOpenServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>actOpenServlet</servlet-name>
        <url-pattern>/act/open</url-pattern>
    </servlet-mapping>
</web-app>

在这里插入图片描述

2.3 编写 ActOpenServlet 实现开户功能

package org.bruceliu.bank.servlet;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ActOpenServlet implements Servlet {

	@Override
	public void service(ServletRequest request, ServletResponse response) {
		//-----------从页面获取参数值------------
		String actno = request.getParameterValue("actno");
		double balance = Double.parseDouble(request.getParameterValue("balance"));
		
		//---------------连接数据库-------------
		Connection conn = null;
		PreparedStatement ps = null;
		int count = 0;
		try {
			// 1.加载驱动 放入Mysql驱动类的全路径,让JVM预先加载这个类到内存中
			Class.forName("com.mysql.jdbc.Driver");
			//2.获取数据库的连接对象
			conn= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bankdb?useUnicode=true&characterEncoding=UTF-8&useSSL=true","root","123456");
			//3.定义SQL语句框架
			String sql = "insert into t_act(actno,balance) values(?,?)";
			//4.进行SQL语句预编译
			ps = conn.prepareStatement(sql);
			//5.进行赋值
			ps.setString(1, actno);
			ps.setDouble(2, balance);
			//6.执行SQL语句
			count = ps.executeUpdate();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//关闭资源
			if(ps != null){
				try {
					ps.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(conn != null){
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		//获取响应流对象
		PrintWriter out = response.getWriter();
		if(count == 1){
			out.print("<html>");
			out.print("<head>");
			out.print("<title>银行帐户-开户结果</title>");
			out.print("<meta content='text/html;charset=utf-8'/>");
			out.print("</head>");
			out.print("<body>");
			out.print("<center><font size='35px' color='green'>恭喜您,开户成功!</font></center>");
			out.print("</body>");
			out.print("</html>");
		}else{
			out.print("<html>");
			out.print("<head>");
			out.print("<title>银行帐户-开户结果</title>");
			out.print("<meta content='text/html;charset=utf-8'/>");
			out.print("</head>");
			out.print("<body>");
			out.print("<center><font size='35px' color='red'>对不起,开户失败!</font></center>");
			out.print("</body>");
			out.print("</html>");
			
		}
	}

}


2.4 测试开户功能

启动服务器,打开浏览器访问开户页面,填写表单,点击开户,运行结果如下所示:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
再开立一个账户
在这里插入图片描述

3. mytomcat【实现转账】

3.1 准备转账页面

<html>
	<head>
		<title>银行帐户-转帐</title>
		<meta content="text/html;charset=utf-8"/>
	</head>
	<body>
		<form name="actTransferForm" action="/bank/act/transfer" method="get">
			转出帐号:
				<input type="text" name="actFrom"/>
				<br><br>
			转出金额:
				<input type="text" name="balance"/>
				<br><br>
			转入帐号:
				<input type="text" name="actTo"/>
				<br><br>
				<input type="submit" value="确认转帐"/>
				<input type="reset" value="重置"/>
		</form>
	</body>	
</html>

启动 httpserver,打开浏览器输入 URL,发送请求访问结果如下所示:
在这里插入图片描述

3.2 编辑配置文件 web.xml

 <servlet>
     <servlet-name>actTransferServlet</servlet-name>
     <servlet-class>org.bruceliu.bank.servlet.ActTransferServlet</servlet-class>
 </servlet>
 <servlet-mapping>
     <servlet-name>actTransferServlet</servlet-name>
     <url-pattern>/act/transfer</url-pattern>
 </servlet-mapping>

3.3 编写转账的 ActTransferServlet 类

package org.bruceliu.bank.servlet;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ActTransferServlet implements Servlet {

	@Override
	public void service(ServletRequest request, ServletResponse response) {
		//------------获取页面请求的参数------------
		String actFrom = request.getParameterValue("actFrom");
		double balance = Double.parseDouble(request.getParameterValue("balance"));
		String actTo = request.getParameterValue("actTo");
		
		//-----------连接数据库---------------
		Connection conn = null;
		PreparedStatement ps = null;
		int count = 0;
		try {
			//1.注册驱动
			// 1.加载驱动 放入Mysql驱动类的全路径,让JVM预先加载这个类到内存中
			Class.forName("com.mysql.jdbc.Driver");
			//2.获取数据库的连接对象
			conn= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bankdb?useUnicode=true&characterEncoding=UTF-8&useSSL=true","root","123456");
			//3.定义SQL语句框架
			String sql_from = "update t_act set balance = balance - ? where actno = ?";
			//4.进行SQL语句的预编译
			ps = conn.prepareStatement(sql_from);
			//5.进行赋值
			ps.setDouble(1, balance);
			ps.setString(2, actFrom);
			//6.执行SQL语句
			count = ps.executeUpdate();
			
			
			String sql_to = "update t_act set balance = balance + ? where actno = ?";
			ps = conn.prepareStatement(sql_to);
			ps.setDouble(1, balance);
			ps.setString(2, actTo);
			count = count + ps.executeUpdate();
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			//关闭资源
			if(ps != null){
				try {
					ps.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(conn != null){
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		//获取响应流对象
		PrintWriter out = response.getWriter();
		if(count == 2){
			out.print("<html>");
			out.print("<head>");
			out.print("<title>银行帐户-转帐结果</title>");
			out.print("<meta content='text/html;charset=utf-8'/>");
			out.print("</head>");
			out.print("<body>");
			out.print("<center><font size='35px' color='green'>转帐成功!</font></center>");
			out.print("</body>");
			out.print("</html>");
		}else{
			out.print("<html>");
			out.print("<head>");
			out.print("<title>银行帐户-转帐结果</title>");
			out.print("<meta content='text/html;charset=utf-8'/>");
			out.print("</head>");
			out.print("<body>");
			out.print("<center><font size='35px' color='red'>转帐失败!</font></center>");
			out.print("</body>");
			out.print("</html>");
			
		}
	}

}


3.4 测试转账功能

转账之前的数据:
在这里插入图片描述
启动服务器,打开浏览器,输入 URL,访问转账页面,如下图所示:
在这里插入图片描述
在这里插入图片描述

3.5 mytomcat【事务】

JDBC 事务默认情况下支持的是自动提交,也就是说只要执行任意一条 DML 语句就会提交一次,
这显然是不符合现实的业务逻辑的,因为银行转账是从账户 A 转到账户 B 中,从账户 A 中转出需要执行一条 update 语句,向账户 B 中转入需要执行一条 update 语句,必须这两条 update 同时成功,或者同时失败,两条都成功则最终提交数据,如果转账过程中发生了异常,为了保证数据的安全,回滚操作。 代码如下图所示:

package org.bruceliu.bank.servlet;

import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ActTransferServlet implements Servlet {

	@Override
	public void service(ServletRequest request, ServletResponse response) {
		//------------获取页面请求的参数------------
		String actFrom = request.getParameterValue("actFrom");
		double balance = Double.parseDouble(request.getParameterValue("balance"));
		String actTo = request.getParameterValue("actTo");
		
		//-----------连接数据库---------------
		Connection conn = null;
		PreparedStatement ps = null;
		int count = 0;
		try {
			//1.注册驱动
			// 1.加载驱动 放入Mysql驱动类的全路径,让JVM预先加载这个类到内存中
			Class.forName("com.mysql.jdbc.Driver");
			//2.获取数据库的连接对象
			conn= DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bankdb?useUnicode=true&characterEncoding=UTF-8&useSSL=true","root","123456");
			//开启事务,关闭自动提交
			conn.setAutoCommit(false);
			//3.定义SQL语句框架
			String sql_from = "update t_act set balance = balance - ? where actno = ?";
			//4.进行SQL语句的预编译
			ps = conn.prepareStatement(sql_from);
			//5.进行赋值
			ps.setDouble(1, balance);
			ps.setString(2, actFrom);
			//6.执行SQL语句
			count = ps.executeUpdate();


			String sql_to = "update t_act set balance = balance + ? where actno = ?";
			ps = conn.prepareStatement(sql_to);
			ps.setDouble(1, balance);
			ps.setString(2, actTo);
			count = count + ps.executeUpdate();

			//提交事务
			conn.commit();
			
		} catch (Exception e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e.printStackTrace();
			}
		}finally{
			//关闭资源
			if(ps != null){
				try {
					ps.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(conn != null){
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		
		//获取响应流对象
		PrintWriter out = response.getWriter();
		if(count == 2){
			out.print("<html>");
			out.print("<head>");
			out.print("<title>银行帐户-转帐结果</title>");
			out.print("<meta content='text/html;charset=utf-8'/>");
			out.print("</head>");
			out.print("<body>");
			out.print("<center><font size='35px' color='green'>转帐成功!</font></center>");
			out.print("</body>");
			out.print("</html>");
		}else{
			out.print("<html>");
			out.print("<head>");
			out.print("<title>银行帐户-转帐结果</title>");
			out.print("<meta content='text/html;charset=utf-8'/>");
			out.print("</head>");
			out.print("<body>");
			out.print("<center><font size='35px' color='red'>转帐失败!</font></center>");
			out.print("</body>");
			out.print("</html>");
			
		}
	}

}

bruceliu9527 发布了267 篇原创文章 · 获赞 79 · 访问量 1万+ 私信 关注

标签:WEB,tomcat,ps,网银,sql,print,import,balance,out
来源: https://blog.csdn.net/BruceLiu_code/article/details/104197538

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有