Servlet监听器使用实例(提高程序运行速度)

无论进入哪个网站,用户注册是必不可少的一部分,用户注册所需要的时间是影响用户体验最重要的一环,今天我们我们的任务就是以用户注册为例,使用servlet监听器对用户注册速度进一步优化

用户注册,也就是将用户数据写入到数据库,我们优化注册速度,也就是对后端操作数据库进行优化,像我这种小白用java写注册程序时,每当有用户注册时,就会先连接数据库,然后执行操作语句,最后关闭,多个用户注册时,就是上面流程的循环,我们知道,连接数据库也是需要时间的,所以,这样就有大把的时间都浪费在了连接数据库上,所以我们可以结合监听器来解决这个问题(都是很基础的东西)

先贴两张优化之前和优化之后的用户注册速度对比图

优化之前:
在这里插入图片描述
优化之后:
在这里插入图片描述

用户注册优化思路:既然时间大多都花在连接数据库上,那我们可以让用户在注册时省去连接数据库这个步骤,并不是不用连接数据库,而是不在用户注册时连接,我们可以提前创建好连接对象,然后用户注册时可以直接调用这个连接对象那我们什么时候创建连接对象呢?我们可以在服务器启动时就创建好连接对象,那怎样实现在服务器启动时就创建连接对象呢?这就可以借助我们的监听器了,服务器启动时就会创建servlet上下文对象,而监听器可以监听servlet上下文对象的状态,包括何时被初始化,何时被摧毁,以及上下文对象里面存放的数据的变化,这样我们就可以利用监听器的这些功能来完成我们的设想

项目结构

其中Listener.java是监听器接口的实现类
在这里插入图片描述
代码部分

AddInfoDao.java部分

package dao;

import java.sql.*;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;


public class AddInfoDao {
	private static Connection conn = null;
	private static PreparedStatement pst = null;
	
	public static boolean addinfo(String a,String b,String c,String d,HttpServletRequest request) {
		boolean result = false;
//		创建servlet上下文对象
		ServletContext application = request.getServletContext();
//		获取上下文对象中存放的Map
		@SuppressWarnings("unchecked")
		Map<Connection, Boolean> allconn = (Map<Connection, Boolean>) application.getAttribute("allconn");
		Iterator<Connection> keys = allconn.keySet().iterator();
//		从Map中获取连接对象
		while (keys.hasNext()) {
//			判断连接对象是否正在被使用,如果为true,表示可以使用,如果为false,表示正在被使用
			if (allconn.get(keys.next()) == true) {
				conn = keys.next();
//				使用一个连接对象时,将此连接对象的使用状态标识为false
				allconn.put(conn, false);
//		因为我们正在使用一个连接对象,所以我们要将此连接对象的状态更新到servlet上下文中,这样其他用户才可以知道此连接对象已被使用
				application.setAttribute("allconn", allconn);
				break;
			}
		}
		try {
//			执行添加数据的SQL语句
			pst = conn.prepareStatement("insert into demo values (?,?,?,?)");
			pst.setString(1, a);
			pst.setString(2, b);
			pst.setString(3, c);
			pst.setString(4, d);
			pst.executeUpdate();
			result = true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
//			当我们执行完sql语句不再使用连接对象时,将连接对象的表示状态改为true,表示其他用户可以使用此连接对象
			allconn.put(conn, true);
//			改变完连接对象的状态后,要更新到上下文中,这样其他用户才可以知道
			application.setAttribute("allconn", allconn);
		}
		return result;
	}
}

GetInfoServlet.java部分

package getinfo;

import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import dao.AddInfoDao;

@WebServlet("/GetInfoServlet")
public class GetInfoServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    public GetInfoServlet() {
        super();
        // TODO Auto-generated constructor stub
    }


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");
		String a = request.getParameter("a");
		String b = request.getParameter("b");
		String c = request.getParameter("c");
		String d = request.getParameter("d");
		Date time1 = new Date();
		boolean result = AddInfoDao.addinfo(a, b, c, d, request);
		Date time2 = new Date();
		System.out.println("用户注册用时为:  " + (time2.getTime()-time1.getTime()) + "毫秒");
		if (result == true) {
			System.out.println("添加成功");
		}else {
			System.out.println("添加失败");
		}
	}

}

Listener.java部分

package listener;

import java.sql.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import util.SqlServerConnection;

// 实现ServletContextListener接口,监听servlet上下文的状态
public class Listener implements ServletContextListener {
	private Connection conn = null;
//	创建Map用来存放数据库连接对象  Map中的键用来存放数据库连接对象 值用来标识此连接对象是否被使用
	Map<Connection, Boolean> allconn = new HashMap<Connection, Boolean>();
	
//	servlet上下文初始化时执行此方法
	public void contextInitialized(ServletContextEvent sce) {
//		创建10个连接对象
		for (int i = 0; i < 10; i++) {
			conn = SqlServerConnection.sql_connection();
			System.out.println("创建数据库连接对象  " + conn);
			allconn.put(conn, true);
		}
//		将存放连接对象的Map存放在servlet上下文中,从服务器启动到服务器关闭期间可以随时随地使用
		sce.getServletContext().setAttribute("allconn", allconn);
	}
	
	
//	servlet上下文被摧毁时执行此方法
	public void contextDestroyed(ServletContextEvent sce) {
//		创建Servlet上下文对象,生命周期从服务器启动到服务器关闭
		ServletContext application = sce.getServletContext();
//		获取存放数据库连接对象的map
		@SuppressWarnings("unchecked")
		Map<Connection, Boolean> allconn = (Map<Connection, Boolean>) application.getAttribute("allconn");
//		获取所有数据库连接对象  连接对象我们存放在了Map的键中 所以我们要获取Map中所有的键
		Iterator<Connection> it = allconn.keySet().iterator();
//		循环关闭所有数据库连接对象
		while (it.hasNext()) {
			Connection connection = (Connection) it.next();
			try {
				connection.close();
				System.out.println("关闭数据库连接对象   " + connection);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

SqlServerConnection.java部分

package util;

import java.sql.*;

public class SqlServerConnection {
	static Connection conn;
	static String drive = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
	static String url = "jdbc:sqlserver://localhost:1433;DatabaseName=ShopSystem";
	static String username = "sa";
	static String password = "sa";
	
	public static Connection sql_connection() {
		try {
//		注册驱动
			Class.forName(drive);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
//			创建连接对象
			conn = DriverManager.getConnection(url,username,password);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			System.out.println("连接失败");
		}
		return conn;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		sql_connection();
	}

}

web.xml部分

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>WebTest</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <listener>
  	<listener-class>listener.Listener</listener-class>
  </listener>
</web-app>

index.html部分

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<center>
	<form action="GetInfoServlet" method="post">
		<input type="text" name="a"><br/>
		<input type="text" name="b"><br/>
		<input type="text" name="c"><br/>
		<input type="text" name="d"><br/>
		<input type="submit">
	</form>
</center>
</body>
</html>

jar包获取地址:https://pan.baidu.com/s/1XvJf2bWmLoQPNU8VCjBfgQ
提取码:q0bl

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值