• Java Web之会话保持和JSP


    前言

    出于提升HTTP传输效率考虑,HTTP协议是无状态的。

    HTTP不会记录每次请求的状态,这就造成了同一个会话中的2个请求之间相互独立,彼此之间没有任何联系。

    本文将基于servlet的session机制结合JSP,实现1个用户登录的Web应用,深入理解一下Java Web应用的核心架构。

    一、会话保持技术

    在Web应用中的1次会话中,包含多次HTTP请求和响应。

    会话技术是针对HTTP请求无状态的特性,在一次会话中(多次HTTP请求和响应之间)保存数据 。

    Cookie和Session是2种HTTP请求会话保持技术,其中Session机制基于Cookie机制。

     

    二、Cookie

    Cookie信息保存在客户端(浏览器),信息大小限制在4KB,其机制如下。

    • 客户端请求服务器,服务器通过HTTP响应头中set-Cooke键告诉客户端保存Cookie。
    • 浏览器接收到服务器回写Cookie要求,通过键值对的形式,在本地设置Cookie,键重复就覆盖。
    • 每次浏览器请求服务器之前都会自动携带上浏览器本地的Cookie信息,除非使用Ajax向服务器发送请求。
    • 服务器可以通过客户端携带的Cookie校验当前客户端并保存HTTP请求状态。

    1.添加cookie信息

    //2.创建明文Cookie信息
                Cookie cookie = new Cookie("product1", product);
                //2.1创建加密Cookie信息
                Cookie encodecookie = new Cookie("product2", URLEncoder.encode("爱我中华","utf-8"));
                //3.将Cookie返回给浏览器
                response.addCookie(cookie);
                response.addCookie(encodecookie);

    2.获取cookie信息

            Cookie[] cookies = request.getCookies();
            if (cookies != null && cookies.length > 0) {
                for (Cookie cookie : cookies) {
                    //获取明文cookie
                    if ("product1".equals(cookie.getName())) {
                        System.out.println(cookie.getValue());
                    }
                    //获取加密cookie
                    if ("product2".equals(cookie.getName())) {
                        System.out.println(URLDecoder.decode(cookie.getValue(), "utf-8"));
                    }
                }
            }

     

    3.设置cookie有效期

    cookie默认实效时间是浏览器关闭之后,也可以指定cookie的实效时间,时间单位为秒。

                 //2.创建明文Cookie信息
                Cookie cookie = new Cookie("product1", product);
                //设置明文cookie的失效时间为5分钟之后
                cookie.setMaxAge(300);
                //2.1创建加密Cookie信息
                Cookie encodecookie = new Cookie("product2", URLEncoder.encode("爱我中华","utf-8"));
                //设置密文cookie的失效时间为3分钟之后
                cookie.setMaxAge(180);

     

    三、Session

    Session基于Cookie,保存在服务器端,Session可以在一次会话的多次请求之间共享数据;

    Sessione有以下特点:

    • Session存储数据在服务器
    • Session存储类型任意(Object)
    • Session存储大小和数量没有限制(相对于内存)
    • Session存储相对安全

     Session机制如下:

    • 1. 浏览器向服务器发送一个添加购物车请求
    • 2. 服务请创建一个Session
    • 3. 通过程序向Session中添加商品信息
    • 4. 服务器通过response将session的唯一标识JSESSIONID写回到浏览器的Cookie中(通过Set-Cookie响应头)
    • 5. 当浏览器发送查询请求的时候,会将cookie中的JSESSIONID信息携带到服务器中(通过Cookie请求头)
    • 6. 服务器接收到请求之后,通过session的唯一标识定位到session
    • 7. 我们就就可以通过程序从session获取信息了

     

    1. 设置session信息

    void setAttribute(String name,Object value)

            //2.获取session对象,并将session信息保存到session对象
            HttpSession session = request.getSession();
            session.setAttribute("product", product);

    2. 获取session信息

    Object getAttribute(String name)

            HttpSession session = request.getSession();
            String product =(String) session.getAttribute("product");

    3. 删除session信息

    void removeAttribute(String name)

    session.removeAttribute("product");

    四、JSP技术

    TCP协议是工作在传输层的数据传输管道,HTTP协议工作在应用程, 通过传输管道在浏览器和服务器之间传输字符串信息。

    在Java Web技术中我们可以以下技术构建1个Web应用。

    • Tomcat接收和响应浏览器的请求和响应, 通过路由锁定1个Servlet并执行。
    • Servlet根据户端请求信息,操作数据库,获取数据,封装到域对象中,转发(forward)到1个.jsp页面。(动态数据准备)
    • JSP把获取到域对象中封装好的动态数据,渲染到HTML,完成动态数据和静态数据的整合。                (动态数据渲染到HTML)
    • Tomcat把整合好的动态数据+HTML静态数据,一同响应给客户端浏览器。  

    JSP(Java Server Pages)是SUN公司在Servlet的基础上推出的一种技术,它将Java代码和HTML语句混合在同1个.jsp文件中编写。

    1个JSP页面由以下2部分构成

    • HTML语句 (输出静态部分)
    • Java代码   (输出动态部分) 

    1.JSP入门案例

    <%@ page import="java.util.Date" %>
    <%@ page import="java.text.SimpleDateFormat" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>JSP案例</title>
    </head>
    <body>
    <%--静态部分--%>
    欢迎访问本网站,当前时间为
    <%--动态部分--%>
    <%
        Date date = new Date();
        String formatDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
        out.write(formatDate);
    %>
    </body>
    </html>
    JSP入门案例

     

    2.JSP执行流程

    JSP本质上就是也是个Servlet,当我们通过浏览器访问1个js页面或者通过1个servlet转发(forward)到1个jsp页面时,Tomcat会经过以下流程,把jsp页面转换成1个Servlet

    Tomcat-------》Web.xml-------》.jsp页面--------》Java代码Servle-------》.Class文件-------》在JVM中运行.Class文件。

    详细流程如下:

    • 客户端发出请求
    • web容器将jsp转化为servlet代码(.java)
    • web容器将转化为servlet代码编译(.class)
    • web容器加载编译后的代码并执行
    • 将执行结果响应给客户端

     

    3.JSP的EL表达式

    JSP中的EL(Expression Language)表达式语言,主要用来简化jsp中对java代码的操作,帮我们从内置的域对象中获取数据在前端显示出来。

    语法:${表达式}

     

    3.1.域对象

    上一篇文章得知Tomcat都会创建request对象和session对象,借助request和session对象进行数据保存;

    在jJSP中我们可以使用EL表达式,从这些对象中获取数据 ,由于数据作用的范围(域)不同,在jsp中称这些封装了servlet数据的对象,为内置域对象。

    内置域对象分别如下

    • page:     当前页面有效

    • request: 当前请求有效

    • session: 当前会话有效

    • application:当前应用有效

    EL表达式获取数据时,会依次从这4个域中寻找,直到找到为止。

    而这四个域对象的作用范围如下图所示

     

    3.1.获取内置域对象中封装的对象数据

    从对象获取数据使用点(对象.属性);

    获取精准域中数据

    • ${requestScope.键名} 从HttpServletRequest域中获取
    • ${sessionScope.键名} 从HttpSession域中获取

    简化写法

    • ${键名} 按照上面的域范围从小到大依次从四个域中进行查找;如果从某一个域中找到了,立即返回;如果四个域中都没有,则返回空
    <h3>获取域对象中存储的对象</h3>
    user对象:${user}<br>
    user对象name:${user.name}<br>
    user对象age:${user.age}<br>

    3.2.获取内置域对象中其他数据类型的数据

    <h3>获取域对象中存储的List</h3>
    List的集合:${userList}<br>
    List的集合第1个元素:${userList[0]}<br>
    List的集合第2个元素:${userList[1]}<br>

     

    4.JSP标准标签库

    Java server pages standarded tag library,即JSP标准标签库

    JSP标准标签库可以在jsp中实现Java的流程控制(判断+ 循环遍历)。

    <%--使用jstl,必须加上这行--%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

    4.1导入jar包

     

    4.2.if标签

    if标签用于单分支条件判断,相当于Java中的`if(条件){}`的用法,它的常见用法如下:

    <c:if test="条件">
    条件成立的逻辑
    </c:if>


    注意: 它只有if的功能,没有else的功能,如果需要else,需要自己取反操作

     

    4.3.forEach标签

    forEach用于循环遍历,相当于java中的for关键字,它的常见属性如下:
    begin:设置循环的开始
    end:设置循环的结束
    var:声明循环过程中的临时变量名字
    step:设置步长——间隔几次循环,执行一次循环体中的内
    items:指定要循环的对象
    varStatus:保存了当前循环过程中的信息(循环的开始、结束、步长、次数等)
    forEach标签的主要用法有下面两种:

     

    4.3.1. 增强for循环

    <c:forEach items="数据集合" var="x">
    ${x}
    </c:forEach>

    4.3.2. 普通for循环

    <c:forEach begin="1" end="10" step="1" var="x">
    ${x}
    </c:forEach>

    5.Servler+JSP实现用户登录案例

    package com.zhanggen.servlet;
    import domain.Person;
    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.ArrayList;
    
    @WebServlet("/loginServlet")
    public class LoginServlet extends HttpServlet {
        @Override
        protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            request.setCharacterEncoding("utf-8");
            response.setContentType("text/html;charset=utf-8");
    
            HttpSession session = request.getSession();
            String sessionCode = (String) session.getAttribute("code");
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            String code = request.getParameter("code");
    
            if (!"zhanggen".equals(username) || !"123.com".equals(password)) {
                response.getWriter().write("用户名/密码错误");
                return;
            }
            if (!"".equals(sessionCode) && !"".equals(code) && code.equals(sessionCode)) {
                ArrayList<Person> friendsList = new ArrayList<>();
                friendsList.add(new Person("Lisa", 36, "河南.安阳"));
                friendsList.add(new Person("Cindy", 26, "内蒙古.乌兰察布"));
                friendsList.add(new Person("Vici", 22, "辽宁.沈阳"));
                friendsList.add(new Person("Andrea", 29, "河南.郑州"));
                friendsList.add(new Person("Wilsion", 36, "四川.绵阳"));
                friendsList.add(new Person("张无忌", 36, "河北.秦皇岛"));
                request.setAttribute("username", username);
                request.setAttribute("friendsList", friendsList);
                ///WEB-INF/下的资源,只能通过请求转发进行访问
                request.getRequestDispatcher("/index.jsp").forward(request, response);
                return;
            }
    
            response.getWriter().write("验证码错误");
    
        }
    }
    LoginServlet

    ----------------------------------------------

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%--使用jstl,必须加上这行--%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    <head>
        <title>微信</title>
    </head>
    <body>
    <h1>欢迎${username}来到微信</h1>
    <table style="border: aqua solid 2px">
        <thead>
        <tr>
            <td>编号</td>
            <td>姓名</td>
            <td>年龄</td>
            <td>地址</td>
        </tr>
        </thead>
        <tbody>
        <c:forEach items="${friendsList}" var="friend" varStatus="status">
            <c:if test="${status.count%2 ==0}">
                <tr style="color: antiquewhite">
                    <td>
                            ${status.count}
                    </td>
                    <td>
                            ${friend.name}
                    </td>
                    <td>
                            ${friend.age}
                    </td>
                    <td>
                            ${friend.address}
                    </td>
                </tr>
            </c:if>
            <c:if test="${status.count%2 !=0}">
                <tr style="color: blue">
                    <td>
                            ${status.count}
                    </td>
                    <td>
                            ${friend.name}
                    </td>
                    <td>
                            ${friend.age}
                    </td>
                    <td>
                            ${friend.address}
                    </td>
                </tr>
            </c:if>
    
        </c:forEach>
        </tbody>
    </table>
    </body>
    </html>
    index.jsp
  • 相关阅读:
    调试PHP如何让浏览器提示错误
    接口的理解
    linux中的curl
    linux后台执行命令:&和nohup
    php定界符<<<EOF讲解
    有关字符集问题
    设置disabled属性
    PHP魔术常量
    phpstorm-有关设置
    php常用函数
  • 原文地址:https://www.cnblogs.com/sss4/p/16194991.html
Copyright © 2020-2023  润新知