【javaweb】自己动手实现简易的Tomcat2

编程入门 行业动态 更新时间:2024-10-11 23:22:02

【javaweb】<a href=https://www.elefans.com/category/jswz/34/1768975.html style=自己动手实现简易的Tomcat2"/>

【javaweb】自己动手实现简易的Tomcat2

一个服务器server中可以存放jd,oa这样的多个web应用;

Web应用是通过sun公司制定的servlet接口与Tomcat,JBoss等多个服务器解耦合的

所以,同一个web应用,就可以运行在多种不同的服务器上;(Tomcat,JBoss等服务器就是通过sun制定的Servlet接口来找到要执行的servlet类,从而启动web应用)

Java程序和数据库也是 JDBC接口来进行了解耦合;

Http协议的作用:

注意:

返回状态码500,就说明代码出现了问题;

 

 

项目目录

主启动类

package cn.huangyan.httpserver.core;import java.io.BufferedReader;
import java.io.IOException;
import java.ServerSocket;
import java.Socket;import cn.huangyan.httpserver.util.Logger;/** httpserver程序主入口* @author:huangyan* @version:1.0* */ 
public class BootStrap {public static void main(String[] args) {start();}// 主程序入口public static void start() {ServerSocket serverSocket = null;BufferedReader br = null;Socket clientSocket = null;try {Logger.log("httpserver start");// 获取当前时间long startTime = System.currentTimeMillis();// 解析服务器中包含的所有web.xml配置文件String[] webAppNames = {"oa"};WebParser.parser(webAppNames);// 获取系统端口号int port = ServerParser.getPort();Logger.log("httpserver-port:"+port);serverSocket = new ServerSocket(port);// 获取结束时间long endTime = System.currentTimeMillis();Logger.log("httpserver started:" + (endTime - startTime) + " ms");// 通过while循环,让服务器一直处理监听状态while(true) {// 开始监听clientSocket = serverSocket.accept();// 每一次请求,都开启一个新的线程进行请求处理new Thread(new HandlerRequest(clientSocket)).start();}} catch (Exception e) {e.printStackTrace();}finally {if(serverSocket != null) {try {serverSocket.close();} catch (IOException e) {e.printStackTrace();}}}}}

a)主线程负责接收每个客户端socket,并为每个客户端socket创建一个子线程负责处理

b)解析服务器中包含的所有web.xml配置文件

c)扫描配置文件server.xml,获取系统端口号

conf/server.xml

<?xml version="1.0" encoding="UTF-8"?>
<server><service><connector port="8080"></connector></service>
</server>

 

package cn.huangyan.httpserver.core;import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;/** 解析服务器中的web.xml配置文件* */
public class WebParser {public static  Map<String, Map<String,String>> servletMaps = new HashMap<String,  Map<String,String>>();/** 解析服务器中所有web应用的web.xml* */public static void parser(String[] webAppNames) throws DocumentException{for(String webAppName : webAppNames) {Map<String,String> servletMap = parser(webAppName);servletMaps.put(webAppName, servletMap);}}/** 解析单个应用的web.xml配置文件* */private static Map<String,String> parser(String webAppName) throws DocumentException{// 获取web.xml的路径String webPath = webAppName + "/WEB-INF/web.xml"; // sun公司规定的路径,没有为什么;    实现web服务器和app解耦// 创建xml解析器SAXReader saxReader = new SAXReader();Document document = saxReader.read(new File(webPath));// 获取servlet节点元素List<Element> servletNodes = document.selectNodes("/web-app/servlet");// 创建一个servletInfoMap集合:将servlet-name和servlet-class当做key和value存入此Map中Map<String,String> servletInfoMap = new HashMap<String, String>();// 开始遍历servletNodesfor(Element servletNode : servletNodes) {// 获取servlet-name节点元素Element servletNameEle = (Element) servletNode.selectSingleNode("servlet-name");// 获取servlet-name节点元素对象的值String servletName = servletNameEle.getStringValue();// 获取servlet-class节点元素Element servletClassEle = (Element) servletNode.selectSingleNode("servlet-class");// 获取servlet-class节点元素对象的值String servletClassName = servletClassEle.getStringValue();// 将servletName和servletClassName作为key/value,放入servletInfoMap集合中servletInfoMap.put(servletName, servletClassName);}// 获取servlet节点元素List<Element> servletMappingNodes = document.selectNodes("/web-app/servlet-mapping");// 创建一个servletInfoMap集合:将servlet-name和url,当做key和value存入此Map中Map<String,String> servletMappingInfoMap = new HashMap<String, String>();// 开始遍历servletMappingNodesfor(Element servletMappingNode : servletMappingNodes) {Element servletNameEle = (Element) servletMappingNode.selectSingleNode("servlet-name");String servletName = servletNameEle.getStringValue();Element urlPatternEle = (Element) servletMappingNode.selectSingleNode("url-pattern");String urlPattern = urlPatternEle.getStringValue();// 这里要替换为servletMappingInfoMap,不要再写成servletInfoMapservletMappingInfoMap.put(servletName, urlPattern);}// 获取servletInfoMap的keySet()Set<String> servletNames = servletInfoMap.keySet();// 创建一个servletMap:// 将servletMappingInfoMap的value与servletInfoMap的value,分别作为key与value存入此servletMapMap<String,String> servletMap = new HashMap<String, String>();for(String servletName : servletNames) {String urlPattern = servletMappingInfoMap.get(servletName);String servletClassName = servletInfoMap.get(servletName);servletMap.put(urlPattern, servletClassName);}return servletMap;}
}

 

考虑使用web.xml配置文件的原因:(解耦合)

Sun公司制定了规范;

Sun公司规定了webapp开发人员必须把web.xml放在规定的位置,必须使用规定的标签来描述url和类名之间的映射关系

Sun公司也规定了web服务器开发人员,就去这里读取web.xml,并读取web.xml中的规定的标签;

从而,实现了webapp开发人员和web服务器开发人员的解耦合

a)使用SAXReader,并使用三个Map,读取web.xml,最终将一个web.xml中的所有urlPattern <--> servletClassName保存进入ServletMap中

解析server.xml配置文件的类

package cn.huangyan.httpserver.core;import java.io.File;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;/** 解析server.xml配置文件* */
public class ServerParser {/** 获取服务器的端口号* @return int port* */public static  int getPort() {// 设置服务器默认启动端口int port = 8080;try {// 创建解析器SAXReader saxReader = new SAXReader();// 通过解析器的read方法,将配置文件读取到内存中,生成一个Document[org.dom4j]对象树//Document document = saxReader.read("D:\\ecli_space\\workspace\\myday06\\src\\main\\resources\\conf\\server.xml");//Document document = saxReader.read("src/main/resources/conf/server.xml");/** File用在web项目中,路径最前面不以/开头时,则是以当前web项目为根目录* */Document document = saxReader.read(new File("src/main/resources/conf/server.xml"));// 获取connector节点的路径:server -> service -> connector// 获取connector节点的xpath路径:/server/service/connector// 获取connector节点的xpath路径:server//connector// 获取connector节点的xpath路径://connectorElement connectorEle = (Element) document.selectSingleNode("//connector");// 获取port属性的值port = Integer.parseInt(connectorEle.attributeValue("port"));} catch (DocumentException e) {e.printStackTrace();}return port;}
}

a)涉及到File类在javaweb项目中,读取文件时路径书写的用法

 

客户端请求处理类

package cn.huangyan.httpserver.core;import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.Socket;
import java.util.Map;import javax.servlet.Servlet;
import javax.servlet.ServletRequest;import org.huangyan.oa.servlet.LoginServlet;import cn.huangyan.httpserver.util.Logger;/** 处理客户端请求* @version 1.0* @since 1.0* */
public class HandlerRequest implements Runnable {public Socket clientSocket;public HandlerRequest(Socket clientSocket) {this.clientSocket = clientSocket;}@Overridepublic void run() {// 处理客户端请求BufferedReader br = null;Logger.log("httpserver thread: "+ Thread.currentThread().getName());;PrintWriter out = null;// 接收客户端消息try {br = new BufferedReader(new	InputStreamReader(clientSocket.getInputStream()));// 获取响应流对象out = new PrintWriter(clientSocket.getOutputStream());/*// 打印出全部,请求协议* String temp = null; while((temp = br.readLine()) != null) {* System.out.println(temp); }*/String requestLine = br.readLine(); // GET /oa/index.html HTTP/1.1String requestURI = requestLine.split(" ")[1];System.out.println("reqeustURI="+requestURI);// 判断用户请求是否为静态页面:以.html或者.htm后缀名的文件叫做HTML静态页面if(requestURI.endsWith(".html") || requestURI.endsWith(".htm")) {//处理静态页面的方法responseStaticPage(requestURI,out);}else {// 动态资源:java程序,业务处理类// requestURI:/oa/login?username=jack&password=123String servletPath = requestURI;if(servletPath.contains("?")) {servletPath = servletPath.split("\\?")[0]; // servletPath.split("[?]")[0]}System.out.println("servletPath="+servletPath);/** // 这里请求路径和LoginServlet在服务器程序中耦合了*  if("/oa/login".equals(servletPath)) {* 		LoginServlet loginServlet = new LoginServlet(); * 		loginServlet.service();*  }*/// 获取应用的名称webAppName// webAppName: oa,在URI中:/oa/loginString webAppName = servletPath.split("[/]")[1];System.out.println("webAppName="+webAppName); // oa// 获取servletMaps集合中的value值Map<String,String> servletMap = WebParser.servletMaps.get(webAppName);// 从uri:/oa/login 中获取到:/loginString urlPattern = servletPath.substring(1+webAppName.length());String servletClassName = servletMap.get(urlPattern);try {if(servletClassName != null) {// 如果找到了动态资源// 封装请求对象ServletRequest request = new RequestObject(requestURI);// 封装响应对象ResponseObject response = new ResponseObject();response.setWriter(out);// 拼接响应信息out.print("HTTP/1.1 200 OK\n");out.print("Content-Type:text/html;charset=utf-8\n\n");/** 创建Servlet对象之前,先从Servlet缓存池中查找* 1. 有,直接拿来用* 2. 没有,创建Servlet对象,并放入缓存池中* */Servlet servlet = ServletCache.get(urlPattern);if(servlet == null) {Class clazz = Class.forName(servletClassName);Object obj = clazz.newInstance();servlet = (Servlet)obj;// 将创建好的Servlet放入缓存池中ServletCache.put(urlPattern, servlet);}/** 服务器将out输出流对象,传递给webapp开发人员使用的service方法* 从而webapp开发人员便可以拿着此out输出流对象,往页面写一些数据* * 由于当前线程持有的是此out输出流对象* 我们为了保证同处于当前线程的service()业务方法,也持有同样的out输出流对象,* 则必须把此out输出流对象传递给service方法,而不能自己去service()业务方法中去new一个新的out对象* * servlet.service(out);* */Logger.log("Servlet对象是:"+servlet);// 这个时候,服务器开发人员不知道如何调用servlet业务处理类里的业务方法// 这个时候,sun公司的servlet规范又出来了servlet.service(request,response);}else {// 404找不到动态资源StringBuilder html = new StringBuilder();html.append("HTTP/1.1 404 NotFound\n");html.append("Content-Type:text/html;charset=utf-8\n\n");html.append("<html>\r\n" + 	"<head>\r\n" + 	"<meta charset=\"UTF-8\">\r\n" + "<title>404-错误</title>\r\n" + "</head>\r\n" + "<body>\r\n" + 	"<center><font size=\"35xp\" color=\"red\">404-Not-Found</font></center>\r\n" + "</body>\r\n" + "</html>");out.print(html);}} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {e.printStackTrace();}}// 强制刷新(否则,浏览器无法显示)out.flush();} catch (IOException e) {e.printStackTrace();} finally {if(br != null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}if(clientSocket != null) {try {clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}}/* 处理静态页面* requestURI * */public void responseStaticPage(String requestURI, PrintWriter out) {// requestURI: /oa/index.html// 静态页面路径:oa/index.htmlString htmlPath = requestURI.substring(1);BufferedReader br = null;try {// 读取页面br = new BufferedReader(new FileReader(htmlPath));String temp = null;StringBuilder html = new StringBuilder();// 拼接响应信息html.append("HTTP/1.1 200 OK\n");html.append("Content-Type:text/html;charset=utf-8\n\n");while((temp = br.readLine()) != null) {html.append(temp);}// 输出HTMLout.print(html);} catch (FileNotFoundException e) {// 404找不到静态资源StringBuilder html = new StringBuilder();html.append("HTTP/1.1 404 NotFound\n");html.append("Content-Type:text/html;charset=utf-8\n\n");html.append("<html>\r\n" + 	"<head>\r\n" + 	"<meta charset=\"UTF-8\">\r\n" + "<title>404-错误</title>\r\n" + "</head>\r\n" + "<body>\r\n" + 	"<center><font size=\"35xp\" color=\"red\">404-Not-Found</font></center>\r\n" + "</body>\r\n" + "</html>");out.print(html);}catch(IOException e) {e.printStackTrace();}}}

a)客户端请求处理类又细分为两个部分:处理静态资源,处理请求的动态资源

b)如果处理的请求是请求动态资源,则涉及到在服务器代码中封装请求对象,封装响应对象,servlet缓存池

c)引出sun公司定义javax.servlet.Servlet接口的目的

Servlet缓存池

package cn.huangyan.httpserver.core;import java.util.HashMap;
import java.util.Map;import javax.servlet.Servlet;/** Servlet缓存池* */
public class ServletCache {private static Map<String,Servlet> servletMap = new HashMap<String,Servlet>();public static void put(String urlPattern , Servlet servlet) {servletMap.put(urlPattern, servlet);}public static Servlet get(String urlPattern) {return servletMap.get(urlPattern);}
}

javax.servlet.Servlet接口

package javax.servlet;/** 由sun公司指定的servlet接口规范,* 该接口由web服务器开发人员调用,由webapp开发人员来实现;* */
public interface Servlet {// 业务处理方法void service(ServletRequest request,ServletResponse response);}/** import cn.huangyan.httpserver.core.ResponseObject;  * // 这个又出现一个问题,此ResponseObject是web服务器开发人员开发程序是自定义的* * * 由sun公司指定的servlet接口规范, public interface Servlet {void service(ResponseObject response); }----------  这就出现了耦合的问题:在sun公司开发的接口中出现了比如Tomcat公司自定义的ResponseObject类----------  这时,就需要把sun公司和Tomcat公司再通过接口进行解耦合定义ServletResponse接口*/

a)在sun公司的Servlet接口中出现了Tomcat公司自定义的Response类,这就又出现了耦合的问题

b)sun公司为了消除这种耦合,就又定义了ServletRequest接口和ServletResponse接口

请求对象接口

package javax.servlet;/** 负责封装请求参数的对象* */
public interface ServletRequest {// 获取单选框标参数的值public String getParametervalue(String key);// 获取多选框标参数的值public String[] getParametervalues(String key);
}

响应对象接口

package javax.servlet;import java.io.PrintWriter;/** sun公司定义的:*   封装响应参数的接口规范* */
public interface ServletResponse {void setWriter(PrintWriter out);PrintWriter getWriter();
}

 

工具类

日期工具类

package cn.huangyan.httpserver.util;import java.text.SimpleDateFormat;
import java.util.Date;/* 日期工具类* @author huangyan* @version 1.0* #since 1.0* */
public class DateUtil {private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");private DateUtil() {}/** 获取系统当前时间* @return String [yyyy-MM-dd HH:mm:ss SSS]* */public static String getCurrentTime() {return dateFormat.format(new Date());}
}

日志工具类

package cn.huangyan.httpserver.util;import java.text.SimpleDateFormat;
import java.util.Date;/** 日志记录器* @author:huangyan* @version:1.0* */
public class Logger {// 工具类的方法往往是静态的,直接通过类名来调用,不需要创建对象;// 工具类的构造方法往往是私有的,但不是必须的;private Logger() {}public static void log(String msg) {/** SimpleDateFormat dataFormat = new* SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); Date nowTime = new Date();* String nowTimeStr = dataFormat.format(nowTime);*/System.out.println("[INFO] "+DateUtil.getCurrentTime()+" "+msg);}
}

 

业务处理类

登录的业务处理类

package org.huangyan.oa.servlet;import java.io.PrintWriter;import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;import cn.huangyan.httpserver.core.ResponseObject;/** 处理登录业务的java程序* 该java程序由webapp开发人员编写;由web服务器来调用* */
public class LoginServlet implements Servlet{@Overridepublic void service(ServletRequest request,ServletResponse response) {System.out.println("login-service:正在执行身份验证...");	// 获取当前线程的输出流对象(也就是当前客户端socket对象对应的输出流对象)PrintWriter out = response.getWriter();out.append("<html>\r\n" + 	"<head>\r\n" + 	"<meta charset=\"UTF-8\">\r\n" + "<title>404-错误</title>\r\n" + "</head>\r\n" + "<body>\r\n" + 	"<center><font size=\"35xp\" color=\"blue\">正在执行身份验证...</font></center>\r\n" + "</body>\r\n" + "</html>");}/** @Override public void service(ResponseObject response) {* System.out.println("login-service:正在执行身份验证...");* * // 获取当前线程的输出流对象(也就是当前客户端socket对象对应的输出流对象) PrintWriter out =* response.getWriter();* * out.append("<html>\r\n" + "<head>\r\n" + "<meta charset=\"UTF-8\">\r\n" +* "<title>404-错误</title>\r\n" + "</head>\r\n" + "<body>\r\n" +* "<center><font size=\"35xp\" color=\"blue\">正在执行身份验证...</font></center>\r\n"* + "</body>\r\n" + "</html>"); }*/
}

用户保存的业务处理类

package org.huangyan.oa.servlet;import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.URLDecoder;import javax.servlet.Servlet;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;/** 处理登录业务的java程序* 该java程序由webapp开发人员编写;由web服务器来调用* */
public class UserSaveServlet implements Servlet{@Overridepublic void service(ServletRequest request,ServletResponse response ) {System.out.println("UserSaveServlet:正在执行用户保存");	String username = null;try {// 对传递过来的“%e6%96%b0%e5%bb%ba”,这种UTF-8编码的串,用UTF-8进行解码username = URLDecoder.decode(request.getParametervalue("username"),"UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}String gender = request.getParametervalue("gender");String[] likes = request.getParametervalues("like");System.out.println("username="+username);PrintWriter out = response.getWriter();out.print("<html>\r\n" + 	"<head>\r\n" + 	"<meta charset=\"UTF-8\">\r\n" + "<title>用户信息</title>\r\n" + "</head>\r\n" + 	"<body>\r\n"+"用户名:"+username+ "<br>"+"性别:"+gender+ "<br>"+"爱好:"+likes[0]+" "+likes[1]+"</body>\r\n" + "</html>");}//	public void service(ResponseObject response) {
//		System.out.println("UserSaveServlet:正在执行用户保存");		
//	}
}

web应用:oa

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>oa办公系统</title>
</head>
<body><center><font size="35xp" color="blue">oa办公系统首页</font></center>
</body>
</html>

userSave.html

<!DOCTYPE html>
<html>
<head><title>用户信息-保存用户信息</title><meta content="text/html;charset=utf-8">
</head>
<body><center><form name="userForm" action="/oa/user/save" method="get">用户名:<input type="text" name="username"/><br><br>性&nbsp;&nbsp;别:<input type="radio" name="gender" value="1"/>男<input type="radio" name="gender" value="0"/>女<br><br>性&nbsp;&nbsp;别:<input type="checkbox" name="like" value="music"/>音乐<input type="checkbox" name="like" value="sport"/>运动<input type="checkbox" name="like" value="food"/>美食<input type="checkbox" name="like" value="sleep"/>睡觉<input type="checkbox" name="like" value="travel"/>旅行<br><br><input type="submit" value="提交"/><input type="reset" value="重置"/></form></center>
</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app><servlet><servlet-name>LoginServlet</servlet-name><servlet-class>org.huangyan.oa.servlet.LoginServlet</servlet-class></servlet><servlet-mapping><servlet-name>LoginServlet</servlet-name><url-pattern>/login</url-pattern></servlet-mapping><servlet><servlet-name>UserSaveServlet</servlet-name><servlet-class>org.huangyan.oa.servlet.UserSaveServlet</servlet-class></servlet><servlet-mapping><servlet-name>UserSaveServlet</servlet-name><url-pattern>/user/save</url-pattern></servlet-mapping></web-app>

web应用:bank

actOpen.html

<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>

actTransfer.html

<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>

web.xml

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

开户的业务处理类

package org.bjpowernode.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 {@Overridepublic 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.注册驱动Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接对象conn = DriverManager.getConnection("jdbc:mysql://localhost:3366/bjpowernode", "root", "111");//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 blocke.printStackTrace();}finally{//关闭资源if(ps != null){try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(conn != null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.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>");}}}

转账的业务处理类

package org.bjpowernode.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 {@Overridepublic 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.注册驱动Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接String url = "jdbc:mysql://127.0.0.1:3366/bjpowernode";String user = "root";String password = "111";conn = DriverManager.getConnection(url, user, password);//开启事务,关闭自动提交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();//提交事务connmit();} catch (Exception e) {try {// 出现异常,则进行事务回滚conn.rollback();} catch (SQLException e1) {e1.printStackTrace();}}finally{//关闭资源if(ps != null){try {ps.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(conn != null){try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.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>");}}}

 

 

更多推荐

【javaweb】自己动手实现简易的Tomcat2

本文发布于:2024-03-09 20:17:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1726017.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自己动手   简易   javaweb

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!