• Java后端开发——实现登录验证程序


    一、实现一个简单登录验证程序

    实现一个简单的用户登录验证程序,如果用户名是 abc ,密码是 123,则显示欢迎用户的信息,否则显示“用户名或密码不正确”。

    【分析】 该案例采用 JSP 页面只完成提交信息和验证结果的显示,而验证过程由 Servlet 完成,这些组件通过 request (或 HttpServletRequest)对象实现数据共享。由提交页面将数据传递给 Servlet,而 Servlet 获取数据并实现验证,根据验证结果,转向显示验证结果的页面。

    【设计】 根据分析,该系统需要设计3个组件以及修改 web.xml 文件。

    (1)登录表单页面: login.jsp。

    (2)处理登录请求并实现验证的 Servlet:LoginCheckServlet.java。

    (3)显示提示的页面: Info.jsp。

    (4)修改 web.xml,配置 Servlet的信息。

    假设,表单传递的参数为 username 和 userpwd。

    1.登录表单页面login.jsp:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>登录页面</title>
    </head>
    <body>
    <form action="CheckServlet" method="post">
    	<table>
    		
    			<tr align="center">
    				<td>请输入用户名:<input type="text" name="username" size="20">
    				</td>
    			</tr>
    			<tr align="center">
    				<td>请输入密码:&nbsp;&nbsp;<input type="password" name="userpwd"
    					size="20">
    				</td>
    			</tr align="center">
    			<td><input type="submit" value="登录" /> <input type="reset" /></td>
    			</tr>
    	</table>
    </form>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    2.处理登录的 Servlet:LoginCheckServlet.java

    package servlet;
    
    import jakarta.servlet.ServletException;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class LoginCheckServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	     	String userName = request.getParameter("username");
    			String userPwd = request.getParameter("userpwd");
    			String info = "";
    			if(("abc".equals(userName))&&"123".equals(userPwd)){
    				info = "欢迎你"+userName+"!";
    			}else{
    				info = "用户名或密码不正确!";
    			}
    			request.setAttribute("outputMessage", info);
    			request.getRequestDispatcher("/info.jsp").forward(request,response);
    
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    3.显示提示的页面 info.jsp:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title heretitle>
    head>
    <body>
    <%=request.getAttribute("outputMessage") %>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    4.修改配置文件,在 web.xml 中,修改LoginCheckServlet 的配置信息:

    在这里插入图片描述
    注意:与前面的表单action路径一致
    在这里插入图片描述
    5.运行效果图
    在这里插入图片描述
    输入正确的用户名和密码
    在这里插入图片描述
    在这里插入图片描述
    输入错误的用户名和密码
    在这里插入图片描述

    二、实现一个带验证码登录验证程序

    1.前端的登陆页面如下:login.jsp

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
      <form action="login" method="post">
          姓名:<input name="name" type="text"><br><br>
          密码:<input name="password" type="password"><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          <input name="vericode" placeholder="验证码" value="" style="width: 60px">&nbsp;&nbsp;
          <img id="vericodeImg" src="imageCode">&nbsp;&nbsp;
          <a id="kanbuq" href="javascript:changeImg();">看不清,换一张</a><br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          <input type="submit" value="提交">
      </form>
      <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
      <script type="text/javascript">
          function changeImg() {
              //需要让每次请求的url都发生变化。否则服务器会认为访问的时一张图片,就不会刷新请求了
              //每次url一样,服务器会认为访问的url是同一张图片,没变化啊
              $("#vericodeImg").attr("src","imageCode?"+Math.random())
          }
      </script>
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    2.后端的LoginServlet登陆实现逻辑如下:LoginServlet.java

    映射的url-patten: /login

    package servlet;
    
    import jakarta.servlet.ServletException;
    import jakarta.servlet.annotation.WebServlet;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    public class LoginServlet extends HttpServlet {
    	private static final long serialVersionUID = 1L;
         
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    	}
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		    response.setContentType("text/html;charset=utf8");
    	        String name=request.getParameter("name");
    	        String password=request.getParameter("password");
    	        String vericode=request.getParameter("vericode");
    	        String generatedCode= (String) request.getSession().getAttribute("verityCode");
    	        if (name.equals("bob")&&password.equals("123")&&vericode.toLowerCase().equals(generatedCode.toLowerCase())){
    	        	response.getWriter().write("登录成功");
    	        }else {response.getWriter().write("登录失败");}
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    3.下面是两个工具代码:生成验证码字符串CreateVerificationCode.java

    package bean;
    
    import java.util.Arrays;
    
    public class CreateVerificationCode {
        /**
         * 验证码难度级别
         */
        public enum SecurityCodeLevel {
            Simple,
            Medium,
            Hard
        }
    
        public static String getSecurityCode() {
            return (String) getSecurityCode(4, SecurityCodeLevel.Medium, false);
        }
    
        public static String getSecurityCode(int length, SecurityCodeLevel level, boolean isCanRepeat) {
            int len = length;
            //除去容易混淆的0和o,1和l
            char[] codes = {
                    '1', '2', '3', '4', '5', '6', '7', '8', '9',
                    'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
                    'j', 'm', 'n', 'p', 'q', 'r', 's', 't','u',
                    'v', 'w', 'x', 'y', 'z','A','B','C','D','E',
                    'F','G','H','J','K','L','M','N','P','Q','R','S',
                    'T','U','V','W','X','Y','Z'};
            if(level==SecurityCodeLevel.Simple){
                codes= Arrays.copyOfRange(codes,0,9);
            }else if (level==SecurityCodeLevel.Medium){
                codes= Arrays.copyOfRange(codes,0,33);
            }
            int n=codes.length;
            //抛出运行时异常
            if (len>n&&isCanRepeat==false){
                throw new RuntimeException(
                        String.format("调用securitycode.getSecurityCode(%1$s,len,level,isCanRepeat,n)"));}
                        char[] result=new char[len];
            //判断能否出现重复的字符
            if (isCanRepeat){
                for(int i=0;i<result.length;i++){
                    //索引0 and n-1
                    int r=(int)(Math.random()*n);
                    //将result中的第i个元素设为codes[r]存放的数值
                    result[i]=codes[r];
                }
            }else {
                for (int i=0;i<result.length;i++){
                    int r=(int)(Math.random()*n);
                    //将result中的第i个元素设为codes[r]存放的数值
                    result[i]=codes[r];
                    codes[r]=codes[n-1];
                    n--;
                }
            }
            return String.valueOf(result);
            }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    4.生成验证码图片(它是基于生成验证码字符串类的)CreateVerificationCodeImage.java

    package bean;
    
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.util.Random;
    
    /**
     * 可生成数字,大写,小写字母及三者混合类型的验证码,支持自定义干扰线,图文颜色
     */
    public class CreateVerificationCodeImage {
        private String securityCode;
        public CreateVerificationCodeImage(String securityCode){
            this.securityCode=securityCode;
        }
        //高度
        private static final int CAPTCHA_HEIGHT = 35;
        //宽度
        private static final int CAPTCHA_WIDTH  = 100;
        //数字的长度
        //private static final int NUMBER_CNT     = 6;
        private Random r = new Random();
        //  字体
        private String[] fontNames = { "宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312" };
        //private String[] fontNames = { "宋体",  "黑体", "微软雅黑"};
    
        /**
         * 机能概要:生成随机的颜色
         * @return
         */
        private Color randomColor() {
            int red = r.nextInt(150);
            int green = r.nextInt(150);
            int blue = r.nextInt(150);
            return new Color(red, green, blue);
        }
    
        /**
         * 机能概要:生成随机的字体
         * @return
         */
        private  Font randomFont() {
            int index = r.nextInt(fontNames.length);
            String fontName = fontNames[index];// 生成随机的字体名称
            int style = r.nextInt(4);// 生成随机的样式, 0(无样式), 1(粗体), 2(斜体), 3(粗体+斜体)
            int size = r.nextInt(5) + 24; // 生成随机字号, 24 ~ 28
           // int size = r.nextInt(5) + 15; // 生成随机字号, 20 ~ 24
            return new Font(fontName, style, size);
        }
    
        // 画干扰线
        private  void drawLine(BufferedImage image) {
            int num = 5;// 一共画5条
            Graphics2D g2 = (Graphics2D) image.getGraphics();
            for (int i = 0; i < num; i++) {// 生成两个点的坐标,即4个值
                int x1 = r.nextInt(CAPTCHA_WIDTH);
                int y1 = r.nextInt(CAPTCHA_HEIGHT);
                int x2 = r.nextInt(CAPTCHA_WIDTH);
                int y2 = r.nextInt(CAPTCHA_HEIGHT);
                g2.setStroke(new BasicStroke(1.5F));
                g2.setColor(randomColor()); // 随机生成干扰线颜色
                g2.drawLine(x1, y1, x2, y2);// 画线
            }
        }
        // 创建BufferedImage,生成图片
        public BufferedImage createImage() {
            BufferedImage image = new BufferedImage(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = (Graphics2D) image.getGraphics();
            // 背景色,白色
            g2.setColor(new Color(255, 255, 255));
            g2.fillRect(0, 0, CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
    
            // 向图片中画4个字符  String securityCode
            for (int i = 0; i < securityCode.length(); i++) {// 循环四次,每次生成一个字符
                String s = securityCode.charAt(i) + "";// 随机生成一个字母
               // float x = i * 1.0F * CAPTCHA_WIDTH / NUMBER_CNT; // 设置当前字符的x轴坐标
                float x = i * 1.0F * CAPTCHA_WIDTH / 4+7F; // 设置当前字符的x轴坐标
                g2.setFont(randomFont()); // 设置随机字体
                g2.setColor(randomColor()); // 设置随机颜色
                g2.drawString(s, x, CAPTCHA_HEIGHT-7); // 画图,依次将字符写入到图片的相应位置-------------------
            }
            drawLine(image); // 添加干扰线
            return image;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    5)调用工具类的生成验证码图片的方法,在通过response对象,将图片流返回给前端,有img标签的src属性负责解析:ImageCodeServelt.java
    映射的url-patten: /imageCode

    package servlet;
    
    import jakarta.servlet.ServletException;
    import jakarta.servlet.annotation.WebServlet;
    import jakarta.servlet.http.HttpServlet;
    import jakarta.servlet.http.HttpServletRequest;
    import jakarta.servlet.http.HttpServletResponse;
    import jakarta.servlet.http.HttpSession;
    
    import java.io.IOException;
    
    import javax.imageio.ImageIO;
    
    import bean.CreateVerificationCode;
    import bean.CreateVerificationCodeImage;
    
    
    public class ImageCodeServelt extends HttpServlet {
    	private static final long serialVersionUID = 1L;
    	
    	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		 String vericode= CreateVerificationCode.getSecurityCode();
    	        HttpSession session=request.getSession();
    	        session.setAttribute("verityCode",vericode);
    	        //设置返回的内容
    	        response.setContentType("img/jpeg");
    	        //浏览器不缓存响应内容--验证码图片,点一次就要刷新一次,所以不能有缓存出现
    	        response.setHeader("Pragma","No-cache");
    	        response.setHeader("Cache-Control","no-cache");
    	        //设置验证码失效时间
    	        response.setDateHeader("Expires",0);
    	        //以字节流发过去,交给img的src属性去解析即可
    	        ImageIO.write(new CreateVerificationCodeImage(vericode).createImage(),"JPEG",response.getOutputStream());
    
    	}
    
    	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		doGet(request, response);
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    最终效果:
    在这里插入图片描述

  • 相关阅读:
    2023最新SSM计算机毕业设计选题大全(附源码+LW)之java线上学习系统8e88w
    基于OpenAPI、freemarker动态生成swagger文档
    Linux中SAMBA服务管理与搭建
    手把手教你用站长工具综查询网站域名在各个平台的权重情况 站长工具综查询
    Git大全
    EMERSON艾默生变频器维修M600/M701/M702
    近红外染料CY5.5标记海藻酸钠|海藻酸钠-CY5.5|alginate-peg-Cyanine5.5
    在ESP32上使用Arduino(Arduino as an ESP-IDF component)
    ECharts与Excel的结合实战
    i.MX 6ULL 驱动开发 四:设备树
  • 原文地址:https://blog.csdn.net/Myx74270512/article/details/134018568