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

news2024/10/2 8:30:01

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

实现一个简单的用户登录验证程序,如果用户名是 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>

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);

	}
}

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 here</title>
</head>
<body>
<%=request.getAttribute("outputMessage") %>
</body>
</html>

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>

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("登录失败");}
	}

}

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);
        }
}

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;
    }
}

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);
	}

}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1128822.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零基础Linux_22(多线程)线程控制和和C++的多线程和笔试选择题

目录 1. 线程控制 1.1 线程创建(pthread_create) 1.2 线程结束(pthread_exit) 1.3 线程等待(pthread_join) 1.4 线程取消(pthread_cancel结束) 1.5 线程tid(pthread_self()) 1.6 线程局部存储(__thread) 1.7 线程分离(pthread_detach) 2. C的多线程 3. 笔试选择题 答…

百济神州:受专利侵权诉讼影响,股价暴跌,估值已被华尔街大幅下调

来源&#xff1a;猛兽财经 作者&#xff1a;猛兽财经 百济神州股价暴跌估值已被下调 今年以来&#xff0c;百济神州(BGNE)在美股的股价已经下跌了26.1%。在2023年10月18日的的交易日结束时&#xff0c;百济神州的最后最后交易价为167.54美元&#xff0c;与2023年1月20日的52周…

Unity DOTS系列之Filter Baking Output与Prefab In Baking核心分析

最近DOTS发布了正式的版本, 我们来分享一下DOTS里面Baking核心机制&#xff0c;方便大家上手学习掌握Unity DOTS开发。今天给大家分享的Baking机制中的Filter Baking Output与Prefab In Baking。 对啦&#xff01;这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础…

优化单元测试效率:Spring 工程启动耗时统计

相关文章&#xff1a; Java Agent 的简单使用 本文相关代码地址&#xff1a;https://gitee.com/dongguabai/blog 单元测试在软件项目的可持续发展中扮演着不可或缺的角色&#xff0c;这一点毫无疑问。不久前&#xff0c;公司大佬在内部分享时也提到过&#xff1a;单元测试是…

“动捕设备+飞兔渲染软件”,激发数字人短视频营销新动力

随着短视频行业持续破发&#xff0c;短视频成为目前吸引流量最快的方式之一。同时&#xff0c;元宇宙催生众多虚拟主播、虚拟偶像、虚拟IP等&#xff0c;以数字人形象结合短视频形式&#xff0c;在社交平台上频频出圈。如虚拟美妆达人“柳夜熙”一条视频涨粉150w&#xff0c;但…

[卷积神经网络]FasterNet论文解析

一、概述 FasterNet是CVPR2023的文章&#xff0c;通过使用全新的部分卷积PConv&#xff0c;更高效的提取空间信息&#xff0c;同时削减冗余计算和内存访问&#xff0c;效果非常明显。相较于DWConv&#xff0c;PConv的速度更快且精度也非常高&#xff0c;识别精度基本等同于大型…

【计算机网络(1)】计算机网络体系结构1:计算机网络概述

文章目录 概念 & 功能 & 发展计算机网络的概念计算机网络的功能计算机网络的发展网络的本质 组成 & 分类计算机网络的组成计算机网络的分类 概念 & 功能 & 发展 计算机网络的概念 1. 网络 网一样的东西或网状系统。其中&#xff08;有线电视网络、电信网…

亲测解决no module named ‘PyQt5.QtCore‘

如果是在windows上遇到这个问题&#xff0c;升级一下VS Studio即可。 运行坏境和问题 Win10 Anaconda 解决方法 升級vs studio from 2022 preview to 2022。

springboot配置注入增强(四)使用框架实现自定义数据源和自定义属性解析

1.代码 框架代码已经上传到gitee中 代码链接&#xff1a;https://gitee.com/summer-cat001/config-enhance jar包&#xff1a;https://gitee.com/summer-cat001/config-enhance/tree/master/build/libs 2.使用方式 2.1 引入jar包 引入本地jar包或者把jar包上传到自己的ma…

年薪20w+,做测试的第4年,从手工测试到自动化测试每一步都是艰难的~

自己已经做了好几年的手工测试了&#xff0c;越来越觉得如果一直在手工测试的道路上前进&#xff0c;并不会有很大的发展&#xff0c;所以通过自己的努力&#xff0c;已经成功的转入自动化测试的方向&#xff0c;那么想快速的转入自动化方向&#xff0c;我们应该怎么做呢&#…

Linux的命令基本格式

因为对服务器来讲&#xff0c;图形界面会占用更多的系统资源&#xff0c;而且会安装更多的服务、开放更多的端口&#xff0c;这对服务器的稳定性和安全性都有负面影响。其实&#xff0c;服务器是一个连显示器都没有的家伙&#xff0c;要图形界面干十么&#xff1f;说到这里&…

python—openpyxl操作excel详解

前言 openpyxl属于第三方模块&#xff0c;在python中用来处理excel文件。 可以对excel进行的操作有&#xff1a;读写、修改、调整样式及插入图片等。 但只能用来处理【 .xlsx】 后缀的excel文件。 使用前需要先安装&#xff0c;安装方法&#xff1a; pip install openpyxl…

基于二维小波变换的散斑相位奇异构造算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 图(1)表示散斑原图像&#xff0c;(2)表示对(1)图像进行x轴方向的极化分析的小波相位图&#xff0c;呈周期的水平条纹&#xff0c;(3)表示对(1)图像…

大数据Doris(十二):扩容缩容

文章目录 扩容缩容 一、FE 扩容和缩容 1、增加 FE 节点 2、 删除 FE 节点

非接触式外径测量仪 光电在线检测

非接触式的检测方式可以在不损伤产品表面的情况下&#xff0c;进行高精度的检测&#xff0c;它能对一些高温、熔融等不易测量的轧材检测&#xff0c;适用面更广。光电非接触式的外径测量仪同样是非接触式的检测方式&#xff0c;完成了线缆电缆、橡胶、塑料等产品的高精度检测。…

YOLOv7改进:新颖的上下文解耦头TSCODE,即插即用,各个数据集下实现暴力涨点

💡💡💡本文属于原创独家改进:上下文解耦头TSCODE,进行深、浅层的特征融合,最后再分别输入到头部进行相应的解码输出,实现暴力暴力涨点 上下文解耦头TSCODE| 亲测在多个数据集实现暴力涨点,对遮挡场景、小目标场景提升也明显; 收录: YOLOv7高阶自研专栏介绍: …

✔ ★【备战实习(面经+项目+算法)】 10.22学习时间表(总计学习时间:4.5h)(算法刷题:7道)

✔ ★【备战实习&#xff08;面经项目算法&#xff09;】 坚持完成每天必做如何找到好工作1. 科学的学习方法&#xff08;专注&#xff01;效率&#xff01;记忆&#xff01;心流&#xff01;&#xff09;2. 每天认真完成必做项&#xff0c;踏实学习技术 认真完成每天必做&…

rust学习——操作字符串、字符串转义、操作UTF8-字符串 (操作中文字符串)

文章目录 操作字符串追加 (Push)插入 (Insert)替换 (Replace)1、replace2、replacen3、replace_range 删除 (Delete)1、 pop —— 删除并返回字符串的最后一个字符2、 remove —— 删除并返回字符串中指定位置的字符3、truncate —— 删除字符串中从指定位置开始到结尾的全部字…

CentOS7单磁盘挂载一个目录

1、查看磁盘是否存在 fdisk -l 2、格式化磁盘 mkfs -t ext4 /dev/vdb 3、查看磁盘分区的UUID blkid /dev/vdb 4、创建挂载目录 mkdir -p /data 5、磁盘挂载 mount /dev/vdb /data 6、设置开机启动自动挂载 需要让系统开机自动挂载&#xff0c;需要将挂载信息写入到/etc/f…

安装PyCharm必看,手把手教你安装pycharm

目录 一&#xff0c;简介 二&#xff0c;安装包 一&#xff0c;简介 Jetbrains家族和Pycharm版本划分&#xff1a; pycharm是Jetbrains家族中的一个明星产品&#xff0c;Jetbrains开发了许多好用的编辑器&#xff0c;包括Java编辑器&#xff08;IntelliJ IDEA&#xff09;、…