手写tomcat(四)-WEB服务器测试-网银转账系统
作者:互联网
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