首先声明这个案例是我白嫖的,但是嫖到一半发现代码不全,所以就自己就完善了案例代码!希望后续的小狐伴们不要碰到这个坑!!!

话不多说先看效果图:

这是登录首页:(这个案例其实很简陋,但是为了和你们分享,首页我还是花了一段时间修改的!)

这是登录成功后的界面:

说实话真的很丑!!!但是别急,作为java后台人员我们不追求这个,我们追求的是技术,是可以买到面包和爱情的技术!来看下面的案例代码结构!!

上面是实现怎个案例的所有文件,本来应该按照MVC的框架放包的,但是怕和我一样的小白头晕,所以就简化了!不懂得可以私聊我哦!虽然我也不是很懂!接下来我们一个个分析上面的文件!我们先从视图层开始分享吧!(为什么不是说前端页面呢!因为最近了解到jsp实质还是java,请看下面我随便找到的一篇“高质量博客,博主也是这么认为的呢!)

index.jsp

<%-- Created by IntelliJ IDEA. --%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<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>Login</title><script>/*分析:点击超链接或者图片,需要换一张1.给超链接和图片绑定单击事件2.重新设置图片的src属性值PS:生成的图片先要缓存在本地,每次请求是不会修改,所以验证码图片不会切换;* 将图片路径后添加时间戳,通过错误的路径来欺骗服务器重新请求*/window.onload = function () {//1.获取图片对象var img = document.getElementById("checkCode");//2.绑定图片单击事件img.onclick = function () {//加时间戳var date = new Date().getTime();//加时间戳,防止浏览器利用缓存img.src = "/VerificationCode?" + date;}//绑定链接点击事件var ahref = document.getElementById("change");ahref.onclick = function () {var date = new Date().getTime();img.src = "/VerificationCode?" + date;}}</script><style>body {/* 不重复 */background: url("img/backgroundimg2.jpg") no-repeat;/* 背景铺满 */background-size: 100% auto;}div {color: red;}#login-box {width: 30%;height: auto;/* 居中 */margin: 0 auto;/* 中央位置 */margin-top: 15%;/* 内容居中 */text-align: center;background: #00000080;padding: 20px 50px;}#login-box h1 {color: #fff;}#login-box .form .item {margin-top: 15px;}#login-box .form .item i {font-size: 18px;color: #fff;}/* input border */#login-box .form .item input {width: 180px;font-size: 18px;border: 0;border-bottom: 2px solid #fff;padding: 6px 10px;background: #ffffff00;color: #fff;}#login-box .button {margin-top: 15px;width: 180px;height: 30px;font-size: 20px;font-weight: 700;color: #fff;background-image: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);/* background-image: linear-gradient(to top, #a8edea 0%, #fed6e3 100%); */border: 0;border-radius: 15px;}</style>
</head><body><form class="box" action="${pageContext.request.contextPath}/ServletLogin" method="POST"><div id="login-box"><h1>Login</h1><!-- 输入框 --><div class="form"><div class="item"><i class="fa fa-user-circle-o" aria-hidden="true"></i><input type="text" name="username" placeholder="Username"></div><div class="item"><i class="fa fa-key" aria-hidden="true"></i><input type="password" name="password" placeholder="Password"></div><div class="item"><i class="fa fa-check-circle-o" aria-hidden="true"></i><input type="text" name="checkCode" placeholder="验证码"></div><div><br><img id="checkCode" src="${pageContext.request.contextPath}/VerificationCode" alt="checkCode"><a id="change" href="">看不清?换一张</a></div></div><input type="submit" class="button" value="Login"></div></form><div ><%=request.getAttribute("CHECKCODE_Error")==null ? "" : request.getAttribute("CHECKCODE_Error")%></div><div><%=request.getAttribute("Login_Error")==null ? "" : request.getAttribute("Login_Error")%></div></body>
</html>

backgroundimg.jpg
index视图层背景图

背景图我都给你准备好了,你看我就差拿着你的手敲代码了!

success.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>Title</title><style type="text/css">body{background: url("img/success.jpg") no-repeat;background-size: 100% auto;}</style>
</head>
<body>
<h1>sucesss</h1>
</body>
</html>

这个成功视图层我不想写,就放了一张背景图,关于登录成功背景图似乎有点少,还很丑!真的丑。。。。

success.jpg
​​登陆成功背景图

背景图给你们了,总不要说我小气了吧!还有一个背景图好丑又模糊,我就不给你们了,反正也没什么用!

关于web.xml是没有任何代码配置的!对于新手的话我挺建议走web.xml依赖注入的!但是我这次没用,就下次用吧!

来看servlet代码类:
ServletLogin.java
package com.dsw.varification;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;/*** @author Vere*/
@WebServlet(name ="ServletLogin",urlPatterns = "/ServletLogin")
public class ServletLogin extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//1.设置编码req.setCharacterEncoding("UTF-8");resp.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=UTF-8");String verification = req.getParameter("checkCode");//2.获取所有请求参数String username = req.getParameter("username");String password = req.getParameter("password");User loginUser = new User(username,password);//4.验证码处理//4.1获取生成的验证码HttpSession session = req.getSession();String validation_code = (String) session.getAttribute("validation_code");//删除session中存储的验证码,防止重复使用session.removeAttribute("validation_code");//4.2判断验证码是否正确if (validation_code != null && validation_code.equalsIgnoreCase(verification)) {//忽略大小写,比较字符串,验证码正确User user = new User(username,password);//判断用户名和密码是否一致//5.调用UserDao的login方法//6.判断userif ("admin".equals(username)&&"root".equals(password)) {//登陆成功,存储数据req.setAttribute("user", user);session.setAttribute("username", user.getName());//转发req.getRequestDispatcher("/successServlet").forward(req, resp);}else {//登录失败req.getRequestDispatcher("/failServlet").forward(req, resp);}}else {//验证码不一致//存储提示信息到requestreq.setAttribute("CHECKCODE_Error", "验证码错误");//转发到登录页面req.getRequestDispatcher("index.jsp").forward(req, resp);}}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doPost(req, resp);}
}

上课了,看黑板!关于下面这个注释能看懂吗?

@WebServlet(name ="ServletLogin",urlPatterns = "/ServletLogin")
不懂得看下面,能的也要看下面,你以为你很牛逼吗?
属性名 类型 描述
name String 指定Servlet 的 name 属性,等价于 <servlet-name>。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。
value String[] 该属性等价于 urlPatterns 属性。两个属性不能同时使用。
urlPatterns String[] 指定一组 Servlet 的 URL 匹配模式。等价于<url-pattern>标签。
loadOnStartup int 指定 Servlet 的加载顺序,等价于 <load-on-startup>标签。
initParams WebInitParam[] 指定一组 Servlet 初始化参数,等价于<init-param>标签。
asyncSupported boolean 声明 Servlet 是否支持异步操作模式,等价于<async-supported> 标签。
description String 该 Servlet 的描述信息,等价于 <description>标签。
displayName String 该 Servlet 的显示名,通常配合工具使用,等价于 <display-name>标签。

主要是看name和urlPatterns这两个属性!

在Servlet中,设置了@WebServlet注解,当请求该Servlet时,服务器就会自动读取当中的信息,如果注解@WebServlet("/ServletLogin"),则表示该Servlet默认的请求路径为…/ServletLogin,这里省略了urlPatterns属性名,完整的写法应该是:@WebServlet(urlPatterns = “/ServletLogin”),如果在@WebServlet中需要设置多个属性,必须给属性值加上属性名称,中间用逗号隔开,否则会报错.
若没有设置@WebServlet的name属性,默认值会是Servlet的类完整名称.

在servlet3.0以后,web.xml中对Servlet配置,同样可以在@WebServlet注解中配置.

req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=UTF-8");

如果你和我一样害怕页面乱码!请乖乖加上这个代码,好吗?不要动不动就说“哎呀!我的怎么乱码了?”呵呵哒!比我还菜,菜鸡......

 //2.获取所有请求参数String username = req.getParameter("username");String password = req.getParameter("password");

你们谁敢说这个看不懂的?我,我看不懂,其实之前我也看不懂,不过我最近学了《葵花宝典》,我豁然开朗,竟然看懂了,

String getParameter(String name):根据参数名称获取参数值

例如例子中index.jsp中from标签传递的参数为“username”和“password”,所以最后在java程序中获得的也是username和password的值
下面是一些还没用到的方法也是关于

String[] getParameterValues(String name);//根据参数名称获取参数值的数组 hobby=xx&hobby=gameEnumeration getParameterNames();//获取所有请求的参数名称Map<String,String[]> getParameterMap();//获取所有参数的map集合

本人不建议使用Map<String,String[]> getParameterMap():

然后就是关于session这个知识点了

HttpSession session = req.getSession();
String validation_code = (String) session.getAttribute("validation_code");
//删除session中存储的验证码,防止重复使用
session.removeAttribute("validation_code");

我很好奇你掌握了session?你个菜鸡,拽什么拽,反正我不会,这是我找的笔记:活不多说这是我白嫖的,写的挺好的,喜欢的可以点进去看原文Session原理

Web三大概念:cookie,session,application

Session:记录一系列状态

Session与cookie功能效果相同。Session与Cookie的区别在于Session是记录在服务端的,而Cookie是记录在客户端的。

解释session:当访问服务器否个网页的时候,会在服务器端的内存里开辟一块内存,这块内存就叫做session,而这个内存是跟浏览器关联在一起的。这个浏览器指的是浏览器窗口,或者是浏览器的子窗口,意思就是,只允许当前这个session对应的浏览器访问,就算是在同一个机器上新启的浏览器也是无法访问的。而另外一个浏览器也需要记录session的话,就会再启一个属于自己的session

原理:HTTP协议是非连接性的,取完当前浏览器的内容,然后关闭浏览器后,链接就断开了,而没有任何机制去记录取出后的信息。而当需要访问同一个网站的另外一个页面时(就好比如在第一个页面选择购买的商品后,跳转到第二个页面去进行付款)这个时候取出来的信息,就读不出来了。所以必须要有一种机制让页面知道原理页面的session内容。

session的两种实现方式(也就是传递方式):第一种通过cookies实现。第二种通过URL重写来实现

第一种方式的理解:就是把session的id 放在cookie里面(为什么是使用cookies存放呢,因为cookie有临时的,也有定时的,临时的就是当前浏览器什么时候关掉即消失,也就是说session本来就是当浏览器关闭即消失的,所以可以用临时的cookie存放。保存再cookie里的sessionID一定不会重复,因为是独一无二的。),当允许浏览器使用cookie的时候,session就会依赖于cookies,当浏览器不支持cookie后,就可以通过第二种方式获取session内存中的数据资源。

第二种方式的理解:在客户端不支持cookie的情况下使用。为了以防万一,也可以同时使用。

如果不支持cookie,必须自己编程使用URL重写的方式实现。

如何重写URL:通过response.encodeURL()方法

encodeURL()的两个作用

第一个作用:转码(说明:转中文的编码,或者一些其他特殊的编码。就好比如网页的链接中存在中文字符,就会转换成为一些百分号或者其他的符号代替。)

第二个作用:URL后面加入sessionID,当不支持cookie的时候,可以使用encodeURL()方法,encodeUTL()后面跟上sessionID,这样的话,在禁用cookie的浏览器中同时也可以使用session了。但是需要自己编程,只要链接支持,想用session就必须加上encodeURL()。

Session中的一些常用方法说明

isNew():是否是新的Session,一般在第一次访问的时候出现

getid():拿到session,获取ID

getCreationTime():当前session创建的时间

getLastAccessedTime():最近的一次访问这个session的时间。

getRrquestedSessionid: 跟随上个网页cookies或者URL传过来的session

isRequestedSessionIdFromCookie():是否通过Cookies传过来的

isRequestedSessionIdFromURL():是否通过重写URL传过来的

isRequestedSessionIdValid():是不是有效的sessionID

session有期限

当一个网站的第一个窗口关掉了,而没有继续接着访问第二个页面,就没有使用到session。那么session会在中断程序后立刻关闭session吗?这个时候session就需要给它保留的时间,当最近一次访问的时候开始计时,每刷新一次重写开始计时。当隔了这么久的时间,没有访问这个session后,对不起,要关闭这个session了。session有过期时间,session什么时候过期,要看配置,

session能干什么

session就是服务器里面的一块内存,内存里面能放任何东西,只要是名值对就可以了。

session里面的名字永远都是String类型

这个代码还有一个知识点就是

req.getRequestDispatcher("/successServlet").forward(req, resp);

可是我不想讲了,太累了,怕你们嫌弃我啰嗦......

请求转发和重定向的区别

转发:

转发
​​​​​​

重定向:

重定向

User.java

package com.dsw.varification;/*** @author Vere*/
public class User {private String name;private String password;public User() {}public User(String name, String password) {this.name = name;this.password = password;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}

这个没有讲头了!下一个

SuccessServlet.java
package com.dsw.varification;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author Vere*/
@WebServlet(name = "SuccessServlet",urlPatterns = "/successServlet")
public class SuccessServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//页面设置编码req.setCharacterEncoding("utf-8");resp.setCharacterEncoding("utf-8");resp.setContentType("text/html;charset=UTF-8");//获取request域中共享的user对象User user= (User)req.getAttribute("user");if(user != null) {//重定向到success.jspresp.sendRedirect(req.getContextPath() + "/success.jsp");}}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

下一个

FailServlet.java 
package com.dsw.varification;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** @author Vere*/
@WebServlet(name = "FailServlet" ,urlPatterns = "/failServlet")
public class FailServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//页面设置编码resp.setContentType("text/html;charset=UTF-8");req.setAttribute("Login_Error", "用户名或密码错误");//输出resp.getWriter().write("登陆失败...用户名或密码错误");req.getRequestDispatcher("/index.jsp").forward(req, resp);}
}

注意!!!注意!!!这个要考的,快拿出笔记本出来:

VerificationCode.java 
package com.dsw.varification;import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;/*** @author Vere*/
@WebServlet(name = "VerificationCode",urlPatterns = {"/VerificationCode"})
public class VerificationCode extends HttpServlet {private static final String codeChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获得验证码集合的长度int charsLength = codeChars.length();// 下面3条记录是关闭客户端浏览器的缓冲区// 这3条语句都可以关闭浏览器的缓冲区,但是由于浏览器的版本不同,对这3条语句的支持也不同// 因此,为了保险起见,同时使用这3条语句来关闭浏览器的缓冲区resp.setHeader("ragma", "No-cache");resp.setHeader("Cache-Control", "no-cache");resp.setDateHeader("Expires", 0);// 设置图形验证码的长和宽int width = 100, height = 30;BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics g = image.getGraphics();Random random = new Random();g.setColor(getRandomColor(180, 250));g.fillRect(0, 0, width, height);g.setFont(new Font("Times New Roman", Font.ITALIC, height));g.setColor(getRandomColor(120, 180));// 用户保存最后随机生成的验证码StringBuffer validationCode = new StringBuffer();// 验证码的随机字体String[] fontNames = { "Times New Roman", "Book antiqua", "Arial" };// 随机生成4个验证码for (int i = 0; i < 5; i++) {// 随机设置当前验证码的字符的字体g.setFont(new Font(fontNames[random.nextInt(3)], Font.ITALIC,height));// 随机获得当前验证码的字符char codeChar = codeChars.charAt(random.nextInt(charsLength));validationCode.append(codeChar);// 随机设置当前验证码字符的颜色g.setColor(getRandomColor(10, 100));// 在图形上输出验证码字符,x和y都是随机生成的g.drawString(String.valueOf(codeChar), 16 * i + random.nextInt(7),height - random.nextInt(6));}// 获得HttpSession对象HttpSession session = req.getSession();// 设置session对象5分钟失效session.setMaxInactiveInterval(5 * 60);// 将验证码保存在session对象中,key为validation_codesession.setAttribute("validation_code", validationCode.toString());//关闭Graphics对象g.dispose();OutputStream outS = resp.getOutputStream();ImageIO.write(image, "JPEG", outS);}private Color getRandomColor(int minColor, int maxColor) {Random random = new Random();if(minColor > 255){minColor = 255;}if(maxColor > 255){maxColor = 255;}//获得r的随机颜色值int red = minColor+random.nextInt(maxColor-minColor);int green = minColor + random.nextInt(maxColor-minColor);int blue = minColor + random.nextInt(maxColor-minColor);return new Color(red,green,blue);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {doGet(req, resp);}
}

好了,讲完了!关于源码

Jsp+Servlet+tomcat实现简单的登录验证码案例相关推荐

  1. JSP+Servlet + JDBC 实现简单的登录验证模块

    数据库设计+编码+运行调试 数据库准备: 二话不说,上图 文件组织如下: 首先写出三个JSP页面文件 login.jsp <%@ page language="java" c ...

  2. 手把手教你用JSP+Servlet+Tomcat实现一个最简单的Web应用

    JSP+Servlet+Tomcat实现一个简单的Web应用 需要使用到的技术 ①JSP ② Servlet ③Tomcat Web开发中的常见概念 Demo *本文针对编程务实实验内容,简单演示一下 ...

  3. 爬虫三(Bs4搜索、Selenium基本使用、无界面浏览器、Selenium自动登录百度案例、自动获取12306登录验证码案例、切换选项卡、浏览器前进后退、登录Cnblogs获取Cookie自动点赞)

    文章标题 一.Bs4搜索文档树 二.CSS选择器 三.selenium基本使用 四.无界面浏览器 五.selenium其他使用 1)自动登录百度案例 2)获取位置属性大小.文本 3)自动获取12306 ...

  4. jsp+servlet实现的简单登录验证

    jsp+servlet连接数据库的登录验证 1.打开IDEA,新建login.jsp文件 <%@ page contentType="text/html;charset=UTF-8&q ...

  5. java 网上商城系统,jsp+servlet搭建的简单网上商城系统

    项目描述 这个是早期做的JSP+servlet项目,主要完成了购物的流程的功能和后台某部分功能,页面仿一号店.天猫.京东页面制作的,不兼容过早的浏览器版本,请尽量使用最新版本的浏览器!还有一些功能尚未 ...

  6. 使用Jsp+Servlet的wlop官网(验证码登录+session自动登陆)

    这个页面是我学习前端的时候自己使用JQuery写的轮播图,登录功能的后端判断未实现,现将登陆功能补充完整. 需求: 1,验证码登录# 2,账号密码登录# 3,登录失败在登录部分提示相应的信息# 3,登 ...

  7. java项目如何分工合作,JavaWeb基础 jsp+servlet分工合作的简单示例

    礼悟: 好好学习合思考,尊师重道存感恩.叶见寻根三返一,江河湖海同一体. 虚怀若谷良心主,愿行无悔给最苦.读书锻炼强身心,诚劝且行且珍惜. javaEE:7 javaSE:1.8 JSTL:1.2.2 ...

  8. Model2(JSP+Servlet+JavaBean)模式实现用户注册登录

    模块介绍 本实例为用户登录模块,采用Model2模式进行开发,展现了模型层(Model).视图层(View)和控制层(Controller). 视图层包括:用户注册登录页面(login.jsp).用户 ...

  9. java特定用户登录_求教!!!用 jsp+servlet 怎样控制指定用户名登录页面啊!

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 package cn.zmx; import java.io.IOException; import java.io.PrintWriter; impor ...

最新文章

  1. 【建模必备】遗传算法应用举例(多元单峰值函数的优化实例)
  2. DPDK架构与特点(转)
  3. word2vec原理(二):基于Hierarchical Softmax的模型
  4. SAP进销存难点分析及对策
  5. redismanager 获取不到yml中的密码_SpringBoot敏感信息加密,springboot配置文件密码加密jasypt...
  6. 为什么使用lambda表达式
  7. CUDA11.1安装教程(python3.8)
  8. 绕过模拟器检测_和平精英:光子重点打击外设与模拟器,违规将封禁365天
  9. OpenShift 4 - 用安全上下文(SC)与安全上下文约束(SCC)控制应用对受保护功能的访问
  10. 高性能队列 Disruptor
  11. pip在多个python版本中将包安装到制定版本
  12. 2.10 数值分析: 条件数的定义及计算
  13. 定时器之多层级时间轮
  14. 线程的发展史,调度策略、适用范围、特点,进程与线程的区别、线程的属性、posix线程库
  15. u盘超级加密3000使用方法
  16. matlab中的sjy定义,sjy(sjy是什么缩写)
  17. C++ 什么是继承和派生
  18. Jmeter对Web Socket进行压力测试 —— 200人直播课实战经验
  19. python Linux学习之 ansible-- ansible test -m ping运行错误
  20. 一举解决Win10所有分辨率引起的软件/系统界面字体小/文字模糊/看不清问题

热门文章

  1. 传递函数波特图的画法和理解
  2. R语言爬虫之——RCurl
  3. Android每天定时提醒功能、定时功能、闹钟
  4. git prune 分支清除
  5. Resnet 官方代码 pytorch
  6. 【Linux】【基础IO】
  7. poi-tl循环表格列和行
  8. 《智能风控实践指南》读书笔记
  9. LibGdx tmx地图加载步骤
  10. 使用xgboost进行文本分类