谁总结的JavaWeb会话技术了?太全面了...

作者:涛GuoGuo的跟屁虫丶博Ke 

https://www.cnblogs.com/doondo/p/13997465.html

文末有大彩蛋!

会话概念

  • 一次会话中包含多次请求和响应。

    一次会话:浏览器第一次给服务器资源发送请求,会话建立,直到有一方断开为止,一次会话结束。

会话的功能

  • 在一次会话的范围内的多次请求间,共享数据。

会话实现的方式

  • 客户端会话技术:Cookie

  • 服务端会话技术:Session

Cookie

  • 概念:客户端会话技术,将数据保存到客户端

使用步骤

  1. 创建Cookie对象,绑定数据

 new Cookie(String name, String value);
  1. 服务端发送Cookie到客户端

  response.addCookie(Cookie cookie);
  1. 客户端访问新资源,携带Cookie数据

   Cookie[] cookies = request.getCookie();

项目实战

  1. 写Cookie数据到客户端的Servlet

   package org.taoguoguo.cookie;
   
   import javax.servlet.ServletException;
   import javax.servlet.annotation.WebServlet;
   import javax.servlet.http.Cookie;
   import javax.servlet.http.HttpServlet;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
   import java.io.IOException;
   
   /**
    * @author taoguoguo
    * @description Cookie快速入门-写Cookie数据到客户端的Servlet
    * @website https://www.cnblogs.com/doondo
    * @create 2020-11-17 21:44
    */
   @WebServlet("/CookieDemo1")
   public class CookieDemo1 extends HttpServlet {
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           //1.创建Cookie对象
           Cookie c = new Cookie("msg","hello");
           //2.发送Cookie
           response.addCookie(c);
       }
  
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           this.doPost(request, response);
       }
   }
  1. 获取客户端Cookie数据的Servlet

  package org.taoguoguo.cookie;
   
   import javax.servlet.ServletException;
   import javax.servlet.annotation.WebServlet;
   import javax.servlet.http.Cookie;
   import javax.servlet.http.HttpServlet;
   import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
   import java.io.IOException;
   
   /**
    * @author taoguoguo
    * @description cookie快速入门-获取客户端Cookie数据
    * @website https://www.cnblogs.com/doondo
    * @create 2020-11-17 21:46
    */
   @WebServlet("/CookieDemo2")
   public class CookieDemo2 extends HttpServlet {
       protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           //3.获取Cookie
           Cookie[] cookies = request.getCookies();
           //获取数据,遍历Cookie
           if(cookies!=null){
               for(Cookie cookie:cookies){
                   System.out.println(cookie.getName() + "->" + cookie.getValue());
               }
           }
   
       }
   
       protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
           this.doPost(request, response);
       }
   }
  1. 输出结果:

  msg->hello

Cookie实现原理

基于响应头 set-cookie和请求头cookie实现

客户端请求访问服务器,服务器将需要存储到cookie里面的内容,通过键值对形式写到set-cookie头中,然后将数据响应给客户端;

客户端再次发送请求时,会将存储在客户端的Cookie数据,放在请求头cookie中,提交给服务端,服务器可获取请求头中Cookie的数据,进行数据,从而做到交互。

Cookie的细节

  1. 一次是否可以发送多个Cookie?

  • 可以,服务端可以创建多个Cookie对象,使用response调用多次addCookie方法发送Cookie即可。

  • Cookie在浏览器中的有效时间?

    • 默认情况下,当浏览器关闭,Cookie数据被销毁

    • 持久化存储

       /*int 取值分类
        正数:将Cookie数据写到硬盘文件中,持久化存储,Cookie 存活时间(单位为:秒)
        负数:默认值
        零:删除Cookie信息
       */
       setMaxAge(int seconds)
    
      package org.taoguoguo.cookie;
       
       import javax.servlet.ServletException;
       import javax.servlet.annotation.WebServlet;
       import javax.servlet.http.Cookie;
       import javax.servlet.http.HttpServlet;
       import javax.servlet.http.HttpServletRequest;
       import javax.servlet.http.HttpServletResponse;
       import java.io.IOException;
       
       /**
        * @author taoguoguo
        * @description Cookie存活时间举例
        * @website https://www.cnblogs.com/doondo
        * @create 2020-11-17 21:46
        */
       @WebServlet("/CookieDemo3")
       public class CookieDemo3 extends HttpServlet {
           protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               //1.创建Cookie对象
               Cookie cookie = new Cookie("msg","setMaxAge");
               //2.设置Cookie的存活时间
               cookie.setMaxAge(30);   //将Cookie持久化硬盘,30后会自动删除Cookie文件
               //3.发送Cookie
               response.addCookie(cookie);
           }
       
           protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               this.doPost(request, response);
           }
       }
       
    
    1. Cookie是否可以存储中文

    • Tomcat 8 之前,Cookie中不能直接存储中文数据

      解决方案:将中文转码,一般采用URL编码

    //存中文到Cookie编码
         Cookie cookie = new Cookie("uname", URLEncoder.encode(uname,"utf-8"));
         //获取Cookie解码
         String value = URLDecoder.decode(cookie.getValue(),"utf-8");
    
    • Tomcat 8 之后,Cookie支持中文数据,但不支持特殊字符,依然可以通过URL编码解决

    1. Cookie的获取范围多大?

    • 假设在一个Tomcat服务器中,部署了多个web项目,那么这些web项目的Cookie能否共享?

    • 默认情况下,Cookie不能共享

           //设置cookie的取值范围 默认情况下,设置为当前的虚拟目录也就是 request.getContext的值
           //如果需要共享,需要将path 设置为父级别目录 
           //比如 /project1; /project2 两个项目需要共享,则 setPath("/") 
           c.setPath(String path) 
    
    • 不同的Tomcat服务器间Cookie共享问题?

    • 设置一级域名相同,那么多个服务器之间的Cookie可以共享

           /**
            比如,贴吧的域名为:tieba.baidu.com  而新闻的域名为 news.baidu.com
            其中 baidu.com 为一级域名 tieba、news 等为二级域名
            c.setDomain(".baidu.com") 那么tieba.baidu.com 和 news.baidu.com中的Cookie可以共享
           */
           c.setDomain(String path);
    

    Cookie的特点和作用

    1. Cookie存储数据在客户端浏览器

    2. 浏览器对于单个Cookie的大小限制,以及对同一个域名下的总Cookie数量也有限制(20个)

    作用:

    1. cookie一般用于存储少量的不太敏感的数据

    2. 在不登陆的情况下,服务器对客户端的身份的识别

      比如在百度浏览器未登录情况下做一些偏好设置,服务端发一个Cookie给浏览器,浏览器访问时带上这个Cookie,服务端就可以渲染对应的偏好设置

    Cookie案例

    需求:1。访问一个Servlet,如果第一次访问,则提示:您好,欢迎首次访问;如果不是第一次访问,则提示欢迎回来,您上次访问时间为:显示时间字符串。
    

    分析:

    • 可以采用Cookie来完成

    • 在服务器中的Servlet来判断是否有一个名为 lastTime的Cookie

      有:不是第一次访问

      没有:第一次访问

      • 响应数据,您好,欢迎你首次访问

      • 写回Cookie: lastTime:当前时间

      • 响应数据:欢迎回来,你上次访问的时间为:获取lastTime中Cookie数据

      • 写回Cookie, 更新Cookie时间的值

    案例代码:

    package org.taoguoguo.cookie;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * @author taoguoguo
     * @description Cookie案例
     * @website https://www.cnblogs.com/doondo
     * @create 2020-11-17 21:46
     */
    @WebServlet("/cookieTest")
    public class CookieTest extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //设置响应消息体的数据格式和编码
            response.setContentType("text/html;charset=utf-8");
            //1.获取所有Cookie
            Cookie[] cookies = request.getCookies();
            boolean flag = false;   //默认没有Cookie
            //2.遍历Cookie数组
            if(cookies!=null && cookies.length>0){
                for (Cookie cookie : cookies) {
                    //3.获取cookie的名称
                    String name = cookie.getName();
                    //4.判断名称是否为 lastTime
                    if("lastTime".equals(name)){
                        flag = true;
                        //Cookie存在,不是第一次访问
                        String value = cookie.getValue();
                        value = URLDecoder.decode(value,"utf-8");
                        //获取当前时间的字符串,重新设置Cookie的值,重新发送Cookie
                        String str_date = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());
                        str_date = URLEncoder.encode(str_date, "utf-8");
                        cookie.setValue(str_date);
                        //设置Cookie的存活时间
                        cookie.setMaxAge(60*60);    //一小时
                        response.addCookie(cookie);
                        //cookie
                        response.getWriter().write("<h1>欢迎回来,您上次的访问时间为: "+value+"</h1>");
                    }
                }
            }
    
            if(cookies == null || cookies.length==0 || flag == false){
                //没有 第一次访问
                String str_date = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date());
                //时间输出格式中空格特殊字符处理
                str_date = URLEncoder.encode(str_date, "utf-8");
                Cookie cookie = new Cookie("lastTime",str_date);
                //设置Cookie的存活时间
                cookie.setMaxAge(60*60);    //一小时
                response.addCookie(cookie);
                response.getWriter().write("<h1>您好,欢迎你首次访问</h1>");
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            this.doPost(request, response);
        }
    }
    

    JSP总结

    JSP 概念

    Java Server Page: Java服务端页面,可以理解为一个特殊的页面,既可以定义html标签,又可以定义Java代码,用于简化书写。

    JSP 原理

    JSP 本质就是一个Servlet ,在启动项目访问 JSP 页面时,我们的Tomcat容器空间中,会将JSP 文件 编译为一个 .java 文件 然后Javac编译为一个.class文件 提供访问。我们可以打开 index.jsp 经过编译 后的 index_jsp.java , 发现其继承 自 org.apache.jasper.runtime.HttpJspBase,而 HttpJspBase 继承自 HttpServlet, 所以说 JSP 本质 就是 Servlet

    而这个Servlet 的 service 方法 做的事情 就是将我们的返回数据,通过输出流 拼接html 标签 ,从而实现页面展示效果。

    JSP 脚本

    1. <% Java代码 %>

    • 定义的 Java代码在Jsp 转换成 java后,位于Service方法中,Service 方法中可以怎么写,该脚本语法就可以怎么写。

  • <%! Java代码 %>

    • 定义的 Java代码 在Jsp 转换成 java后,位于类的成员变量中,但这种一般用得比较少。因为servlet是单例的,多个线程同时访问,如果值有修改,其他线程获取时会存在线程安全问题,Servlet中一般推荐定义局部变量。

  • <%= Java代码 %>

    • 定义的Java代码,会输出到页面上。out.print()可以输出什么,该脚本就可以定义什么

    JSP内置对象

    在 JSP 页面不需要获取和创建,可以直接使用的对象

    JSP一共有9个内置对象:

    1. request

    2. response

    3. out:字符输出流对象,可以将数据输出到页面上。和response.getWriter()类似

    • response.getWriter() 和 out.write 的区别:

      tomcat 服务器真正给客户端做出响应之前,会先找 response 缓冲区数据,再找 out 缓冲区数据。response.getWriter() 数据输出永远再 out.write() 之前

    Session

    概念

    服务器端的会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象中,HttpSession

    快速入门

    1. 获取 HttpSession 对象:

    • HttpSession session = request.getSession();

  • 使用 HttpSession 对象:

    • Object getAttribute(String name);

    • void setAttribute(String name, Object value);

    • void removeAttribute(String name);

  • 案例编码

    • SessionDemo1设置Session数据

         package org.taoguoguo.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;
         
         /**
          * @author taoguoguo
          * @description ${NAME}
          * @website https://www.cnblogs.com/doondo
          * @create 2020-11-23 23:00
          */
         @WebServlet("/sessionDemo1")
         public class SessionDemo1 extends HttpServlet {
             protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                 //使用Session共享数据
                 //1.获取Session
                 HttpSession session = request.getSession();
                 //2.存储数据
                 session.setAttribute("msg","hello session");
             }
         
             protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                 this.doPost(request, response);
             }
         }
    
    • SessionDemo2获取Session数据

         package org.taoguoguo.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;
         
         /**
          * @author taoguoguo
          * @description ${NAME}
          * @website https://www.cnblogs.com/doondo
          * @create 2020-11-23 23:00
          */
         @WebServlet("/sessionDemo2")
         public class SessionDemo2 extends HttpServlet {
             protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                 //使用Session获取数据
                 //1.获取Session
                 HttpSession session = request.getSession();
                 //2.存储数据
                 Object msg = session.getAttribute("msg");
                 System.out.println(msg);
         
             }
         
             protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                 this.doPost(request, response);
             }
         }
    

    Session实现原理

    思考SessionDemo1 和 SessionDemo2 是不是同一个Session呢? 答案是肯定的同一个。不然怎么从Session中获取到数据呢?

    Session的实现是依赖于Cookie的,当服务器创建一个Session时,会在内部记录一个SessionId,而服务器响应数据给客户端时,会在响应头中设置Cookie: JseesionId:sessionid值的方式,将创建的SessionId 发放到客户端。而客户端再次请求服务器时,会将客户端的Cookie:JessionId 发送到服务端,服务端根据这个SessionId,就能获取到对应ID的Session对象,拿到会话中的数据。

    Session的细节

    1. 当客户端关闭后,服务器不关闭,两次获取的Session是否为同一个?

    • 默认情况下,不是。因为一次新的会话,从request中获取的Session对象的SessionId是不一样的。

    • 如果需要相同,可以通过创建Cookie,键为 JESSIONID,设置最大存活时间,让Cookie持久化的方法来实现。因为Session是基于Cookie来是实现的,只要Cookie每次携带的JessionId相同,就是同一个Session。

    实例代码:

         package org.taoguoguo.session;
         
         import javax.servlet.ServletException;
         import javax.servlet.annotation.WebServlet;
         import javax.servlet.http.*;
         import java.io.IOException;
         
         /**
          * @author taoguoguo
          * @description ${NAME}
          * @website https://www.cnblogs.com/doondo
          * @create 2020-11-23 23:00
          */
         @WebServlet("/sessionDemo3")
         public class SessionDemo3 extends HttpServlet {
             protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                 //使用Session获取数据
                 //1.获取Session
                 HttpSession session = request.getSession();
                 System.out.println(session);
                 //期望客户端关闭后,session也能相同
                 Cookie cookie = new Cookie("JESSIONID",session.getId());
                 cookie.setMaxAge(60*60);
                 response.addCookie(cookie);
             }
         
             protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
                 this.doPost(request, response);
             }
         }
    
    1. 客户端不关闭,服务器关闭,两次获取的Session是同一个吗?

      不是同一个,因为Session对象是由服务器创建的,服务器关闭,Session对象就内存就清空了。重启后新创建的Session的地址值是随机分配的。

      但现在有个场景,假设用户在基于Session实现的购物车中,添加了N件商品,但准备下单时接到电话。接电话过程中,服务器重启。待电话结束后,点击下单,Session由于不是同一个对象数据丢失了该如何处理?

      服务器Tomcat已经实现了Session的钝化和活化。将项目打成 war 包部署到Tomcat的 webapp 目录下,正常启动Tomcat,访问存储Session的Servlet, 当Tomcat正常关闭时,Tomcat 的 work 目录会产生一个 SESSIONS.ser 的文件,持久化Session的数据,当Tomcat再次启动时,会将SESSION.ser 文件数据加载到Tomcat内存中序列化为Session对象,从而拿到Session存储的数据。

      但IDEA 编辑器只实现的Session的钝化,没有实现Session的活化。IDEA在启动Tomcat时,会先删除 work 目录,然后新建work 目录,获取不到 Session.ser 文件,及其存储的数据。

    • 在服务器启动后,将Session文件转换为内存中的Session对象即可

    • 在服务器正常关闭之前,将Session对象序列化到硬盘上

    • Session的钝化:

    • Session的活化:

  • Session什么时候被销毁?

    • 服务器关闭

    • session 对象调用 invalidate() 方法

    • session的默认失效时间为30分钟

      Tomcat 的 web.xml 选择性配置 设置Session时长:

         <session-config>
          <session-timeout>30</session-timeout>
         </session-config>
    

    Session的特点

    1. Session用于存储一次会话的多次请求的数据,存在服务器端。

    2. Session可以存储任意类型,任意大小的数据。

    Session与Cookie的区别

    1. Session 存储数据在服务端,Cookie在客户端

    2. Session没有数据大小限制,Cookie有大小限制

    3. Session数据存在服务端较为安全,Cookie相对不安全

    Session案例

    访问带有验证码的登录页面,用户输入用户名,密码,及验证码

    • 如果用户名和密码输入有误,则跳转至登录页面,提示:用户名或密码错误

    • 如果验证码错误,跳转登录页面,提示:验证码错误

    • 如果全部输入正确,则跳转至主页 success.jsp 显示:用户名,欢迎您

    案例编码

    1. 验证码Servlet

       package org.taoguoguo.servlet;
       
       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 java.awt.*;
       import java.awt.image.BufferedImage;
       import java.io.IOException;
       import java.util.Random;
       
       /**
        * @author taoguoguo
        * @description ${NAME}
        * @website https://www.cnblogs.com/doondo
        * @create 2020-11-24 23:33
        */
       @WebServlet("/checkCodeServlet")
       public class CheckCodeServlet extends HttpServlet {
           protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               //1.创建一个图像缓冲区对象
               int width = 100;
               int height = 50;
               BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
               //2.美化图片
               //2.1填充背景色
               Graphics graphics = image.getGraphics();    //画笔对象
               graphics.setColor(Color.pink);  //设置画笔颜色
               graphics.fillRect(0,0,width,height);
               //2.2画边框
               graphics.setColor(Color.blue);
               graphics.drawRect(  0,0,width-1,height-1);
               //2.3写验证码
               String code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789";
               //生成随机角标
               Random random = new Random();
               StringBuilder builder = new StringBuilder();
               for (int i=1; i<=4; i++){
                   int index = random.nextInt(code.length());
                   //获取字符
                   char c = code.charAt(index);
                   builder.append(c);
                   graphics.drawString(String.valueOf(c),width/5*i,height/2);
               }
               //将验证码存入到Session
               String checkCode_session = builder.toString();
               request.getSession().setAttribute("checkCode_session",checkCode_session);
       
               //2.4画干扰线
               graphics.setColor(Color.green);
               for(int i=0; i<10; i++){
                   int x1 = random.nextInt(width);
                   int y1 = random.nextInt(height);
       
                   int x2 = random.nextInt(width);
                   int y2 = random.nextInt(height);
                   graphics.drawLine(x1,y1,x2,y2);
               }
               //3.将图片输出到页面展示
               ImageIO.write(image,"jpg",response.getOutputStream());
           }
       
           protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               this.doPost(request, response);
           }
       }
    
    
    1. login.jsp

       <%--
         User: taoGuoGuo
         Date: 2020/11/24
         Time: 23:36
         WebSite: https://www.cnblogs.com/doondo/
       --%>
       <%@ page contentType="text/html;charset=UTF-8" language="java" %>
       <html>
       <head>
           <title>login</title>
       
           <script>
               window.onload = function () {
                   document.getElementById("img").onclick = function () {
                       this.src="/checkCodeServlet?time="+ new Date().getTime();
                   }
               }
           </script>
           <style>
               div{
                   color: red;
               }
           </style>
       
       </head>
       <body>
           <form action="/loginServlet" 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="checkCode"></td>
                   </tr>
                   <tr>
                       <td colspan="2"><img src="/checkCodeServlet" id="img"></td>
                   </tr>
                   <tr>
                       <td colspan="2"><input type="submit" value="登录"></td>
                   </tr>
               </table>
           </form>
           <div><%=request.getAttribute("errorMsg") == null ? "": request.getAttribute("errorMsg")%></div>
       </body>
       </html>
    
    
    1. loginServlet

       package org.taoguoguo.servlet;
       
       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.util.Map;
       
       /**
        * @author taoguoguo
        * @description ${NAME}
        * @website https://www.cnblogs.com/doondo
        * @create 2020-11-24 23:47
        */
       @WebServlet("/loginServlet")
       public class LoginServlet extends HttpServlet {
           protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               //1.设置request编码
               request.setCharacterEncoding("utf-8");
               //2.获取参数
               String username = request.getParameter("username");
               String password = request.getParameter("password");
               String checkCode = request.getParameter("checkCode");
               //3.先获取生成的验证码
               HttpSession session = request.getSession();
               String checkCode_session = session.getAttribute("checkCode_session").toString();
               //删除Session中存储的验证码
               session.removeAttribute("checkCode_session");
               //4.先判断验证码是否正确
               if (checkCode_session != null && checkCode_session.equalsIgnoreCase(checkCode)){
                   //忽略大小写比较
                   //验证码正确
                   //判断用户名和密码是否一致
                   if("zhangsan".equals(username) && "123".equals(password)){//需要查询数据库
                       //登录成功
                       //存储用户信息,重定向到 success.jsp
                       session.setAttribute("user",username);
                       response.sendRedirect(request.getContextPath()+"/success.jsp");
                   }else{
                       //存储信息到request
                       request.setAttribute("errorMsg","用户名或密码错误");
                       request.getRequestDispatcher("/login.jsp").forward(request,response);
                   }
               }else{
                   //验证码不一致
                   //存储信息到request
                   request.setAttribute("errorMsg","验证码错误");
                   request.getRequestDispatcher("/login.jsp").forward(request,response);
               }
           }
       
           protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
               this.doPost(request, response);
           }
       }
    
    1. success.jsp

      <%--
         User: taoGuoGuo
         Date: 2020/11/25
         Time: 0:15
         WebSite: https://www.cnblogs.com/doondo/
       --%>
       <%@ page contentType="text/html;charset=UTF-8" language="java" %>
       <html>
       <head>
           <title>success</title>
       </head>
       <body>
       <h1><%=request.getSession().getAttribute("user")%>,欢迎您</h1>
       </body>
       </html>
    

    最后送书

    最后,新书《分布式一致性算法开发实战》刚刚上架,销量不错,本书分析了分布式一致性Raft算法以及Raft算法所依赖的理论,在此基础上讲解并实现Raft算法以及基于Raft算法的KV服务。(文末送书)

    《分布式一致性算法开发实战》内容简介:本书分析了分布式一致性Raft算法以及Raft算法所依赖的理论,在此基础上讲解并实现Raft算法以及基于Raft算法的KV服务。通过本书,你可以深入了解Raft算法的运行机制,也可以学习到如何正确地实现Raft。

    本书分为11章,第一章介绍分布式一致性算法,第二章详细分析Raft算法,第三章在第二章基础上整体设计,第四章到第八章逐个讲解基于Raft算法的KV服务的各个组件的实现,第九章讲解Raft算法的主要优化之一的日志快照,第十章是生产环境必须的服务器成员变更功能,最后一章介绍其他一些相关的Raft优化。

    本书详细介绍了Raft的核心算法、服务器成员变更以及各种优化的实现,适合想尝试实现Raft算法或者在生产环境中加入Raft算法的读者,以及对于分布式一致性算法有兴趣的读者。


    抽奖规则:(本次活动使用腾讯官方抽奖助手)
    0、抽奖截止时间:2020年12月1日20:00
    1、必须是粉丝哦
    2、中奖后请24小时内请联系号主,如果我有你好友看到是你也会提示你滴
    3、扫以下二维码回复“领书”即可获取抽奖码


    
    

    好文章,我在看
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值