03_JSP入门_Cookie_Session

一、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存放在tomcatwork目录下,它是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%>&lt;%&ndash;在浏览器上面打印str,相当于out.println&ndash;%&gt;--%>
<%--  <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

一个服务器最多在客户端浏览器上保存20Cookie

一个浏览器最多保存300Cookie

上面的数据只是HTTPCookie规范,但在浏览器大战的今天,一些浏览器为了打败对手,为了展现自己的能力起见,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500Cookie等!但也不会出现把你硬盘占满的可能!

注意,不同浏览器之间是不共享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不只有namevalueCookie还是生命。所谓生命就是Cookie在客户端(浏览器)的有效时间,可以通过setMaxAge(int)来设置Cookie的有效时间。

  • cookie.setMaxAge(-1)CookiemaxAge属性的默认值就是-1,表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么Cookie就会消失。不会长期保存。
  • cookie.setMaxAge(60*60):表示Cookie对象可存活1小时。当生命大于0时,浏览器会把Cookie保存到硬盘上,就算关闭浏览器,就算重启客户端电脑,Cookie也会存活1小时;
  • cookie.setMaxAge(0)Cookie生命等于0是一个特殊的值,它表示Cookie被作废!也就是说,如果原来浏览器已经保存了这个Cookie,那么可以通过CookiesetMaxAge(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对象:SessionJSP内置对象之一,不用创建就可以直接使用。

3.3、HttpSession域对象功能

一个会话创建一个HttpSession对象,同一会话中的多个请求中可以共享Session中的数据

目前为止已经学习了三个域对象,分别是requestsessionservletContext,他们都有共同的方法:

  • 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
  1. 当用户第一次使用session时(表示第一次请求服务器),服务器会创建session,并创建一个Cookie,在Cookie中保存了sessionid,发送给客户端(浏览器)。这样客户端(浏览器)就有了自己sessionid了。但这个Cookie只在浏览器内存中存在,也就是说,在关闭浏览器窗口后,Cookie就会丢失,也就丢失了sessionId
  2. 当用户第二次访问服务器时,会在请求中把保存了sessionIdCookie发送给服务器,服务器通过sessionId查找session对象,然后再使用。也就是说,只要浏览器容器不关闭,无论访问服务器多少次,使用的都是同一个session对象。这样也就可以让多个请求共享同一个session了;
  3. 当用户关闭了浏览器窗口后,再打开浏览器访问服务器,这时请求中没有了sessionId,那么服务器会创建一个session,再把sessionId通过Cookie保存到浏览器中,也是一个新的会话开始了。原来的session会因为长时间无法访问而失效;
  4. 当用户打开某个服务器页面长时间没动作时,这样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,并在响应中给客户端新sessionsessionId;(比如退出–设置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);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

.又是新的一天.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值