一个用户注册登陆的系统,用到了MD5加密处理密码,实现了一个简单的数据库连接池connectionPool,

实现了注册,登陆,登陆之后修改用户信息等功能,非常适合初学者

一.准备工作

数据库:MySQL  5.5.62-log MySQL Community Server (GPL)

创建user表,数据库为first_db;

CREATE TABLE IF NOT EXISTS `user`(

`user_id` INT UNSIGNED AUTO_INCREMENT,

 `username` VARCHAR(100) NOT NULL,

 `password` VARCHAR(100) NOT NULL,

 `phone` VARCHAR(100) NOT NULL, PRIMARY KEY ( `user_id` )

)ENGINE=InnoDB DEFAULT CHARSET=utf8;

二.项目结构图:

三.部分核心代码

web.xml: 

实现servlet指向CheckUser类和UpdateUser类,指定login.jsp为首页

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<servlet>
<servlet-name>CheckUser</servlet-name>
<servlet-class>com.Account.CheckUser</servlet-class>
</servlet>
<servlet>
<servlet-name>UpdateUser</servlet-name>
<servlet-class>com.Account.UpdateUser</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>CheckUser</servlet-name>
<url-pattern>/CheckUser</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>UpdateUser</servlet-name>
<url-pattern>/UpdateUser</url-pattern>
</servlet-mapping> <welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>

login.jsp:

login.jsp是登陆页面,from表单中加了一个<input type="hidden" name="actiontype" value="login" />的隐藏按钮,用于在CheckUser类中判断是登陆还是注册,通过actiontype的值。点击登陆,根据servlet分发到CheckUser类处理请求

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html>
<html>
<head>
<title>登陆</title>
</head>
<body>
<h2>欢迎登陆</h2>
<form action="CheckUser" method="post">
账号:<input type="text" name="userName"><br/>
密码:<input type="password" name="password"><br/>
<input type="hidden" name="actiontype" value="login" /> <!-- 用隐藏域来判断登陆还是注册 -->
<input type="submit" value="登陆"/><br/><br />
</form>
<button onclick="window.location='register.jsp'">注册</button>
${sessionScope.errorMsg} <!-- EL语法--获取session的errorMsg并显示 -->
</body>
</html>

CheckUser.java:

实现处理登陆注册的请求 向数据库请求并返回结果

package com.Account;
import java.io.IOException; import java.sql.Connection;
//import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; @SuppressWarnings("serial")
public class CheckUser extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession();
String userName = request.getParameter("userName");
String password = request.getParameter("password"); //md5对密码加密
Md5 md5=new Md5(); //判断类型是登陆还是注册
String Sql="";
String action_type = request.getParameter("actiontype");
if(action_type.equals("login")){
Sql = "SELECT user_id,username,password,phone FROM user "
+ "where username='" + userName+ "' AND password='" + md5.MD5(password) + "' ";
}else if(action_type.equals("register")){
Sql = "INSERT into user (username,password,phone) values ('"+ userName+"' ,'"+md5.MD5(password) +"',' ')";
} Connection connection = null;
PreparedStatement preSta = null;
ResultSet rs = null; // 建立连接,DriverManager是JDBC的管理层
try {
//使用连接池的方式连接数据库
ConnectionPool.setUrl(ConnectionPool.getUrl());
ConnectionPool.setUser(ConnectionPool.getUser());//DBTools.getDatabaseUserName()
ConnectionPool.setPassword(ConnectionPool.getPassword()); connection = ConnectionPool.getConnection();
preSta = connection.prepareStatement(Sql); UserInfo info = null; if(action_type.equals("login")) {
rs = preSta.executeQuery();
while(rs.next()){
info = new UserInfo();
info.setuser_id(rs.getInt("user_id"));
info.setUserName(rs.getString("username"));
info.setPassword(rs.getString("password"));
info.setPhone(rs.getString("phone"));
}
if(info != null){
session.setAttribute("password", password);
session.setAttribute("info", info);
String login_suc = "success.jsp";
response.sendRedirect(login_suc);
}
else{
String login_fail = "login.jsp";
session.setAttribute("errorMsg", "用户名或密码错误,登陆失败!");
response.sendRedirect(login_fail);
}
}
else if(action_type.equals("register")){
int count= preSta.executeUpdate();
if(count>0){
session.setAttribute("registerMsg", "注册成功!");
}
else{
session.setAttribute("registerMsg", "注册失败,请重试!");
}
response.sendRedirect("register.jsp");
}
} catch (Exception e) {
e.printStackTrace();
}
// 关闭连接
finally {
if(connection!=null){
try{
connection.close();
}catch(Exception e){}
}
if(preSta!=null){
try{
preSta.close();
}catch(Exception e){}
}
if(rs!=null){
try{
rs.close();
}catch(Exception e){}
}
}
}
}

MD5.Java:

MD5加密类,给password字段加密

package com.Account;

import java.security.MessageDigest;

public class Md5 {
public final String MD5(String s) {//MD5加密方法
char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
try {
byte[] btInput = s.getBytes();
// 获得MD5摘要算法的 MessageDigest 对象
MessageDigest mdInst = MessageDigest.getInstance("MD5");
// 使用指定的字节更新摘要
mdInst.update(btInput);
// 获得密文
byte[] md = mdInst.digest();
// 把密文转换成十六进制的字符串形式
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf]; //>>>不带符号 右移 四位(位移处补0)
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

ConnectionPool.java:

手动实现一个简单的数据库连接池,提升性能

package com.Account;

import java.sql.*;
import java.lang.reflect.*;
import java.util.*;
import java.io.*; public class ConnectionPool {
private static LinkedList m_notUsedConnection = new LinkedList();
private static HashSet m_usedUsedConnection = new HashSet();
private static String m_url = "jdbc:mysql://localhost:3306/first_db";
private static String m_user = "root";
private static String m_password = "123456";
static final boolean DEBUG = true;
static private long m_lastClearClosedConnection = System.currentTimeMillis();
public static long CHECK_CLOSED_CONNECTION_TIME = 4 * 60 * 60 * 1000; // 4小时 private void ConnectionPool() {
} static {
initDriver();
} private static void initDriver() {
Driver driver = null;
// load mysql driver
try {
driver = (Driver) Class.forName("com.mysql.jdbc.Driver").newInstance();
installDriver(driver);
} catch (Exception e) {
}
} public static void installDriver(Driver driver) {
try
{
DriverManager.registerDriver(driver);
}
catch (Exception e)
{
e.printStackTrace();
}
} public static synchronized Connection getConnection() {
clearClosedConnection();
while (m_notUsedConnection.size() > 0) {
try {
ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection
.removeFirst();
if (wrapper.connection.isClosed()) {
continue;
}
m_usedUsedConnection.add(wrapper);
if (DEBUG) {
wrapper.debugInfo = new Throwable(
"Connection initial statement");
}
return wrapper.connection;
} catch (Exception e) {
}
}
int newCount = getIncreasingConnectionCount();
LinkedList list = new LinkedList();
ConnectionWrapper wrapper = null;
for (int i = 0; i < newCount; i++) {
wrapper = getNewConnection();
if (wrapper != null) {
list.add(wrapper);
}
}
if (list.size() == 0) {
return null;
}
wrapper = (ConnectionWrapper) list.removeFirst();
m_usedUsedConnection.add(wrapper); m_notUsedConnection.addAll(list);
list.clear(); return wrapper.connection;
} private static ConnectionWrapper getNewConnection() {
try {
Connection con = DriverManager.getConnection(m_url, m_user,
m_password);
ConnectionWrapper wrapper = new ConnectionWrapper(con);
return wrapper;
} catch (Exception e) {
e.printStackTrace();
}
return null;
} static synchronized void pushConnectionBackToPool(ConnectionWrapper con) {
boolean exist = m_usedUsedConnection.remove(con);
if (exist) {
m_notUsedConnection.addLast(con);
}
} public static int close() {
int count = 0; Iterator iterator = m_notUsedConnection.iterator();
while (iterator.hasNext()) {
try {
((ConnectionWrapper) iterator.next()).close();
count++;
} catch (Exception e) {
}
}
m_notUsedConnection.clear(); iterator = m_usedUsedConnection.iterator();
while (iterator.hasNext()) {
try {
ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
wrapper.close();
if (DEBUG) {
wrapper.debugInfo.printStackTrace();
}
count++;
} catch (Exception e) {
}
}
m_usedUsedConnection.clear(); return count;
} private static void clearClosedConnection() {
long time = System.currentTimeMillis();
// sometimes user change system time,just return
if (time < m_lastClearClosedConnection) {
time = m_lastClearClosedConnection;
return;
}
// no need check very often
if (time - m_lastClearClosedConnection < CHECK_CLOSED_CONNECTION_TIME) {
return;
}
m_lastClearClosedConnection = time; // begin check
Iterator iterator = m_notUsedConnection.iterator();
while (iterator.hasNext()) {
ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
try {
if (wrapper.connection.isClosed()) {
iterator.remove();
}
} catch (Exception e) {
iterator.remove();
if (DEBUG) {
System.out
.println("connection is closed, this connection initial StackTrace");
wrapper.debugInfo.printStackTrace();
}
}
} // make connection pool size smaller if too big
int decrease = getDecreasingConnectionCount();
if (m_notUsedConnection.size() < decrease) {
return;
} while (decrease-- > 0) {
ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection
.removeFirst();
try {
wrapper.connection.close();
} catch (Exception e) {
}
}
} /**
* get increasing connection count, not just add 1 connection
*
* @return count
*/
public static int getIncreasingConnectionCount() {
int count = 1;
int current = getConnectionCount();
count = current / 4;
if (count < 1) {
count = 1;
}
return count;
} /**
* get decreasing connection count, not just remove 1 connection
*
* @return count
*/
public static int getDecreasingConnectionCount() {
int count = 0;
int current = getConnectionCount();
if (current < 10) {
return 0;
}
return current / 3;
} public synchronized static void printDebugMsg() {
printDebugMsg(System.out);
} public synchronized static void printDebugMsg(PrintStream out) {
if (DEBUG == false) {
return;
}
StringBuffer msg = new StringBuffer();
msg.append("debug message in " + ConnectionPool.class.getName());
msg.append("\r\n");
msg.append("total count is connection pool: " + getConnectionCount());
msg.append("\r\n");
msg.append("not used connection count: " + getNotUsedConnectionCount());
msg.append("\r\n");
msg.append("used connection, count: " + getUsedConnectionCount());
out.println(msg);
Iterator iterator = m_usedUsedConnection.iterator();
while (iterator.hasNext()) {
ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();
wrapper.debugInfo.printStackTrace(out);
}
out.println();
} public static synchronized int getNotUsedConnectionCount() {
return m_notUsedConnection.size();
} public static synchronized int getUsedConnectionCount() {
return m_usedUsedConnection.size();
} public static synchronized int getConnectionCount() {
return m_notUsedConnection.size() + m_usedUsedConnection.size();
} public static String getUrl() {
return m_url;
} public static void setUrl(String url) {
if (url == null) {
return;
}
m_url = url.trim();
} public static String getUser() {
return m_user;
} public static void setUser(String user) {
if (user == null) {
return;
}
m_user = user.trim();
} public static String getPassword() {
return m_password;
} public static void setPassword(String password) {
if (password == null) {
return;
}
m_password = password.trim();
} } class ConnectionWrapper implements InvocationHandler {
private final static String CLOSE_METHOD_NAME = "close";
public Connection connection = null;
private Connection m_originConnection = null;
public long lastAccessTime = System.currentTimeMillis();
Throwable debugInfo = new Throwable("Connection initial statement"); ConnectionWrapper(Connection con) {
this.connection = (Connection) Proxy.newProxyInstance(
con.getClass().getClassLoader(),
new Class[]{Connection.class}, this);
m_originConnection = con;
} void close() throws SQLException {
m_originConnection.close();
} public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
Object obj = null;
if (CLOSE_METHOD_NAME.equals(m.getName())) {
ConnectionPool.pushConnectionBackToPool(this);
} else {
obj = m.invoke(m_originConnection, args);
}
lastAccessTime = System.currentTimeMillis();
return obj;
} }

四.完成效果

首先user表是空的,然后在首页注册用户,然后查看数据库信息已经注册成功,再进行登陆,登陆成功后跳转到个人中心页面,修改密码手机等信息,完成后再次查看数据库

五.完整源代码包含jar包地址:

https://download.csdn.net/download/wcc27857285/10778616

java 用户注册登陆Demo的更多相关文章

  1. 微信小程序_(校园视)开发用户注册登陆

    微信小程序_(校园视) 开发用户注册登陆 传送门 微信小程序_(校园视) 开发上传视频业务 传送门 微信小程序_(校园视) 开发视频的展示页-上 传送门 微信小程序_(校园视) 开发视频的展示页-下 ...

  2. Jsoup实现java模拟登陆

    Jsoup实现java模拟登陆 2013-10-29 14:52:05|  分类: web开发|举报|字号 订阅     下载LOFTER我的照片书  |     1:如何获取cookies. 1.1 ...

  3. Java模拟登陆02【转载】

    在使用java访问URL时,如果该URL需要身份验证,那么就不能够直接访问,因为没有登陆.那么,如何解决这个问题呢?     方法是使用java模拟登陆,登陆后记录下cookie信息,在下次发起请求时 ...

  4. JAVA长连接demo

    http://blog.csdn.net/caomiao2006/article/details/38830475 JAVA长连接demo 2014-08-25 23:20 4767人阅读 评论(2) ...

  5. 启动servlet报错:The servlets named [DemoServlet] and [main.java.com.wlf.demo.servlet.DemoServlet] are both mapped to the url-pattern [/hello] which is not permitted

    先看具体错误日志: [2019-04-26 09:29:25,484] Artifact demo-servlet:war: Artifact is being deployed, please wa ...

  6. Java反射机制demo(七)—反射机制与工厂模式

    Java反射机制demo(七)—反射机制与工厂模式 工厂模式 简介 工厂模式是最常用的实例化对象模式. 工厂模式的主要作用就是使用工厂方法代替new操作. 为什么要使用工厂模式?直接new不好吗? 直 ...

  7. Java反射机制demo(六)—获得并操作一个类的属性

    Java反射机制demo(六)—获得并操作一个类的属性 获得并操作一个类的属性?! 不可思议啊,一个类的属性一般都是私有成员变量啊,private修饰符啊! 但是毫无疑问,这些东西在Java的反射机制 ...

  8. Java反射机制demo(五)—获得并调用一个类中的方法

    Java反射机制demo(五)—获得并调用一个类中的方法 这个demo在使用反射机制操作属性之前,主要原因是因为在.class文件字节码中,方法排在属性的前面. 1,获得一个类中的方法 先看一下方法和 ...

  9. Java反射机制demo(四)—获取一个类的父类和实现的接口

    Java反射机制demo(四)—获取一个类的父类和实现的接口 1,Java反射机制得到一个类的父类 使用Class类中的getSuperClass()方法能够得到一个类的父类 如果此 Class 表示 ...

随机推荐

  1. 基于UDP协议的套接字编程

    基于udp协议的套接字编程 UDP是无链接的,先启动那一端都不会报错 UDP协议是数据报协议,发空的时候也会自带报头,因此客户端输入空,服务端也能收到 一般不用与传输大数据 虽然没有粘包问题,但是不能 ...

  2. Hive学习详细版

    一.概述 1.Hadoop的开发问题 只能用java语言开发,存在语言门槛 需要对Hadoop底层原理,api比较了解才能做开发 开发调试比较麻烦 2.什么是Hive Hive是基于Hadoop的一个 ...

  3. windows系统下jupyter notebook使用虚拟环境

    目录 [亲测好使]windows系统下jupyter notebook使用虚拟环境 在虚拟环境中安装jupyter,并添加到jupyter kernel 参考 [未测试,但觉得比上面那方法好,因为上面 ...

  4. C++的注释

    ### 1.2 注释 **作用**:在代码中加一些说明和解释,方便自己或其他程序员程序员阅读代码 **两种格式** 1. **单行注释**:// 描述信息  - 通常放在一行代码的上方,或者一条语句的 ...

  5. 如何使用Spark大规模并行构建索引

    使用Spark构建索引非常简单,因为spark提供了更高级的抽象rdd分布式弹性数据集,相比以前的使用Hadoop的MapReduce来构建大规模索引,Spark具有更灵活的api操作,性能更高,语法 ...

  6. Java开发系列-JSP

    概述 JSP是java 服务器页面,它运行在服务器端,本质上就是一个serlvet,产生的java文件和class保留在tomcat的word目录下. JSP主要作用是将内容的生成与页面相分离. JS ...

  7. PostgreSQL问题解决--连接数过多

    I am trying to connect to a Postgresql database, I am getting the following Error: Error:org.postgre ...

  8. 利用eclipse通过mybatis进行查询汉字字符时候无法显示结果,但是直接通过cmd窗口可以显示的解决方法

    将数据库配置文件中的url写成如下的形式就可以成功查询: url = "jdbc:mysql://127.0.0.1:3306/test?characterEncoding=utf8&quo ...

  9. mybatis分页插件PageHelp的使用

    1.简介 ​ PageHelper 是国内非常优秀的一款开源的 mybatis 分页插件,它支持基本主流与常用的数据库,例如 mysql.oracle.mariaDB.DB2.SQLite.Hsqld ...

  10. IDEA启动springboot项目一直build

    启动main方法后,项目一直在不断的build,期间截了两张一闪而过的提示 我用的是Run Dashboard面板,不论是通过删除configuration,rebuild,删除IDEA缓存都没有效果 ...