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、继承中成员变量同名的场景说明 子类 继承 父类 的 成员 , 如果 子类 中定义了…...

Chapter03-Authentication vulnerabilities
文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...