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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ParanoidYang/article/details/71157289

功能简介

捣腾了几天,总算实现这个小小的登录功能,在此记录一下。
功能:输入框中输入用户名和密码和验证码,提交到服务器进行处理,如果验证码正确,就连接数据库查看用户名和密码是否存在,存在则进入主界面,否则重定向到登录界面。如果勾选了十天内免登录,则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>

总结

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

猜你喜欢

转载自blog.csdn.net/ParanoidYang/article/details/71157289