jsp连接mysql数据库,实现含验证码的用户登录

xiaoxiao2021-02-27  520

功能简介

捣腾了几天,总算实现这个小小的登录功能,在此记录一下。 功能:输入框中输入用户名和密码和验证码,提交到服务器进行处理,如果验证码正确,就连接数据库查看用户名和密码是否存在,存在则进入主界面,否则重定向到登录界面。如果勾选了十天内免登录,则Cookie会记录用户名和密码,下次进入登录界面,就会自动填充上去。 所需的所有文件如下:

下面一步一步讲解如何实现的。

数据库相关准备

因为要连接mysql数据库,所以首先创建一个数据库login,再创建一张表users来保存用户名和密码。

//创建数据库 create database login; //创建数据表 create table users (username char(50) primary key, pwd char(50) not null ); //插入用户信息 insert into users values('admin','123');

接着就是下载连接mysql的驱动程序,并导入到MyEclipse中,详细步骤参考:http://blog.csdn.net/yanhui_wei/article/details/36011107

数据库的相关准备弄好之后,接下来就看看各个jsp程序。

登录界面

login.jsp

<%@ page language="java" import="java.util.*,java.net.*" contentType="text/html; charset=utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <% request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); String username = ""; String password = ""; Cookie[] arrCookie = request.getCookies(); if (arrCookie != null) { for (Cookie ck : arrCookie) { if (ck.getName().equals("UserName")) { username = URLDecoder.decode(ck.getValue(), "utf-8"); } if (ck.getName().equals("PassWord")) { password = URLDecoder.decode(ck.getValue(), "utf-8"); break; } } } %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>登录</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <link rel="stylesheet" type="text/css" href="styles.css"> <script type="text/javascript"> /* 点击图片改变验证码 */ function reloadCode() { checkcode.src = "servlet/validateCode?id=" + (new Date()).getTime(); } </script> </head> <body> <div class="wrapper"> <div class="form"> <form name="loginForm" action="dologin" method="post"> <table> <tr> <td>用户名:</td> <td><input type="text" name="txtUsername" value="<%=username%>" class="input" placeholder="请输入用户名admin" /> </td> </tr> <tr> <td>密码:</td> <td><input type="password" name="txtPassword" value="<%=password%>" class="input" placeholder="请输入密码123" /> </td> </tr> <tr> <td>验证码:</td> <td><input name="txtCheckCode" type="text" id="txtCheckCode" placeholder="请输入验证码" class="captcha_input"> <a href="javascript:reloadCode();"> <img src="servlet/validateCode" id="checkcode" /> </a></td> </tr> <tr> <td colspan="2"><input type="checkbox" name="isUseCookie" checked="checked" />十天内记住我的登录状态</td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="登录" class="input login" /> </td> </tr> </table> </form> <div class="divider"> ——————<span>第三方登录</span>————— </div> <!-- 页底开始 --> <footer> <p>Copyright 2017@Paranoidyang</p> </footer> </div> <!-- 页底结束 --> </div> </body> </html>

页面效果:

因为对这些页面进行了css设置,所以还有个 styles.css

@CHARSET "UTF-8"; * { margin: 0; padding: 0; } .wrapper { width: 354px; margin: 0 auto; } .form{ height: 300px;/*元素的高度*/ position: absolute; top: 50%;/*元素的顶部边界离父元素的的位置是父元素高度的一半*/ margin-top: -150px;/*设置元素顶边负边距,大小为元素高度的一半*/。 } .input { border: 1px solid #B8B8B8; width: 280px; height: 45px; padding: 0 10px; border-radius: 5px; /*将输入框变为圆角的,5px为圆角半径*/ } .captcha_input { border: 1px solid #B8B8B8; width: 184px; height: 45px; padding: 0 10px; /* border-radius: 5px;将输入框变为圆角的,5px为圆角半径 */ border-top-left-radius: 5px; border-bottom-left-radius: 5px; } input, img{vertical-align:middle;}/* 让输入框和验证码图片水平局中对齐,默认情况下,图片会高出文本框一些,很难看 */ img{ height:45px; width:90px; } .login { width: 350px; color: #fff; background-color: #4798F6; border: none; margin-top: 10px; } /*分隔线样式*/ .divider { letter-spacing: -1px; color: #ddd; text-align:center; } .divider span { letter-spacing: 0; color: #B8B8B8; margin: 0 20px; } footer p { text-align: center; font-size: 14px; color: #B8B8B8; }

生成验证码

从登录页面中,可以看到有个输入验证码的功能,这是现在很多网站登录验证的一种方式。它的工作机制是这样的:当你用户名或密码输入错误时,就会弹出让输入验证码的页面,如果你一次性就输正确了,它是不会出现的,这样下来,就可以防止不法分子利用特定程序对网站进行恶意的注册和攻击。在这里,我简化这个步骤,直接就显示出让你输入验证码的界面(注意:其他网站登录中是只在输错时才会让你输入验证码的喔)。 工作原理:首先,服务端随机产生几个随机数或者随机算式,然后通过session对象将数据传输到客户端,客户端输入验证码,通过表单将数据提交到服务器,服务器提取数据之后和产生的随机数字或者算式的结果对比,以此进行验证。 下面的代码就是服务器端用于生成验证码的: validateCode.java

package util; import java.awt.*; import java.awt.geom.*; import java.awt.image.*; import java.io.*; import java.util.*; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.imageio.ImageIO; /* * 生成验证码 */ public class validateCode extends HttpServlet { private static final long serialVersionUID = 1L; public validateCode() { super(); } public void destroy() { super.destroy(); } public void init() throws ServletException { super.init(); } /*该方法主要作用是获得随机生成的颜色*/ public Color getRandColor(int s,int e){ Random random=new Random (); if(s>255) s=255; if(e>255) e=255; int r,g,b; r=s+random.nextInt(e-s); //随机生成RGB颜色中的r值 g=s+random.nextInt(e-s); //随机生成RGB颜色中的g值 b=s+random.nextInt(e-s); //随机生成RGB颜色中的b值 return new Color(r,g,b); } @Override public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置不缓存图片 response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "No-cache"); response.setDateHeader("Expires", 0); //指定生成的响应图片,一定不能缺少这句话,否则错误. response.setContentType("image/jpeg"); int width=85,height=25; //指定生成验证码的宽度和高度 BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB); //创建BufferedImage对象,其作用相当于一图片 Graphics g=image.getGraphics(); //创建Graphics对象,其作用相当于画笔 Graphics2D g2d=(Graphics2D)g; //创建Grapchics2D对象 Random random=new Random(); Font mfont=new Font("楷体",Font.BOLD,16); //定义字体样式 g.setColor(getRandColor(200,250)); g.fillRect(0, 0, width, height); //绘制背景 g.setFont(mfont); //设置字体 g.setColor(getRandColor(180,200)); //绘制100条颜色和位置全部为随机产生的线条,该线条为2f for(int i=0;i<100;i++){ int x=random.nextInt(width-1); int y=random.nextInt(height-1); int x1=random.nextInt(6)+1; int y1=random.nextInt(12)+1; BasicStroke bs=new BasicStroke(2f,BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL); //定制线条样式 Line2D line=new Line2D.Double(x,y,x+x1,y+y1); g2d.setStroke(bs); g2d.draw(line); //绘制直线 } //输出由英文,数字,和中文随机组成的验证文字,具体的组合方式根据生成随机数确定。 String sRand=""; String ctmp=""; int itmp=0; //制定输出的验证码为四位 for(int i=0;i<4;i++){ switch(random.nextInt(3)){ case 1: //生成A-Z的字母 itmp=random.nextInt(26)+65; ctmp=String.valueOf((char)itmp); break; case 2: //生成汉字 String[] rBase={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}; //生成第一位区码 int r1=random.nextInt(3)+11; String str_r1=rBase[r1]; //生成第二位区码 int r2; if(r1==13){ r2=random.nextInt(7); }else{ r2=random.nextInt(16); } String str_r2=rBase[r2]; //生成第一位位码 int r3=random.nextInt(6)+10; String str_r3=rBase[r3]; //生成第二位位码 int r4; if(r3==10){ r4=random.nextInt(15)+1; }else if(r3==15){ r4=random.nextInt(15); }else{ r4=random.nextInt(16); } String str_r4=rBase[r4]; //将生成的机内码转换为汉字 byte[] bytes=new byte[2]; //将生成的区码保存到字节数组的第一个元素中 String str_12=str_r1+str_r2; int tempLow=Integer.parseInt(str_12, 16); bytes[0]=(byte) tempLow; //将生成的位码保存到字节数组的第二个元素中 String str_34=str_r3+str_r4; int tempHigh=Integer.parseInt(str_34, 16); bytes[1]=(byte)tempHigh; ctmp=new String(bytes); break; default: itmp=random.nextInt(10)+48; ctmp=String.valueOf((char)itmp); break; } sRand+=ctmp; Color color=new Color(20+random.nextInt(110),20+random.nextInt(110),random.nextInt(110)); g.setColor(color); //将生成的随机数进行随机缩放并旋转制定角度 PS.建议不要对文字进行缩放与旋转,因为这样图片可能不正常显示 /*将文字旋转制定角度*/ Graphics2D g2d_word=(Graphics2D)g; AffineTransform trans=new AffineTransform(); trans.rotate((45)*3.14/180,15*i+8,7); /*缩放文字*/ float scaleSize=random.nextFloat()+0.8f; if(scaleSize>1f) scaleSize=1f; trans.scale(scaleSize, scaleSize); g2d_word.setTransform(trans); g.drawString(ctmp, 15*i+18, 14); } HttpSession session=request.getSession(true); session.setAttribute("randCheckCode", sRand); g.dispose(); //释放g所占用的系统资源 ImageIO.write(image,"JPEG",response.getOutputStream()); //输出图片 } }

服务器登录处理程序

用户在输入框输入完所有要求的内容后,点击登录,这些数据就会被提交到服务器的dologin.java程序,对登录操作进行处理,首先判断验证码是否正确,如果错误则重定向回login.jsp,如果正确则连接数据库,查看数据库是否存在输入的用户名和密码,如果存在则跳转到main.jsp,否则重定向到login.jsp dologin.java

import java.io.IOException; import java.net.URLEncoder; import java.sql.DriverManager; import java.sql.ResultSet; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.mysql.jdbc.Connection; import com.mysql.jdbc.PreparedStatement; public class dologin extends HttpServlet { public dologin() { super(); } public void destroy() { super.destroy(); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Connection ct; PreparedStatement ps; ResultSet rs; // 驱动程序名 String driver = "com.mysql.jdbc.Driver"; // URL指向要访问的数据库名library String url = "jdbc:mysql://localhost:3306/login"; // MySQL配置时的用户名 String user = "root"; // MySQL配置时的密码 String password = "642765"; // 输入的用户名和密码 String txtUsername; String txtPassword; // 数据库中存储的用户名和密码 String myuserword; String mypwd; // 接收数据 txtUsername = request.getParameter("txtUsername"); txtPassword = request.getParameter("txtPassword"); // 验证码检测 String txtCheckCode = request.getParameter("txtCheckCode");// 获取输入框中输入的验证码 String CheckCode = request.getSession().getAttribute("randCheckCode") .toString();// 获取验证码真实的值 boolean judgeCheckCode = txtCheckCode.equals(CheckCode);// 比对输入的验证码与真实验证码是否一致 // 如果验证码正确,就连接数据库,对比用户名和密码 if (judgeCheckCode) { System.out.println("验证码正确"); System.out.println("正在连接数据库..."); try { // 加载驱动程序 Class.forName(driver); // getConnection()方法,连接MySQL数据库!! ct = (Connection) DriverManager.getConnection(url, user, password); if (ct != null) { System.out.println("数据库连接成功!"); } ps = (PreparedStatement) ct .prepareStatement("select * from users where username=? and pwd=? "); ps.setString(1, txtUsername); // 将第一个?设置为参数txtUsername ps.setString(2, txtPassword); // 将第二个?设置为参数txtPassword // rs是一个ResultSet结果集,可以把rs理解成返回一张表行的结果集 rs = ps.executeQuery(); // 执行查找看是否存在,有的话rs.next()返回true,反之为 // false // 如果存在此用户,则跳转到主界面 if (rs.next()) { myuserword = rs.getString(1);// 获得表格的第一列,此处为用户名 mypwd = rs.getString(2); // 获得表格的第二列,此处为密码 System.out.println("成功从login数据库的users表中获取到用户名和密码:"); System.out.println(myuserword + "\t" + mypwd + "\t");// “\t”为“转义字符”,代表的是一个tab,也就是8个空格。 response.sendRedirect("main.jsp"); } else { System.out.println("没有该用户,请重新输入"); response.sendRedirect("login.jsp"); } ct.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } // 如果验证码错误,就跳转回登录界面 } else { System.out.println("验证码错误"); response.sendRedirect("login.jsp"); } // 判断是否勾选十天免登录 boolean isRememberUser = (request.getParameter("isUseCookie") != null); if (isRememberUser) {// 要记住用户 // 把用户名和密码保存在Cookie对象里面 String username = URLEncoder.encode(txtUsername, "utf-8"); // 使用URLEncoder解决无法在Cookie当中保存中文字符串问题, String pwd = URLEncoder.encode(txtPassword, "utf-8"); Cookie usernameCookie = new Cookie("UserName", username); Cookie passwordCookie = new Cookie("PassWord", pwd); usernameCookie.setMaxAge(60*60*24*10); passwordCookie.setMaxAge(60*60*24*10);// 设置最大生存期限为10天 response.addCookie(usernameCookie); response.addCookie(passwordCookie); } else { Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0) { for (Cookie c : cookies) { if (c.getName().equals("UserName") || c.getName().equals("PassWord")) { c.setMaxAge(0); // 设置Cookie失效 response.addCookie(c); // 重新保存。 } } } } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } public void init() throws ServletException { } }

主界面

当用户名、密码、验证码都正确时,就会跳转到main.jsp,程序如下:

main.jsp

<%@ page language="java" import="java.util.*,java.net.*" contentType="text/html; charset=utf-8"%> <%@ page import="util.*"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>主界面</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <h1>主界面</h1> <hr> </body> </html>

页面显示如下:

web.xml配置

还有一步,不要漏掉了,在web.xml中还有做相关的配置,配置文件内容如下:

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name></display-name> <servlet> <description>This is the description of my J2EE component</description> //验证码相关配置 <servlet-name>validateCode</servlet-name> <servlet-class>util.validateCode</servlet-class> </servlet> <servlet> <servlet-mapping> <servlet-name>validateCode</servlet-name> <url-pattern>/servlet/validateCode</url-pattern> </servlet-mapping> //服务器处理程序相关配置 <servlet-name>dologin</servlet-name> <servlet-class>dologin</servlet-class> </servlet> <servlet-mapping> <servlet-name>dologin</servlet-name> <url-pattern>/dologin</url-pattern> </servlet-mapping> //设置默认界面 <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app>

总结

到此,这个简易的登录验证就实现了,还有很多需要修改完善的,接下来几天再慢慢都写下来,敬请关注。

转载请注明原文地址: https://www.6miu.com/read-883.html

最新回复(0)