• JSP和AJAX实现登录注册


    前言

    WEB组队大作业要求用JSP实现后台访问修改数据库,用了老师的课件和网上查找得来的资料。


    代码

    login.jsp:

    <body>
        <div id="backgroundpic"></div>
        <div id="logInWrap">
            <div id="logInContain">
                <h1>登录</h1>
                <form action="loginCheck.jsp" method="POST" name="formLogin">
                    <input type="text" placeholder="昵称/邮箱" name="name">
                    <input type="password" placeholder="密码" name="password">
                    <input type="button" value="登录" onclick="doCheck_logIn()">
                </form>
                <p>还没有帐号?<a href="signup.jsp">前往注册</a></p>
    		    <%  
    		    String flag = request.getParameter("errNo");  
    		    try{
    		         if(flag!=null)
    		            out.println("<span id='loginMsg'>用户名不存在或密码错误</span>");
    		    }catch(Exception e){
    		        e.printStackTrace();
    		    }
    		   %>
            </div>
            <span id="logInBack"><a href="Index.html">返回</a></span>
        </div>
    </body>
    

    loginCheck.jsp:

    <%@page language="java" import="java.util.*,java.sql.*" contentType="text/html; charset=utf-8"%>
    <% request.setCharacterEncoding("utf-8");
        String msg=""; 
        String pwd="", name="";//数据库中保存的密码和用户名
        String conStr = "jdbc:mysql://172.18.187.10:53306/blog_15336202"
        + "?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8";
        String userName = request.getParameter("name"); //从登录页面post过来的用户名和密码
        String userPwd = request.getParameter("password");
        try {
            Class.forName("com.mysql.jdbc.Driver"); // 查找数据库驱动类
            Connection con=DriverManager.getConnection(conStr, "user", "123");
            Statement stmt=con.createStatement(); //创建MySQL语句的对象
            ResultSet rs=stmt.executeQuery("select * from users where (name = '" + userName + "' or email = '" + userName + "') and password = '" + userPwd + "'");//执行查询,返回结果集
            if(rs.next()) { //把游标(cursor)移至第一个或下一个记录
                response.sendRedirect("loGinsuccess.jsp?username=" + userName); //密码正确跳转loGinsuccess.jsp
            }else{
                response.sendRedirect("login.jsp?errNo");//密码不对返回到登陆  
            }
        rs.close(); stmt.close(); con.close();
        }
        catch(Exception e){
            msg = e.getMessage();
        }
    %>
    

    loGinsuccess.jsp:

    <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>
    <%request.setCharacterEncoding("utf-8");%>
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>登录成功界面</title>
    </head>
    <body>
        <h1>登录成功!!!</h1>
    </body>
    </html>
    

    signup.jsp:

    <%@page language="java" import="java.util.*,java.sql.*" contentType="text/html; charset=utf-8"%>
    <% request.setCharacterEncoding("utf-8");
    String msg = "";
    String connectString = "jdbc:mysql://172.18.187.10:53306/blog_15336202" + "?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8";
    String user="user"; String pwd="123";
    String username = request.getParameter("name");
    String password = request.getParameter("password");
    String email = request.getParameter("email");
    if (request.getMethod().equalsIgnoreCase("post")){
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection(connectString,user, pwd);
        Statement stmt = con.createStatement();
        try {
            String fmt="insert into users(name,password,email) values('%s', '%s', '%s')";
            String sql = String.format(fmt,username,password, email);
            int cnt = stmt.executeUpdate(sql);
            if (cnt > 0)
                msg = "注册成功!";
            stmt.close(); con.close();
        }
        catch (Exception e) {
            msg = e.getMessage();
        }
    }
    %>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>注册</title>
        <script src="js/loginAndRegister.js"></script>
    </head>
    <body>
        <div id="backgroundpic"></div>
        <div id="signUpWrap">
            <div id="signUpContain">
                <h1>注册</h1>
                <form action="signup.jsp" method="post" name="formRegister">
                    <input type="text" placeholder="昵称" name="name" id="username">
                    <input type="text" placeholder="邮箱" name="email" id="email">
                    <input type="password" placeholder="密码" name="password" id="password">
                    <input type="password" placeholder="确认密码" name="password2" id="password2">
                    <input type="button" value="注册" onclick="doCheck_Register()">
                </form>
                <p>已有帐号?<a href="login.jsp">前往登录</a></p>
                <span id="registerMsg"><%=msg%><span>
            </div>   
            <span id="signUpBack"><a href="Index.html">返回</a></span>
        </div>
    </body>
    </html>
    

    注册和登录检查函数:

    
    //注册检查函数:验证是否输入完全,两次输入的密码是否相同。
    function doCheck_Register() {
        var inPut = document.querySelectorAll("div#signUpContain form input");
        let flag = 0;
        for (let i = 0; i < inPut.length - 1; ++i) {
            if (inPut[i].value == "") {
                alert("请输入 " + inPut[i].placeholder);
                document.querySelectorAll("div#signUpContain form input")[i].focus();
                flag++;
                break;
            }
        }
        var pass1 = document.querySelector("div#signUpContain form input#password");
        var pass2 = document.querySelector("div#signUpContain form input#password2");
        if(flag == 0) {
            if (pass1.value != pass2.value) {
                alert("两次密码不相同!")
                document.querySelector("div#signUpContain form input#password2").focus();
                flag++;
            }
        }
    
        if (flag == 0) {
            formRegister.submit();
        }
        return false;
    }
    
    //登录检查函数:验证是否输入,否则提示输入。
    function doCheck_logIn() {
        var inPut = document.querySelectorAll("div#logInContain form input");
        let flag = 0;
        for (let i = 0; i < inPut.length - 1; ++i) {
            if (inPut[i].value == "") {
                alert("请输入 " + inPut[i].placeholder);
                document.querySelectorAll("div#logInContain form input")[i].focus();
                flag++;
                break;
            }
        }
        if (flag == 0) {
            formLogin.submit();
        }
        return false;
    }
    

    更新-2019.6.21

    随着大作业的不断迭代修改,注册的功能被一点点修改和优化,这一次修改主要包括:

    • 输入昵称邮箱等信息后提示是否可注册,无需刷新页面
    • 分离注册判断jsp程序和页面代码,提高可读性

    效果如图:

    想法

    实际上之前就一直想实现这样的局部刷新效果,看起来比刷新页面才知道用户名是否唯一要酷炫多了,但是可能是没有怎么用过AJAX所以一直有一种畏惧心理,直到某天晚上我实在是想要实现这个“实时”提示的酷炫小功能,遂决定克服恐惧。

    实现思路

    思路其实很清晰,之前没用AJAX时,是通过提交表单的方式,将当前输入通过POST提交给本jsp程序,然后通过查询数据库确定输入值是否已存在,功能都有,不足就是需要刷新页面。

    AJAX就是解决这种异步刷新需求的。

    通过AJAX请求,一旦输入值发生变动,可以通过js函数创建http请求,将输入值提交到registerCheck.jsp后台程序,后台程序完成上述检查工作再发送响应正文,响应正文根据不同情况设置为各种提示消息,最后回到js函数中,收到http响应正文,将正文提示消息在html文档中合适位置显示出来,就完成输入提示了。并且整个过程是异步进行的,只会对局部进行刷新,提高整个网页浏览的流畅性。

    关键和遇到的问题

    关键

    写代码的时候直接把后台的检查程序单独列出来,这样比原来全都混在一起要清晰多了,后期也更容易修改。

    也就是说,实际上输入信息之后,信息的值会被提交到一个jsp程序里,这个jsp程序完成数据库检查唯一性的工作,然后通过AJAX发送响应回到当前的注册页面里。整个工作对用户是“透明的”,这样一来就提高了用户浏览网页的流畅度了,不会一直刷新刷新。

    问题

    代码写好之后,输入英文数字字符是ok的,但是当输入单引号的时候会出现问题,原因就是MySQL注入的问题了。

    由于registerCheck.jsp检查程序里查询数据库的语句是简单的"select * from users where name='" + value + "'",当输入中包含单引号这种会影响后台数据库查询语句时,就会出现预料之外的问题。

    解决这个问题的方法及时在前端提交输入值的时候,先做一个判断,将单引号字符去掉:

    if (id == "username" || id == "email") {
        inPut_value = inPut_value.split("'").join("");
    }
    

    不过,虽然解决了输入单引号的问题,但是考虑到其他MySQL注入问题,诸如输入“or”、“and”等数据库查询语句字符的时候,也会出现意想不到的问题,这个问题我还没有解决…因为涉及到JAVA程序的编写,日后再来完善!

    完整代码

    前端输入页面signup.jsp

    {% fold %}

    <%@page language="java" import="java.util.*,java.sql.*" contentType="text/html; charset=utf-8"%>
    <% request.setCharacterEncoding("utf-8");
    String userId = request.getParameter("userId");
    String msg = "";
    String query = "";
    String sql = "";
    String sql2 = "";
    String connectString = "jdbc:mysql://172.18.187.10:3306/blog_15336202" + "?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8";
    String user="user"; String pwd="123";
    String username = request.getParameter("name");
    String password = request.getParameter("password");
    String sex = "保密";
    String birthday = "";
    String phone = "";
    String hobby = "";
    String hometown = "";
    String email = request.getParameter("email");
    String job = "";
    String school = "";
    String company = "";
    String sign = "";
    String resume = "";
    if (request.getMethod().equalsIgnoreCase("post")){
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection(connectString, user, pwd);
        Statement stmt = con.createStatement();
        query = request.getParameter("query");
        //TODO 解决MySQL注入问题
        sql="select*from users where name='" + username +"'"; //查询数据库中是否有相同用户名
        sql2="select*from users where email='" + email + "'"; //查询数据库中是否有相同邮箱
        ResultSet rs=stmt.executeQuery(sql); 
          if (!rs.next()) { //没有相同用户名,继续判断邮箱是否相同
            try {
                ResultSet rss = stmt.executeQuery(sql2);
                if (!rss.next()) { //没有相同邮箱,注册成功
                    String fmt="insert into users(name, password, sex, birthday, phone, hobby, hometown, email, job, school, company, sign, resume) values('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')";
                    sql = String.format(fmt, username, password, sex, birthday, phone, hobby,hometown, email, job, school, company, sign, resume);
                    int cnt = stmt.executeUpdate(sql);
                    if (cnt > 0) {
                        msg = "注册成功啦!";
                        // 设置 name 和 url cookie 
                        Cookie newuser = new Cookie("user", username);
                        userId = username;
                        // 设置cookie过期时间为一周。
                        newuser.setMaxAge(7*60*60*24); 
    
                        // 在响应头部添加cookie
                        response.addCookie(newuser);
                        response.sendRedirect("index.jsp");
                    }
                }
                else { //用户名相同,但是邮箱已注册
                    msg = "啊呀!这个邮箱被人注册了!";
                }
                stmt.close(); con.close();
            }
            catch (Exception e) {
                msg = e.getMessage();
            }
          }
          else { //用户名已注册
            msg = "啊哦!这个名字已经被别人抢先一步了!";
          }
    }
    %>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>注册</title>
        <script src="js/loginAndRegister.js"></script>
        <style>
            * {
                font-family: Brush Script MT, STKaiti, YouYuan, sans-serif;
            }
            a {
                text-decoration: none;
            }
    
            body {
                font-size: 15px;
            }
    
            input {
                font-family: 微软雅黑;
            }
    
            div#backgroundpic {
                position: absolute;
                z-index: -100;
                left: 0px;
                top: 0px;
                width: 100%;
                height: 100%;
                background: url("images/wholehomepic.jpeg")no-repeat;
                background-size: cover;
                opacity: 0.5;
            }
    
            div#signUpContain {
                text-align: center
            }
    
            div#signUpContain form {
                width: 300px;
                margin: 0 auto;
                /* text-align: center */
            }
    
            div#signUpContain form input {
                display: block;
                width: 300px;
                line-height: 35px;
                text-indent: 1em;
                margin: 30px 0;
                border-radius: 5px;
            }
    
            div#signUpContain form input:last-child {
                text-indent: 0;
                width: 300px;
                outline: none;
                border: 1px solid lightgray;
                background-color: gray;
                line-height: 35px;
                color: white;
                font-size: 18px;
                font-weight: bold;
            }
    
            span#registerMsg {
                font-family: 宋体;
                color: red;
                font-weight: bold;
            }
    
            @media only screen and (max-width: 600px) {
                div#signUpContain form input {
                    width: 250px;
                    margin: 20px auto;
                    line-height: 35px;
                }
    
                div#signUpContain form input#confirm {
                    width: 250px;
                }
            }
    
            div#signUpContain form>div {
                position: relative;
            }
    
            div#signUpContain form span {
                line-height: 10px;
                left: 10px;
                top: 45px;
                position: absolute;
            }
        </style>
    </head>
    <body>
        <div id="backgroundpic"></div>
        <div id="signUpWrap">
            <div id="signUpContain">
                <h1>注册</h1>
                <form action="signup.jsp" method="post" name="formRegister">
                    <div>
                        <input type="text" placeholder="昵称" name="name" id="username" oninput="register_check(id)">
                        <span class="username"></span>
                        <%-- 显示提示消息 --%>
                    </div>
                    <div>
                        <input type="text" placeholder="邮箱" name="email" id="email" oninput="register_check(id)">
                        <span class="email"></span>
                        <%-- 显示提示消息 --%>
                    </div>
                    <div>
                        <input type="password" placeholder="密码" name="password" id="password" onchange="register_check(id)">
                        <span class="password"></span>
                        <%-- 显示提示消息 --%>
                    </div>
                    <div>
                        <input type="password" placeholder="确认密码" name="password2" id="password2" onchange="register_check(id)">
                        <span class="password2"></span>
                        <%-- 显示提示消息 --%>
                    </div>
                    <input type="button" value="注册" onclick="doCheck_Register()" id="confirm">
                </form>
                <p>已有帐号?<a href="login.jsp">前往登录</a></p>
                <span id="registerMsg"><%=msg%><span>
                <span id="result"></span>
            </div>   
        </div>
    </body>
    <script>   
        //===============注册界面输入框检测函数===============
        function register_check(id) {
            // 创建http请求
            var inPut_value = document.getElementById(id).value;
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function () {
                // 当http请求的状态变化时执行 
                if (xmlhttp.readyState == 4) { // 4-已收到http响应数据
                    if (xmlhttp.status >= 200 && xmlhttp.status < 300 || xmlhttp.status == 304) {
                        var inPut = document.getElementById(id);
                        var span_result = document.getElementsByClassName(id)[0];
                        inPut_value = inPut.value;
                        // 200~299-OK 304-unmodified
                        // alert(xmlhttp.responseText);
                        // http响应的正文 
                        span_result.innerHTML = xmlhttp.responseText;
                    } else {
                        alert("error");
                    }
                };
            }; //打开http请求(open)的参数:get|post,url,是否异步发送 
    
            // 提交输入值前进行判断,解决MySQL注入单引号问题,不过未完全解决MySQL注入的问题,TODO
            if (id == "username" || id == "email")
                inPut_value = inPut_value.split("'").join("");
            xmlhttp.open("get", "registerCheck.jsp?id=" + id + "&value=" + inPut_value, true);
            xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xmlhttp.send(null);
            //发送http请求。get只能用null作为参数 
        }
        //===============END注册界面输入框检测函数===============
    </script>
    </html>
    

    {% endfold %}

    后端检查程序registerCheck.jsp

    {% fold %}

    <%@page language="java" import="java.util.*,java.sql.*" contentType="text/html; charset=utf-8"%>
    <% request.setCharacterEncoding("utf-8");
        String param = request.getParameter("id");
        String value = request.getParameter("value");
        String conStr = "jdbc:mysql://172.18.187.10:3306/blog_15336202"
        + "?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8";
        Class.forName("com.mysql.jdbc.Driver"); // 查找数据库驱动类
        Connection con=DriverManager.getConnection(conStr, "user", "123");
        Statement stmt=con.createStatement(); //创建MySQL语句的对象
        
        if (value.equals("")) {
            out.print("输入点东西嘛~这么小气╭(╯^╰)╮");
        }
        else {
            if (param.equals("username")) {
                ResultSet rs=stmt.executeQuery("select * from users where name='" + value + "'");
                if (!rs.next()) {
                    out.print("该昵称可以使用o(∩_∩)o");
                }
                else {
                    out.print("该昵称已被注册了哦o_O");
                }
            
                rs.close();
            }
            else if (param.equals("email")) {
                ResultSet rs=stmt.executeQuery("select * from users where email='" + value + "'");
                if (!rs.next()) {
                    out.print("这个邮箱可以使用呢o(∩_∩)o");
                }
                else {
                    out.print("阿叻~这个邮箱被人注册了哦");
                }
                rs.close();
            }
        }
        stmt.close(); con.close();
    %>
    

    {% endfold %}

    初学前端,记录学习的内容和进度~
  • 相关阅读:
    CentOS 7部署KVM之三基本管理
    CentOS 7部署KVM之二安装配置
    CentOS 7部署KVM之一架构介绍
    DOM 事件流
    渐进增强与优雅降级
    (三)跟我一起玩Linux网络服务:DHCP服务配置之主服务器配置
    (二)跟我一起玩Linux网络服务:BIND的自动部署(附上完整的代码)
    责任链模式--行为模式
    装饰模式--- 结构型模式
    elastic-job+zookeeper实现分布式定时任务调度的使用(springboot版本)
  • 原文地址:https://www.cnblogs.com/xiuhua/p/13398781.html
Copyright © 2020-2023  润新知