一、JSP
入门(了解)
1.1、概述
1.1.1、什么是JSP
JSP(Java Server Pages)
是JavaWeb
服务器端的动态资源。它与HTML
页面的作用是相同的,显示数据和获取数据。JSP可以认为成网页,网页的东西都是写在webapps下
1.1.2、JSP
组成
JSP=HTML+Java脚本+JSP动作标签(包含EL表达式)
1.2、JSP
脚本
本质上就是
Java
代码片段分类:
<%...%>
:Java语句(学)<%=…%>
:Java表达式,相当于out.print(...);
(学)<%!...%>
:Java定义类成员内置对象(无需创建就可以使用的对象):
out
对象在JSP
页面中无需创建就可以使用,它的作用是用来向客户端(浏览器)输出;<%=…%>
与out.print()
功能是相同的,它们都是向客户端输出。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsptest</title>
</head>
<body>
<h1>JSP演示</h1>
<%
// Java语句
String s1 = "hello jsp";
// 不会输出到客户端,而是在服务器端的控制台打印
System.out.println(s1);
%>
<!-- 输出到客户端浏览器上 -->
输出变量:<%=s1 %><br/>
输出int类型常量:<%=100 %><br/>
输出String类型常量:<%="你好" %><br/>
使用HTML直接输出常量<span>100</span>
</body>
</html>
在一个
JSP
中多个<%...%>
可以一起使用,看成一个整体
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsp表格</title>
</head>
<body>
<h1>表格</h1>
<table border="1" width="50%">
<tr>
<th>序号</th>
<th>用户名</th>
<th>密码</th>
</tr>
<%
for(int i = 0; i < 5; i++) {
%>
<tr>
<td><%=i+1 %></td>
<td>user<%=i %></td>
<td><%=100+1 %></td>
</tr>
<%
}
%>
</table>
</body>
</html>
问题:
Servlet和JSP都是动态资源,那我们项目中什么时候使用Servlet?什么时候使用JSP呢?
答:需要给用户显示的时候用JSP,需要在后台和数据库或者其他地方进行交互(比如跳转)的时候,用Servlet
1.3、JSP
原理
背一下
JSP
是特殊的Servlet
(查看编译后的JSP
源码)类(即本质Java类),当JSP
页面首次被访问时,容器(Tomcat
)会先把JSP
编译成Servlet
,然后再去执行Servlet
。所以JSP
其实就是一个Servlet
。
JSP
生成的Servlet
存放在tomcat
的work
目录下,它是JSP
的“真身”。我们打开看看其中的内容,了解一下JSP
的“真身”。你会发现,在
JSP
中的静态信息(例如``等)在“真身”中都是使用out.write()
完成打印!这些静态信息都是作为字符串输出给了客户端。
1.4、JSP注释
<%-- ... --%>
, 在JSP编译成.java
时会被忽略的,即JSP注释。 可以在JSP页面中使用html注释:<!-- ... -->
,但这个注释在JSP编译成的.java中是存在的,它不会被忽略,而且会被发送到客户端浏览器。
Java脚本-学生列表案例:
package com.stedu.servlet;
import com.stedu.bean.Student;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
@WebServlet(name = "test", value = "/test")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//System.out.println("测试成功");
//创建学生对象:
Student student1 = new Student(1, "张三1", 26, "m");
Student student2 = new Student(2,"张三2",26,"m");
Student student3 = new Student(3,"张三3",26,"m");
Student student4 = new Student(4,"张三4",26,"m");
//假设集合中的数据是从数据库中查询出来的:
ArrayList<Student> list = new ArrayList<>();
list.add(student1);
list.add(student2);
list.add(student3);
list.add(student4);
//如果想将这些数据显示在浏览器上面:
//将数据存放在域中,实现分享对象:
request.setAttribute("studentList",list);
//转发到JSP页面:
request.getRequestDispatcher("/test01.jsp").forward(request,response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
<%@ page import="com.stedu.bean.Student" %>
<%@ page import="java.util.ArrayList" %><%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2025/5/14
Time: 16:24
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP入门案例</title>
</head>
<body>
<%-- 这是JSP的注释,如果注释的内容包含java代码,一定要用这个注释--%>
<%-- JSP脚本:Java代码片段--%>
<%-- 功能:在浏览器上输出“呵呵”--%>
<%-- <%--%>
<%-- out.println("呵呵");//浏览器上输出--%>
<%-- String str = "abcd";--%>
<%-- %>--%>
<%-- <hr>--%>
<%-- <%=str%><%–在浏览器上面打印str,相当于out.println–%>--%>
<%-- <hr>--%>
<%
//request对象是另外一个内置对象(不用创建就能使用的对象)
//获取里面的学生,希望在表格上面显示:
ArrayList<Student> studentList = (ArrayList<Student>) request.getAttribute("studentList");
%>
<table border="1" width="50%">
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
<th>Gender</th>
</tr>
<%
for(int index = 0; index < studentList.size(); index++) {
%>
<tr>
<td><%=studentList.get(index).getId()+1%></td>
<td><%=studentList.get(index).getName()%></td>
<td><%=studentList.get(index).getAge()%></td>
<td><%=studentList.get(index).getGender()%></td>
</tr>
<%
}
%>
</table>
</body>
</html>
上述程序执行完,效果如下:
二、Cookie
Cookie的学习作了解,为学习Session做准备。
2.1、什么是Cookie
(重点)
Cookie
翻译成中文是小甜点,小饼干的意思。在HTTP中它表示服务器送给客户端浏览器的小甜点。(Cookie是服务器生成的,是服务器发送给客户端(浏览器)的)
Cookie
是在浏览器访问Web
服务器的某个资源时,由Web
服务器在HTTP
响应消息头中附带传送给浏览器的一小段数据。一旦Web
浏览器保存了某个Cookie
,那么它在以后每次访问该Web
服务器时,都应在HTTP
请求头中将这个Cookie
回传给Web
服务器。一个Cookie
主要由标识该信息的名称(name
)和值(value
)组成。
即:浏览器首次请求访问服务器时,服务器会响应给浏览器一个Cookie,在以后的请求中(访问同一个服务器时),浏览器都会携带着这个Cookie发送给服务器(发特定的Cookie),作用:在服务器和客服端之间传递数据。
2.2、Cookie
规范(了解)
Cookie
大小上限为4KB
;一个服务器最多在客户端浏览器上保存
20
个Cookie
;一个浏览器最多保存
300
个Cookie
;上面的数据只是
HTTP
的Cookie
规范,但在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己的能力起见,可能对Cookie
规范“扩展”了一些,例如每个Cooki
e的大小为8KB
,最多可保存500
个Cookie
等!但也不会出现把你硬盘占满的可能!注意,不同浏览器之间是不共享
Cookie
的。也就是说在你使用IE访问服务器时,服务器会把Cookie
发给IE
,然后由IE
保存起来,当你在使用FireFox
访问服务器时,不可能把IE
保存的Cookie
发送给服务器。
2.3、关于Cookie
的操作(了解,不用背这些代码)
下面这些都是Java代码,即都是写在Servlet当中的。
2.3.1、创建Cookie
//创建Cookie
Cookie ck=new Cookie("name", "zs");
ck.setMaxAge(-1);//内存存储,取值有三种:>0有效期,单位秒;=0浏览器关闭;<0内存存储,默认-1
response.addCookie(ck);//添加到response对象中,响应时发送给客户端
2.3.2、获取Cookie
//获取所有的Cookie
Cookie[] cks=request.getCookies();
//遍历Cookie
for(Cookie ck:cks){
//检索出自己的Cookie
if(ck.getName().equals("name")) {
//记录Cookie的值
code=ck.getValue();
break;
}
}
2.3.3、修改Cookie
只需要保证
Cookie
的名和路径一致即可修改
//修改Cookie
Cookie ck=new Cookie("name", "ls");
ck.setMaxAge(-1);//内存存储,取值有三种:>0有效期,单位秒;=0失效;<0内存存储
response.addCookie(ck);//让浏览器添加Cookie
2.3.4、Cookie
的生命
Cookie
不只有name
和value
,Cookie
还是生命。所谓生命就是Cookie
在客户端(浏览器)的有效时间,可以通过setMaxAge(int)
来设置Cookie
的有效时间。
cookie.setMaxAge(-1)
:Cookie
的maxAge
属性的默认值就是-1
,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么Cookie
就会消失。不会长期保存。cookie.setMaxAge(60*60)
:表示Cookie
对象可存活1小时。当生命大于0时,浏览器会把Cookie
保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,Cookie
也会存活1小时;cookie.setMaxAge(0)
:Cookie
生命等于0是一个特殊的值,它表示Cookie
被作废!也就是说,如果原来浏览器已经保存了这个Cookie
,那么可以通过Cookie
的setMaxAge(0)
来删除这个Cookie
。无论是在浏览器内存中,还是在客户端硬盘上都会删除这个Cookie
。
即ck.setMaxAge(-1);//内存存储,取值有三种:>0有效期(超时时间),单位秒,会放在硬盘;=0浏览器关闭,Cookie作废;<0内存存储,默认-1
案例如下:
//设置Cookie
@WebServlet(name = "AServlet", value = "/AServlet")
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置Cookie,并填写键和值
Cookie cookie = new Cookie("name", "zs");
//设置Cookie的超时时间 -1表示一旦关闭浏览器窗口,那么cookie就会消失
cookie.setMaxAge(-1);
//添加到响应对象,即发送Cookie到浏览器
response.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
//获取Cookie
@WebServlet(name = "BServlet", value = "/BServlet")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Cookie[] cks = request.getCookies();
for (Cookie ck : cks) {
if(ck.getName().equals("name")) {
//获取Cookie的值
System.out.println(ck.getValue());
break;
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
如何证明Cookie已经在浏览器上了?
(1)运行完上面的程序之后,在浏览器页面,按F12,在应用程序里面有Cookie,服务器Tomcat localhost8080,里面会显示超时时间(中央时间,与我们的时间差8个小时)等相关信息。有的电脑会F12键被占用,可采用下面图片方式查看:
(2)浏览器设置里面–管理Cookie
创建的Cookie在有效期内都能被同一个应用中的Servlet中看到。
三、Session
(重点)
3.1、什么是Session
关于会话:
- 会话范围是某个用户从首次访问服务器开始,到该用户关闭浏览器结束(关闭整个浏览器应用);
- 会话:一个用户对服务器的多次连贯性请求!所谓连贯性请求,就是该用户多次请求中间没有关闭浏览器;
- 会话:类似生活中的与10086对话,一次通话完了下一次通话并不知道上次通话的内容。
javax.servlet.http.HttpSession
接口表示一个会话(Session–域对象—范围—一次会话),是Java Web
提供的。
Session
是服务器端对象,保存在服务器端。
3.2、获取Session
HttpSession request.getSesssion()
:如果当前会话已经有了Session
对象那么直接返回,如果当前会话还不存在会话,那么创建Session
并返回;JSP
中得到Session
对象:Session
是JSP
内置对象之一,不用创建就可以直接使用。
3.3、HttpSession
域对象功能
一个会话创建一个
HttpSession
对象,同一会话中的多个请求中可以共享Session
中的数据目前为止已经学习了三个域对象,分别是
request
、session
、servletContext
,他们都有共同的方法:
void setAttribute(String name, Object value)
Object getAttribute(String name)
void removeAttribute(String name)
如果用户需要在会话范围之内共享数据,应该将数据保存在
session
中。案例,演示
session
中会话的多次请求中共享数据
@WebServlet(name = "CServlet", value = "/CServlet")
public class CServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取Session
HttpSession session = request.getSession();
//在Session域中存放数据
session.setAttribute("name", "zs");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
@WebServlet(name = "DServlet", value = "/DServlet")
public class DServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取Session
HttpSession session = request.getSession();
//从Session域中获取数据
String name = (String)session.getAttribute("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
3.4、登录案例
login.jsp
:提供登录表单,提交表单请求到`LoginServlet``
LoginServlet
:获取请求参数,校验用户是否登录成功
- 失败:跳转到登录页面,显示错误信息
- 成功:跳转到成功页,显示“欢迎xxx”的提示信息
success.jsp
:登录成功页面,显示欢迎信息,关闭浏览器后,直接访问登录页会提示登录
流程图如下所示:
LoginServlet
代码如下:
package com.stedu.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "login", value = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取用户名密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//获取Session
HttpSession session = request.getSession();
//判断用户名和密码是否正确
if(username.equals("admin") && password.equals("admin")) {
//登录成功:
session.setAttribute("user","admin");
//登录成功,跳转到成功页面:
request.getRequestDispatcher("/success.jsp").forward(request, response);
} else {
//登录失败
//提示信息:
request.setAttribute("errMsg","用户名或密码错误,请重新输入");
//登录失败重新回到登录页面:
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
login.jsp
代码
<%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2025/5/15
Time: 19:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<%
String errMsg = (String)request.getAttribute("errMsg");
if(errMsg != null) {
%>
<p style="color: red;"><%=errMsg %></p>
<%
}
%>
<form action="/02_jsp_cookie_session/login" method="post">
<%--等价于:<form action="<%=request.getContextPath() %>/lojin" method="post">--%>
<fieldset style="width: 300px;">
<legend>用户登录</legend>
<p>
<label>账号</label>
<input type="text" name="username" placeholder="请输入用户名" />
</p>
<p>
<label>密码</label>
<input type="password" name="password" placeholder="请输入密码" />
</p>
<%-- <p>--%>
<%-- <label>验证码</label>--%>
<%-- <input type="text" name="captcha" placeholder="请输入验证码" />--%>
<%-- <img src="<%=request.getContextPath()%>/captcha" onclick="this.src=this.src+'?d='+Math.random()"/>--%>
<%-- </p>--%>
<p>
<button type="submit">登录</button>
<button type="reset">重置</button>
</p>
</fieldset>
</form>
</body>
</html>
success.jsp
代码
<%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2025/6/29
Time: 14:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Object user = session.getAttribute("user");
if(user!=null){
%>
<%--session也是九大内置对象之一--%>
<p>欢迎<%=session.getAttribute("user")%></p
<%
}else{
%>
<p>您好没有登录,请先<a href="<%=request.getContextPath()%>/login.jsp">登录</a></p>
<%
}
%>
</body>
</html>
3.5、Session
原理(重要,要能自己表达出来)
Session`底层依赖`Cookie
- 当用户第一次使用
session
时(表示第一次请求服务器),服务器会创建session
,并创建一个Cookie
,在Cookie
中保存了session
的id
,发送给客户端(浏览器)。这样客户端(浏览器)就有了自己session
的id
了。但这个Cookie
只在浏览器内存中存在,也就是说,在关闭浏览器窗口后,Cookie
就会丢失,也就丢失了sessionId
;- 当用户第二次访问服务器时,会在请求中把保存了
sessionId
的Cookie
发送给服务器,服务器通过sessionId
查找session
对象,然后再使用。也就是说,只要浏览器容器不关闭,无论访问服务器多少次,使用的都是同一个session
对象。这样也就可以让多个请求共享同一个session
了;- 当用户关闭了浏览器窗口后,再打开浏览器访问服务器,这时请求中没有了
sessionId
,那么服务器会创建一个session
,再把sessionId
通过Cookie
保存到浏览器中,也是一个新的会话开始了。原来的session
会因为长时间无法访问而失效;- 当用户打开某个服务器页面长时间没动作时,这样
session
会超时失效,当用户再有活动时,服务器通过用户提供的sessionId
已经找不到session
对象了,那么服务器还是会创建一个新的session
对象,再把新的sessionId
保存到客户端。这也是一个新的会话开始了。
3.6、Session
其他API
String getId()
:获取sessionId
;
int getMaxInactiveInterval()
:获取session
可以的最大不活动时间(秒),默认为30分钟。当session
在30分钟内没有使用,那么Tomcat
会在session
池中移除这个session
;
void setMaxInactiveInterval(int interval)
:设置session
允许的最大不活动时间(秒),如果设置为1秒,那么只要session
在1秒内不被使用,那么session
就会被移除;
long getCreationTime()
:返回session
的创建时间,返回值为当前时间的毫秒值;
long getLastAccessedTime()
:返回session
的最后活动时间,返回值为当前时间的毫秒值;
void invalidate()
:让session
失效!调用这个方法会被session
失效,当session
失效后,客户端再次请求,服务器会给客户端创建一个新的session
,并在响应中给客户端新session
的sessionId
;(比如退出–设置session
失效!,重要,其他的了解即可)
boolean isNew()
:查看session
是否为新。当客户端第一次请求时,服务器为客户端创建session
,但这时服务器还没有响应客户端,也就是还没有把sessionId
响应给客户端时,这时session
的状态为新。修改
LoginServlet
,体会Session
超时时间及Session
失效
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;
@WebServlet(name = "LoginServlet", value = "/LoginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求参数
String username = request.getParameter("username");
String password = request.getParameter("password");
if(username.equals("admin") && password.equals("admin")) {
//登录成功
//保存数据到Session
HttpSession session = request.getSession();
session.setAttribute("username", username);
//设置Session超时时间为1s
session.setMaxInactiveInterval(1);
//延时2000ms,模拟Session超时
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//设置Session失效
//session.invalidate();
request.getRequestDispatcher("/success.jsp").forward(request, response);
} else {
//登录失败信息
String msg = "用户名或密码错误";
request.setAttribute("errMsg", "用户名或密码错误,请重新输入");
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
修改登录案例,增加退出功能
用于退出登录的
LogoutServlet
package com.stedu.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "logout", value = "/logout")
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//退出:让Session失效:
request.getSession().invalidate();
//跳转到登录页
response.sendRedirect(request.getContextPath() + "/login.jsp");
// request.getRequestDispatcher("/login.jsp").forward(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
修改
success.jsp
<%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2025/6/29
Time: 14:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
Object user = session.getAttribute("user");
if(user!=null){
%>
<%--session也是九大内置对象之一--%>
<p>欢迎<%=session.getAttribute("user")%></p>
<p><a href="<%=request.getContextPath()%>/logout" >退出</a></p>
<%
}else{
%>
<p>您好没有登录,请先<a href="<%=request.getContextPath()%>/login.jsp">登录</a></p>
<%
}
%>
</body>
</html>
3.7、Session
实战保存验证码
在我们注册时,如果没有验证码的话,我们可以使用
URLConnection
来写一段代码发出注册请求。甚至可以使用while(true)
来注册!那么服务器就废了!验证码可以去识别发出请求的是人还是程序!当然,如果聪明的程序可以去分析验证码图片!但分析图片也不是一件容易的事,因为一般验证码图片都会带有干扰线,人都看不清,那么程序一定分析不出来。
3.7.1实际使用方式 官网:hutool
此网站提供了各种工具类
如何使用?
首先在pom.xml中导入下面代码,复制即可:
复制进去,然后刷新Maven
3.7.2 生成验证码
进入后点击概述:
进去之后可以看到具体的实现,比如:
3.7.3 具体实现
在IDEA中创建对应的Servlet:CaptchaServlet,核心就是下面四行代码,记住,就会生成验证码了。
具体的三个步骤:
(1)生成验证码对象
(2)获取验证码中的字符并保存在Session中
(3)将验证码图片响应给页面
如果执行完第一个步骤之后,复制代码//定义图形验证码的长和宽 LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
进去之后出现了IDEA爆红问题
,但是本身的pom.xml
文件写的没有问题可以采用下面的解决方案:
CaptchaServlet
代码 :
package com.stedu.servlet;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "captcha", value = "/captcha")
public class CaptchaServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//(1)生成验证码对象--复制官网里面提供的代码即可
//定义图形验证码的长和宽
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(127,38,4,10);
//(2)获取验证码中的字符并保存在Session中
//获取Session:
HttpSession session = request.getSession();
//保存在Session中:
session.setAttribute("captcha",lineCaptcha.getCode());//输出code
//(3)将验证码图片响应给页面
lineCaptcha.write(response.getOutputStream());//字节流
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
验证码一般用于登录页面,将之前的登录案例作修改优化,增加验证码功能:
Login.jsp
部分代码:
<%--
Created by IntelliJ IDEA.
User: Lenovo
Date: 2025/5/15
Time: 19:27
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<%
String msg = (String)request.getAttribute("msg");
if(msg != null) {
%>
<p style="color: red;"><%=msg %></p>
<%
}
%>
<form action="/02_jsp_cookie_session/login" method="post">
<%--等价于:<form action="<%=request.getContextPath() %>/lojin" method="post">--%>
<fieldset style="width: 300px;">
<legend>用户登录</legend>
<p>
<label>账号</label>
<input type="text" name="username" placeholder="请输入用户名" />
</p>
<p>
<label>密码</label>
<input type="password" name="password" placeholder="请输入密码" />
</p>
<p>
<label>验证码</label>
<input type="text" name="captcha" placeholder="请输入验证码" />
<img src="<%=request.getContextPath()%>/captcha" onclick="this.src=this.src+'?d='+Math.random()"/>
</p>
<p>
<button type="submit">登录</button>
<button type="reset">重置</button>
</p>
</fieldset>
</form>
</body>
</html>
做完上面的实现了出现验证码,并实现了点击时自动刷新的效果。
但是真正的项目中我们会把这个验证码提交到后台并进行校验。
所以我们在之前登录案例的基础上修改LoginServlet
一定先验证验证码(先验证到底是人还是机器)再验证用户名密码
修改LoginServlet
如下:
package com.stedu.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
@WebServlet(name = "login", value = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取用户名密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//获取验证码
String captchaInput = request.getParameter("captcha");
//获取Session
HttpSession session = request.getSession();
//获取用户输入的验证码的字符串:
String captcha = (String)session.getAttribute("captcha");
//验证验证码是否正确---忽略大小写的验证
if(!captcha.equalsIgnoreCase(captchaInput)){
//验证码不正确,提示信息:
request.setAttribute("errMsg","验证码错误,请重新登录");
//登录失败重新回到登录页面:
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
//判断用户名和密码是否正确
if(username.equals("admin") && password.equals("admin")) {
//登录成功:
session.setAttribute("user","admin");
// //设置Session超时时间为1s
// session.setMaxInactiveInterval(1);
// //延时2000ms,模拟Session超时
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// //设置Session失效
// //session.invalidate();
//登录成功,跳转到成功页面:
request.getRequestDispatcher("/success.jsp").forward(request, response);
} else {
//登录失败
//提示信息:
request.setAttribute("errMsg","用户名或密码错误,请重新输入");
//登录失败重新回到登录页面:
request.getRequestDispatcher("/login.jsp").forward(request, response);
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}