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>请输入密码: <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> <input name="vericode" placeholder="验证码" value="" style="width: 60px"> <img id="vericodeImg" src="imageCode"> <a id="kanbuq" href="javascript:changeImg();">看不清,换一张</a><br><br> <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和lchar[] 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-1int 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 ~ 24return 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 securityCodefor (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);}}
最终效果:
相关文章:

Java后端开发——实现登录验证程序
一、实现一个简单登录验证程序 实现一个简单的用户登录验证程序,如果用户名是 abc ,密码是 123,则显示欢迎用户的信息,否则显示“用户名或密码不正确”。 【分析】 该案例采用 JSP 页面只完成提交信息和验证结果的显示ÿ…...
CSS高频面试题
1.行内元素有哪些?块级元素有哪些?空元素有哪些?CSS的盒模型? 块级元素:div, p, h1-h6,form, ul ,li行内元素:a, b, br, span, i, input, select行内块级元素:img , input空元素:即没有内容的HTML元素,…...

解决matlab报错“输入参数的数目不足”
报错语句:tanh((peakNums-parameter)/2) 报错提示:输入参数的数目不足 运行环境:matlab2021b 分析原因: 当执行peakNums - parameter时,如果peakNums和parameter都是向量,那么这并不一定意味着会得到对应…...
使用python_opencv比较图像差异/使用python_opencv找出两张图像的差异范围
目录 1 创建conda环境 2 安装python库 2.1 报错 ModuleNotFoundError: No module named numpy 3 image_diff.py...

NOIP2023模拟1联测22 爆炸
NOIP2023模拟1联测22 爆炸 题目大意 自己看 思路 当一个炸弹被引爆后,它的方向是固定的。如果被竖着引爆,那么应该选择横着引爆,否则选择竖着引爆,这是显然 的。 考虑对于每个炸弹 ( i , j ) (i , j) (i,j) 将第 i i i 行…...

http post协议实现简单的rpc协议,WireShark抓包分析
文章目录 1.http 客户端-RPC客户端1.http 服务端-RPC服务端3.WireShark抓包分析3.1客户端到服务端的HTTP/JSON报文3.2服务端到客户端的HTTP/JSON报文 1.http 客户端-RPC客户端 import json import requests# 定义 RPC 客户端类 class RPCClient:def __init__(self, server_url…...
1024程序员节
一年一年真快啊,...
嵌入式--->怎样选择编译语言,C C++或是Rust?
C 老牌语言,不可替代,速度和资源占用都是嵌入式领域着重考虑的 Rust 作为新生语言,已经成长到可以和C进行竞争的地步,不论是速度还是资源占用看,还是安全性 C 嵌入式开发使用C的思想,可以极大地简化代码&am…...

一起学数据结构(12)——归并排序的实现
1. 归并排序原理: 归并排序的大概原理如下图所示: 从图中可以看出,归并排序的整体思路就是把已给数组不断分成左右两个区间,当这个区间中的数据数量到达一定数值时,便返回去进行排序,整体的结构类似二叉树…...

读书笔记之《敏捷测试从零开始》(一)
大家好,我是rainbowzhou。 子曰:学而时习之,不亦说乎?今天我想和大家分享一本测试书籍——《敏捷测试从零开始》。以下为我的读书笔记: 精彩片段摘录: 焦虑往往来自于对比,当你在自己的圈子里面…...
视频亮度太低了,如何调高
充足、均匀、稳定的光亮对于视频制作是至关重要的,在现实生活中,不可预见的天气变化和拍摄地方的阴暗常常给我们留下暗淡无光的视频片段。 如果你的视频太暗想知道如何使它变亮,且又不知道使用哪个工具,那你无需担心,因…...

Xubuntu16.04系统中安装create_ap创建无线AP
1.背景说明 在Xubuntu16.04系统的设备上安装无线WIFI模块后,想通过设备自身的无线AP,进行和外部设备的连接,需要安装create_ap软件,并设置无线AP的名称和密码,并设置为开机自启动。 create_ap是一个用于在Linux系统上创…...
WPF 设置全局静态参数
可以使用system官方库来设置参数 引入system xmlns:system"clr-namespace:System;assemblymscorlib"设置参数资源 <Window.Resources><system:Double x:Key"ButtonWidth">90</system:Double></Window.Resources>使用参数资源 &l…...
Leetcode链表问题汇总
目录 [2. 两数相加](https://leetcode.cn/problems/add-two-numbers/)[206. 反转链表](https://leetcode.cn/problems/reverse-linked-list/)[206. 反转链表 II](https://leetcode.cn/problems/reverse-linked-list-ii/)[19. 删除链表的倒数第 N 个结点](https://leetcode.cn/p…...

基于卷的磁盘扫描算法设计
1、设计目的 常规情况下,当我们扫描计算机的硬盘时, 通常会使用诸如FindFirstFile/FindNextFile(Windows),或者opendir/readdir(Linux)遍历扫描的目录。 一般情形下,由于文件数量相对较少,文件夹层次低,扫…...

计算机组成原理-存储器概念
计算机组成原理-存储器 存储系统的基本概念 1.层次结构 可以直接被CPU读取: 高速缓存:cache主存储器: 主存和内存 辅助存储器: 辅存和外存 2.分类 1.按层次结构划分 如上面所示 2.按存储介质 半导体存储器磁表面存储器光存储器 3.按信息可更改性 r/w存储器ROM(只读存储器) 4…...

力扣刷题 day54:10-24
1.十进制整数的反码 每个非负整数 N 都有其二进制表示。例如, 5 可以被表示为二进制 "101",11 可以用二进制 "1011" 表示,依此类推。注意,除 N 0 外,任何二进制表示中都不含前导零。 二进制的反…...

Java基础篇 | Java8流式编程
✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉 🍎个人主页:Leo的博客 💞当前专栏: Java从入门到精通 ✨特色专栏…...

SolidworksSimulation完成对压力容器的强度分析
如何通过使用SolidworksSimulation完成对压力容器的分析并查看实 体的膜片应力强度以及弯曲应力强度,操作简单易学,让我们进入到操作界面。 我们以罐体底部实体模型为例,这里已经提前设置好了材料。 点击新算例,选择静应力分析 由…...

【C++】继承 ⑨ ( 继承中成员变量同名的处理方案 )
文章目录 一、继承中成员变量同名的处理方案1、继承中成员变量同名的场景说明2、使用域作用符区分同名成员变量 二、代码示例 - 继承中成员变量同名的处理方案 一、继承中成员变量同名的处理方案 1、继承中成员变量同名的场景说明 子类 继承 父类 的 成员 , 如果 子类 中定义了…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...