web会话技术 Cookie与Session

目录

Web会话技术

Java Web开发中使用的会话技术

Cookie技术

什么是Cookie

cookie的应用场景

Cookie的基本使用

服务器向浏览器发送Cookie

获取浏览器携带的Cookie

Cookie中使用中文问题

Cookie的携带路径

Cookie默认的携带情况

让指定的Cookie, 可以在WEB应⽤下的任意资源都携带

Cookie的生存时间

删除已存在的Cookie

案例 记录上⼀次的访问时间

Session技术

什么是Session

session与cookie的区别

session的应用场景

Session的基本使用

Session域对象

持久化Session对象

session生命周期

案例 验证码


Web会话技术

web会话可简单理解为:⽤户开⼀个浏览器,访问某⼀个web⽹站,在这个⽹站点击多个超链接,访问 服务器多个web资源,然后关闭浏览器,整个过程称之为⼀个会话。

1. 打开浏览器
2. 访问京东, 此时 与京东⽹站 产⽣了会话
3. 访问京东的具体商品⻚⾯; 或 其他⻚⾯; 或访问了其他⽹站, 此时,⼀直会与京东⽹站保持着会话连接
4. 关闭浏览器, 此时 与京东⽹站的会话结束;
重写打开浏览器,再次访问京东, 这就是第⼆次会话了

Java Web开发中使用的会话技术

在客户端与服务器端交互的过程中,通常会产⽣⼀些数据, 为了保存会话过程中产⽣的数据,在Servlet 技术中,提供了两个⽤于保存会话数据的对象,分别是Cookie和Session。

通过京东购物⻋案例, 了解会话技术 Cookie对象 \ Session对象

  • Cookie对象: 客户端浏览器的会话技术,它可以把服务器传递过来的⼀些数据记录在客户端浏览器中,解决会话从什么时候开始,到什么时候结束。
  • Session对象: 服务器端的会话技术, 它可以把同⼀⽤户与服务器多次请求响应的⼀些数据记录在服务器Session域中, 实现该⽤户在本次会话中, 可随时获取Session域中的数据, 满⾜多次请求响应之 间 进⾏数据传递\访问使⽤.

 

Cookie技术

什么是Cookie

Cookie对象: 客户端浏览器的会话技术,它可以把服务器传递过来的⼀些数据记录在客户端浏览器中, 解决会话从什么时候开始,到什么时候结束。

⼩结:

  • 在客户端保存的数据, 数据产⽣是在服务器
  • 在浏览器中Cookie是以⽂本的形式保存数据

cookie的应用场景

1. 判断⽤户是否登陆过⽹站,以便下次登录时能够实现⾃动登录(或者记住密码)。如果我们删除 cookie,则每次登录必须从新填写登录的相关信息。

2. 保存上次登录的时间等信息。

3. 保存上次查看的⻚⾯

4. 浏览计数。

Cookie的基本使用

服务器向浏览器发送Cookie

把服务器端想要保存在客户端的数据, 通过Cookie来完成; 保存在客户端的数据 都是较⼩的⽂本数据.

实现步骤:

  • 创建Cookie对象,直接new Cookie(String key,String value)
  • 将Cookie数据保存到客户端, 使⽤response对象⽅法 addCookie()

API:

  • Cookie
//构造⽅法:
Cookie(String key, String value) , ⽤于创建Cookie对象, 并指定Cookie中保存的键值对信息
  • Response对象
//⽅法:
addCookie( Cookie c ), ⽤于将指定的Cookie对象 响应回 客户端浏览器

 

代码演示:

@WebServlet(urlPatterns = "/send")
public class SendCookieServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletRespons response) throws ServletException, IOException {
         //创建Cookie对象
         Cookie cookie = new Cookie("code","java");
         //使⽤response对象的addCookie⽅法, 将Cookie对象 响应回 客户端浏览器
         response.addCookie(cookie);
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          doGet(request, response);
     }
}

获取浏览器携带的Cookie

浏览器在访问服务器的时候, 会携带保存的Cookie数据, 服务器端可使⽤request对象获取Cookie数据; Cookie数据放在请求头

实现步骤:

  • 使⽤Request对象 getCookies()⽅法, 获取浏览器携带的所有Cookie数据
  • 遍历拿到每⼀个Cookie对象, 获取Cookie的键, 获取Cookie的值

API:

  • request
 Cookie[] getCookies() 获取多个Cookie,返回的是Cookie对象数组
  • Cookie对象方法
String getName()获取Cookie的键
String getValue()获取Cookie中的值

代码演示:

@WebServlet(urlPatterns = "/get")
public class GetCookieServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //使⽤Request对象 getCookies()⽅法, 获取浏览器携带的所有Cookie数据
         Cookie[] cookies = request.getCookies();
         //遍历拿到每⼀个Cookie对象, 获取Cookie的键, 获取Cookie的值
         for (Cookie cookie : cookies) {
             String key = cookie.getName();
             String value = cookie.getValue();
             System.out.println(key +" = " + value);
         }
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

Cookie中使用中文问题

Cookie数据,值可以使⽤中⽂, 但建议不要使⽤中⽂

  • 若在Cookie使⽤中⽂, Tomcat低版本不⽀持, 从Tomcat8开始⽀持中⽂
  • 若使⽤中⽂, 需要把中⽂进⾏utf-8编码

API:

  • URLEncoder类
String encode("需要编码的数据","采⽤的编码表") 采⽤指定编码表对数据进⾏编码,返回编码后的字符串
  • URLDecoder类
String decode("需要解码的数据","采⽤的编码表") 采⽤指定编码表对数据进⾏解码,返回解码后的字符串

代码演示:

@WebServlet(urlPatterns = "/china")
public class ChinaCookieServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse res0ponse) throws ServletException, IOException {
         //定义中⽂字符串
         String code = "代码";
         //使⽤URLEncoder的encode⽅法进⾏编码
         String encode = URLEncoder.encode(code,"utf-8");
         System.out.println("encode = " + encode);
         //将编码后的字符串, 通过Cookie,响应回浏览器
         Cookie cookie = new Cookie("code", encode);
         response.addCookie(cookie);
         //访问服务器, 获取Cookie, 使⽤URLDecoder的decode⽅法对已经编码的字符串进⾏解码
         Cookie[] cookies = request.getCookies();
         for (Cookie cookie2 : cookies) {
             if ("code".equals(cookie2.getName())) {
                 //对已经编码的字符串进⾏解码
                 String decode = URLDecoder.decode(encode,"utf-8");
                 System.out.println(cookie2.getName() +" == "+ decode);
             }
         }
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

Cookie的携带路径

问: Cookie数据放在请求头, 浏览器访问服务器,每次都会携带所有的Cookie进⾏访问吗

结论: 浏览器访问服务器,不会携带所有的Cookie进⾏访问

Cookie默认的携带情况

浏览器对Cookie的默认设置

情况分析: Cookie在访问路径 web05/abc/path 下创建

  • 浏览器访问 web05/abc 下的任意资源, 会携带该Cookie; 例如访问 web05/abc/test.jsp
  • 浏览器访问 不是 web05/abc 下的任意资源, 不会携带该Cookie; 例如访问 web05/index.jsp

代码演示:

  • 拷⻉index.jsp⽂件到 web\abc\⽬录下, 改名为test.jsp
  • 编写servlet代码
  • 依次访问:
    • web04/abc/path , 实现创建Cookie, 响应回浏览器
  • web04/abc/test.jsp, 查看是否获取到了 指定的Cookie对象. 结果是: 携带了
  • web04/index.jsp, 查看是否获取到了 指定的Cookie对象 . 结果是: 没有携带
@WebServlet(urlPatterns = "/abc/path")
public class PathCookieServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         Cookie cookie = new Cookie("test_cookie", "wensong");
         response.addCookie(cookie);
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

让指定的Cookie, 可以在WEB应⽤下的任意资源都携带

  • Cookie对象
//⽅法:
setPath("cookie的携带路径") ⽤于设置cookie携带路径, 若参数写成request.getContextPath() 代表web应⽤下任意资源都携带本Cookie

代码演示:

  • 编写servlet代码
  • 依次访问:
    • /abc/path2 , 实现创建Cookie, 响应回浏览器
    • /abc/test.jsp, 查看是否获取到了 指定的Cookie对象. 结果是: 携带了
    • /index.jsp, 查看是否获取到了 指定的Cookie对象 . 结果是: 携带了
@WebServlet(urlPatterns = "/abc/path2")
public class PathCookie2Servlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         Cookie cookie = new Cookie("test_cookie","wensong");
         //设置Cookie的携带路径, 全web应⽤路径下携带
         cookie.setPath(request.getContextPath());
         response.addCookie(cookie);
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

Cookie的生存时间

浏览器中Cookie是有⽣存时间的, 默认是当前会话.浏览器关闭,该会话结束. 可以通过更改Cookie的⽣存时间, 来延⻓Cookie的⽣存时间

  • Cookie对象
//⽅法:
setMaxAge(int 秒) 更改Cookie的⽣存时间, 参数单位: 秒

代码演示:

@WebServlet(urlPatterns = "/life")
public class LifeCookieServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletRespons 
response) throws ServletException, IOException {
         Cookie cookie = new Cookie("code","java");
         cookie.setPath( request.getContextPath() );
         //设置Cookie的⽣存时间, 10分钟
         cookie.setMaxAge(60 * 10);
         response.addCookie(cookie);
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

删除已存在的Cookie

要删除已经存在的cookie,后⼀个⽤来覆盖的新cookie, 必须名称与路径与原来的cookie⼀致

  • 覆盖原有Cookie的需要满⾜的要求:
    • 保证同名键
    • 保证相同的携带路径
    • setMaxAge(0)

代码演示:

@WebServlet(urlPatterns = "/clear")
public class clearCookieServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //获取已有的Cookie
         Cookie[] cookies = request.getCookies();
        //将键为"code"的 cookie 进⾏覆盖, 实现cookie的删除
         for (Cookie cookie : cookies) {
             if ("code".equals(cookie.getName())){
                 //保证同名键
                 Cookie newCookie = new Cookie("code",cookie.getValue());
                 //保证相同的携带路径
                 newCookie.setPath( cookie.getPath() );
                 //setMaxAge(0),设置存活时间为0s 就完成了删除操作
                 cookie.setMaxAge(0);
                 response.addCookie(newCookie);
             }
         }
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

案例 记录上⼀次的访问时间

需求: 展示⽤户上⼀次访问服务器的时间

分析:

实现步骤:

  • 设置浏览器响应编码
  • 获取客户端携带的Cookie
  • 判断key为time的cookie是否存在
  • 存在
    • 获取value值,响应回浏览器显示
    • 覆盖Cookie, 调⽤createCooke⽅法
  • 不存在
    • 响应回浏览器 "欢迎您⾸次访问" 
    • 创建Cookie, 调⽤createCooke⽅法

⽅法 : createCooke

1. 获取当前时间

2. 创建Cookie, 记录本次访问时间

代码演示:

@WebServlet("/time")
public class TimeCookieServlet extends HttpServlet {
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //设置响应字符编码
         response.setContentType("text/html;charset=utf-8");
         //获取所有的Cookie
         Cookie[] cookies = request.getCookies();
         //判断key为time的cookie是否存在
         for (Cookie cookie : cookies) {
             if ("time".equals( cookie.getName())) {
                 //存在, 获取value值,响应回浏览器显示
                 String value = cookie.getValue();
                 response.getWriter().print("您上次访问时间为:"+value);
                 //创建Cookie
                 createCooke(request, response);
                 return;
             }
         }
         //不存在, 响应回浏览器 "欢迎您⾸次访问"
         response.getWriter().print("欢迎您⾸次访问");
         //创建Cookie
         createCooke(request, response);
     }
     private void createCooke(HttpServletRequest request, HttpServletResponse response) {
         //获取当前时间
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MMdd_HH:mm:ss");
         String currentTime = sdf.format(new Date());
         //创建Cookie, 记录本次访问时间
         Cookie time = new Cookie("time", currentTime);
         time.setPath( request.getContextPath());
         time.setMaxAge(60*10);
         response.addCookie(time);
     }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

Session技术

什么是Session

Session对象: 服务器端的会话技术, 它可以把同⼀⽤户与服务器多次请求响应的⼀些数据记录在服务器 Session域中, 实现该⽤户在本次会话中, 可随时获取Session域中的数据, 满⾜多次请求响应之间 进⾏数 据传递\访问使⽤.

  • 思考, 下⾯的购物⻋案例中, 使⽤ServletContext域或Request域存储购物⻋商品信息是否适合?

  • Session与Cookie是紧密相关的。 Session的使⽤要求⽤户浏览器必须⽀持Cookie,如果浏览器不⽀持使⽤Cookie,或者设置为禁⽤Cookie,那么将不能使⽤Session。
  • Session信息对客户来说,不同的⽤户, 使⽤不同的Session信息来记录。当⽤户启⽤Session时, Tomcat引擎⾃动产⽣⼀个SessionID. 在新会话开始时,服务器将SessionID当做cookie存储在⽤户的浏览器中。

session与cookie的区别

 cookiesession
会话数据保存的位置浏览器服务器
数据的安全性不安全安全
存储数是否有限制

session的应用场景

Session⽤于保存每个⽤户的专⽤信息,变量的值保存在服务器端,通过SessionID来区分不同的客户

常⻅应⽤场景:

  1. 保存⽤户登录信息

  2. 将某些数据放⼊session中,供同⼀⽤户的不同⻚⾯使⽤

  3. 登录验证信息

Session的基本使用

Session域对象

session对象是HttpSession接⼝的实现类对象, session对象由tomcat引擎创建. 实现将某些数据放⼊session中,供同⼀⽤户的不同⻚⾯使⽤

  • 作⽤域范围 : ⼀次会话有效(浏览器不关闭)

实现步骤:

  • 使⽤Request的getSession() 当session存在时返回该session,否则新建⼀个session并返回该对象
  • 通过session对象的setAttribute\getAttribute 进⾏数据的存取

API:

  • 域对象存储数据: setAttribute(String key,String value)
  • 取出域对象数据: Object getAttribute(String key)
  • 移除域对象数据: removeAttribute(String key)

代码演示

@WebServlet(urlPatterns = "/session1")
public class Session1Servlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //获取session对象
         HttpSession session = request.getSession();
         //存储数据到session域
         session.setAttribute("code","java");
         //从session域中取出数据
         Object value = session.getAttribute("peige");
         System.out.println("Session1Servlet value = " + value);
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

session2Servlet

@WebServlet(urlPatterns = "/session2")
public class Session2Servlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //获取session对象
         HttpSession session = request.getSession();
         //获取session域中的数据
         Object value = session.getAttribute("code");
         System.out.println("Session2Servlet value == " + value);
     }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

持久化Session对象

发现关闭浏览器再次打开访问时,session域中原有数据不存在了. 现在想要session实现关闭浏览器继续 可以访问数据. 每个session对象都有个唯⼀标识 JSESSIONID, 服务通过Cookie对象, 将JSESSIONID存储在客户端 Cookie中, 就可以实现持久化Session对象.

实现步骤:

  • 获取JSESSIONID, 通过session对象中的getID()⽅法
  • 创建Cookie对象, 将JSESSIONID 存⼊Cookie
  • 使⽤response对象, 将cookie 响应回浏览器

API:

  • session对象
String getID() 获取session对象的唯⼀编码,返回String

代码演示:

@WebServlet("/save")
public class SaveSessionServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         HttpSession session = request.getSession();
         session.setAttribute("course","javaee");
         String sessionId = session.getId();
         System.out.println("sessionId = " + sessionId);
         //创建Cookie
         Cookie cookie = new Cookie("JSESSIONID", sessionId);
         cookie.setPath( request.getContextPath());
         cookie.setMaxAge(60*10);
         response.addCookie(cookie);
     }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

@WebServlet("/save2")
public class Save2SessionServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         HttpSession session = request.getSession();
         String sessionId = session.getId();
         System.out.println("sessionId = " + sessionId);
         Object course = session.getAttribute("course");
         System.out.println("course = " + course);
     }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

session生命周期

  • session创建时机   
  1. 这个浏览器在servlet中第⼀次使⽤session时候,通过getSession⽅法创建;   
  2. 这个浏览器第⼀次访问jsp的时候,服务器也会为这个浏览器创建⼀个session对象;
  • session销毁时机   
  1. 程序员调⽤invalidate⽅法;(⽴刻销毁)   
  2. 设置的存活时间到了;(默认是30分钟)   
  3. 服务器⾮正常关闭;(突然断电)
  • 注意事项:   
  1. 正常关闭服务器,session不会销毁,⽽是直接序列化到硬盘上,下⼀次服务器启动的时候,会重新创建出来;   
  2. 如果浏览器单⽅⾯关闭会话,服务器上对应的session不会死亡 ,但是会导致服务器给浏览器创建的JSESSIONID的cookie死亡,当cookie死亡后,会导致浏览器⽆法找到上⼀个session对象,会造成服务器中session死亡的假象;
  • 可扩展: 利⽤Debug进⾏源码剖析, 查看获取Session对象的过程. 下⾯代码已包含获取Seesion主要代码
@WebServlet(urlPatterns = "/code")
public class getSessionObjectForCode extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取session对象
         HttpSession session = request.getSession();
     }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}
//servlet中编写, HttpSession session = request.getSession()时, 调⽤Request类getSession()⽅法
//Request类getSession()⽅法,在内部调⽤ doGetSession(true) ⽅法
class Request {
     //此请求的当前活动会话
     protected Session session = null;

     public HttpSession getSession() {
         Session session = doGetSession(true);
         if (session == null) {
             return null;
         }
         //返回接⼝实现类对象
         return session.getSession();
     }
     protected Session doGetSession(boolean create) { //create为true
         // 如果没有ServletContext对象,则不能有会话, 返回null
         Context context = getContext();
         if (context == null) {
             return (null);
         }
         // 如果当前会话存在且有效,则返回该会话. 有效判断主要为session存活时间
         if ((session != null) && !session.isValid()) {
             session = null;
         }
         if (session != null) {
             return (session);
         }
         /*
         若执⾏到当前⾏代码, 说明当前会话不存在或存活⽆效, 这时,获取浏览器请求服务器时所携带的 Cookie对象, 查看是否有JSESSIONID, 若有此ID, 通过该ID 查找到服务器端Session对象.
 若查到的Session对象存在且有效,返回该Session对象
 */
         // 如果请求的会话存在且有效,则返回该会话
         Manager manager = context.getManager();
         if (manager == null) {
             return (null);
         }
         if (requestedSessionId != null) {
             try {
                 session = manager.findSession(requestedSessionId);
             } catch (IOException e) {
                 session = null;
             }
             if ((session != null) && !session.isValid()) {//有效判断主要为session存活时间
                 session = null;
             }
             if (session != null) {
                 session.access();
                 return (session);
             }
         }
         /*
         若执⾏到这,说明浏览器请求服务器时所携带的 Cookie对象 也没有能有的Session对象, 服务器端开始创建新Session
         */
         // 如果请求并且未提交响应,则创建新会话
         sessionId = null;
         if (!create) {
             return (null);
         }

         //创建新Session对象, 内部完成sessionID的⽣成, 创建时间的指定,存活时间的指定
         session = manager.createSession(sessionId);
         //基于新Session会话创建新会话cookie
         if (session != null
             && context.getServletContext()
             .getEffectiveSessionTrackingModes()
             .contains(SessionTrackingMode.COOKIE)) {
             Cookie cookie =
             ApplicationSessionCookieConfig.createSessionCookie(
             context, session.getIdInternal(), isSecure());
             //创建Cookie, 存⼊内容 Cookie的携带路径 \sessionid\ 创建时间\ 存活时间
             //通过response对象 响应给浏览器
             response.addSessionCookieInternal(cookie);
         }
         if (session == null) {
             return null;
         }
         return session;
     }
}

案例 验证码

需求 使⽤session存储验证码, 完成验证码的校验

分析

1. 在登录⻚⾯⽤户登录的时候要查看到验证码,如图所示:

2. 在⽣成⻚⾯验证码图⽚的同时,需要使⽤session存储验证码

3. 在处理⽤户登录请求的时候,对验证码进⾏校验

4. 校验通过才能执⾏登录操作

步骤

⽤户请求中的验证码获取
获取session中保存的验证码
与session中保存的验证码进⾏校验
     验证码错误,告诉⽤户,⻚⾯提示
     验证码正确,登录逻辑执⾏,打印提示

代码实现

1. login.jsp⻚⾯

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
     <meta http-equiv="Content-Type" content="text/html; charset=utf8">
     <title>login</title>
     <script type="text/javascript">
         function changeCode(){
             document.getElementById("img").src = "/check?t="+new Date().getTime();
         }
     </script>
</head>
<body>
<form action="/login" method="post">
     <table>
         <tr><td>⽤户名:</td><td><input type="text" name="username">
</td></tr>
         <tr><td>密码:</td><td><input type="password" name="password">
</td></tr>
         <tr><td>验证码:</td><td><input type="text" name="code"></td>
</tr>
         <!-- 通过向服务器发送请求,从服务器获取验证码数据 -->
         <tr><td></td><td><img id="img" src="/check"
onclick="changeCode();"/><a href="#" onclick="changeCode();">换⼀换</a>
<span><%=
request.getAttribute("msg")==null?"":request.getAttribute("msg") %>
</span></td></tr>
         <tr><td></td><td><input type="submit" value="登陆"></td></tr>
     </table>
</form>
</body>
</html>

2. 配置验证码servlet

@WebServlet(urlPatterns = "/check")
public class CheckcodeServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         // 创建画布
         int width = 120;
         int height = 40;
         BufferedImage bufferedImage = new BufferedImage(width, height,
         BufferedImage.TYPE_INT_RGB);
         // 获得画笔
         Graphics g = bufferedImage.getGraphics();
         // 填充背景颜⾊
         g.setColor(Color.white);
         g.fillRect(0, 0, width, height);
         // 绘制边框
         g.setColor(Color.red);
         g.drawRect(0, 0, width - 1, height - 1);
         // ⽣成随机字符
         // 准备数据
         String data ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
         // 准备随机对象
         Random r = new Random();
         // 声明⼀个变量 保存验证码
         String code = "";
         // 书写4个随机字符
         for (int i = 0; i < 4; i++) {
             // 设置字体
             g.setFont(new Font("宋体", Font.BOLD, 28));
             // 设置随机颜⾊
             g.setColor(new Color(r.nextInt(255), r.nextInt(255),
             r.nextInt(255)));
             String str = data.charAt(r.nextInt(data.length())) + "";
             g.drawString(str, 10 + i * 28, 30);
             // 将新的字符 保存到验证码中
             code = code + str;
         }
         // 绘制⼲扰线
         for (int i = 0; i < 6; i++) {
             // 设置随机颜⾊
             g.setColor(new Color(r.nextInt(255), r.nextInt(255),r.nextInt(255)));
             g.drawLine(r.nextInt(width), r.nextInt(height),
             r.nextInt(width), r.nextInt(height));
         }
         // 将验证码 打印到控制台
         System.out.println(code);
         // 将验证码放到session中
         request.getSession().setAttribute("code_session", code);
         // 将画布显示在浏览器中
         ImageIO.write(bufferedImage, "jpg",
         response.getOutputStream());
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

3. 登录servlet

@WebServlet(urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         //⽤户请求中的验证码获取
         String code = request.getParameter("code");
         //获取session中保存的验证码
         String code_session =(String)request.getSession().getAttribute("code_session");
         //与session中保存的验证码进⾏校验
         if(!code_session.equalsIgnoreCase(code)){
             //验证码错误,告诉⽤户,⻚⾯提示
             request.setAttribute("msg","验证码错误");
             request.getRequestDispatcher("/login.jsp").forward(request,response);
             return;
         }
         //验证码正确,登录逻辑执⾏

     }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doGet(request, response);
     }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值