1.会话技术

1.会话技术概述

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

java 会话技术 javaweb会话_数据

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

功能:在一次会话的范围内的多次请求间,共享数据

分类

  • 客户端会话技术:Cookie
  • java 会话技术 javaweb会话_java_02

  • 服务器端会话技术:Session

2.Cookie对象

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

大白话:将需要共享的数据,响应时,发送给浏览器,当下一次请求时,浏览器又请求给服务器,实现数据共享

常用方法

  • 创建Cookie对象:new Cookie(String name, String value)
  • 发送Cookie对象:response.addCookie(Cookie cookie)
  • 获取Cookie,拿到数据:Cookie[] request.getCookies()

代码示例
Cookie01代码,往Cookie中存入信息

@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建Cookie对象
        Cookie c = new Cookie("msg","hello");
        //2.发送Cookie
        response.addCookie(c);
    }

Cookie02代码,从Cookie中拿出信息

@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //3.获取Cookie对象
        Cookie[] cookies = request.getCookies();
        //遍历Cookie
        if (cookies!=null){
            for (Cookie c : cookies) {
                String name = c.getName();
                String value = c.getValue();
                System.out.println(name+"=="+value);
            }
        }
    }

浏览器收到set-cookie响应头,就明白了,这个数据要存储到cookie中去,当我们下一次请求浏览器时,就将数据通过请求头cookie发送到服务器中去实现

java 会话技术 javaweb会话_java_03

cookie细节

一次可不可以发送多个cookie?

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

cookie在浏览器中保存多长时间?

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

持久化存储

持久化存储用setMaxAge(int seconds)

  1. 正数:将Cookie数据写到硬盘的文件中。持久化存储。并指定cookie存活时间,时间到后,cookie文件自动失效
  2. 负数:默认值
  3. 零:删除cookie信息

代码示例

向cookie中保存信息,并设置浏览器保存60s

@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.创建Cookie对象
        Cookie c = new Cookie("msg","setMaxAge");
        //2.设置cookie保存时间
        //将cookie持久化到硬盘,60秒后会浏览器自动删除cookie文件,那么服务器就接收不到该数据
        c.setMaxAge(60);
        //3.发送Cookie
        response.addCookie(c);
    }

获取指定信息

@Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //3.获取Cookie对象
        Cookie[] cookies = request.getCookies();
        //遍历Cookie
        if (cookies!=null){
            for (Cookie c : cookies) {
                if ("msg".equals(c.getName())){
                    String name = c.getName();
                    String value = c.getValue();
                    System.out.println(name+"=="+value);
                }
            }
        }
    }

关闭浏览器60s之内,我们再次访问该路径,服务器控制台任然能够得到msg数据

cookie能不能存中文?

  • 在tomcat 8 之前 cookie中不能直接存储中文数据。(需要将中文数据转码—一般采用URL编码(%E3))
  • 在tomcat 8 之后,cookie支持中文数据。特殊字符还是不支持,建议使用URL编码存储,URL解码解析

cookie共享问题?

假设在一个tomcat服务器中,部署了多个web项目,那么在这些web项目中cookie能不能共享?

  • 默认情况下cookie不能共享
  • setPath(String path):设置cookie的获取范围。默认情况下,设置当前的虚拟目录
  • 如果要共享,则可以将path设置为"/"

不同的tomcat服务器间cookie共享问题?

  • setDomain(String path):如果设置一级域名相同,那么多个服务器之间cookie可以共享
  • setDomain(".baidu.com"),那么tieba.baidu.com和news.baidu.com中cookie可以共享

Cookie特征

特征

  1. cookie存储数据在客户端浏览器
  2. 浏览器对于单个cookie 的大小有限制(4kb) 以及 对同一个域名下的总cookie数量也有限制(20个)

作用

  1. 在不登录的情况下,完成服务器对客户端的身份识别
  2. cookie一般用于存出少量的不太敏感的数据

3.Session对象

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

常用方法

request.getSession():获取HttpSession对象

Object getAttribute(String name) :得到保存数据

void setAttribute(String name, Object value):保存数据

void removeAttribute(String name) :移除数据

代码示例

Session01

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取session对象
        HttpSession session = req.getSession();
        //2.往session中存入数据
        session.setAttribute("msg","hello,session");
    }

Session02

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取session对象
        HttpSession session = req.getSession();
        //2.获取session对象的数据
        Object msg = session.getAttribute("msg");
        System.out.println(msg);
    }

session实现原理

java 会话技术 javaweb会话_java 会话技术_04

其实就是利用cookie对象,来传递一个Session的ID,当下次请求时,通过ID来找到储存在服务器中的Session对象

Session细节

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

  • 默认情况下。不是。
  • 如果需要相同,则需要手动创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存那么cookie所携带的session的ID也将在下一次请求发送给服务器。

代码示例

@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1.获取session对象
        HttpSession session = req.getSession();
        //2.往session中存入数据
        session.setAttribute("msg","hello,session");

        //3.手动设置Cookie
        Cookie cookie = new Cookie("JSESSIONID",session.getId());
        //4.设置Cookie存活时间(一个小时)
        cookie.setMaxAge(60*60);
        //5.发送cookie
        resp.addCookie(cookie);
    }

客户端不关闭,服务器关闭后,两次获取的session是同一个吗?

  • 不是同一个,但是要确保数据不丢失。tomcat自动完成以下工作

session的钝化:

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

session的活化

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

Tocat服务器已经帮我们自动实现session的钝化和session的活化

session什么时候被销毁?

  1. 服务器关闭时被销毁
  2. session对象调用invalidate()后,被销毁
  3. session默认失效时间 30分钟
选择性配置修改(在web.xml中配置)
<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相对于不安全

2.JSP基础

什么是JSP:Java Server Pages: java服务器端页面

  • 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定义java代码
  • 用于简化书写!!!

原理

  • JSP本质上就是一个Servlet

1.JSP的脚本

  1. <% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
  2. <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
  3. <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  <% System.out.println("hello,jsp"); int i=200; %> <%-- 等于在service方法中--%>
  <%! int i=100;  %> <%--  定义成员变量--%>
  <%= "hello,jsp"  %> <%--  把值输出到页面上--%>
  <%= i %> <%--  把值输出到页面上--%>
  </body>
</html>

注意:如果定义的变量名相同(<%! 代码 %>和 <% 代码 %>都定义了相同的i),<%= 代码 %>在输出时,<% 代码 %>优先

2.指令

作用:用于配置JSP页面,导入资源文件

格式:<%@ 指令名称 属性名1=属性值1 属性名2=属性值2 … %>

例如:<%@ page contentType="text/html;charset=UTF-8" language="java" %>

分类

  1. page: 配置JSP页面的
  2. include : 页面包含的。导入页面的资源文件
  3. taglib : 导入资源

1.page指令

  • contentType:等同于response.setContentType()
  1. 设置响应体的mime类型以及字符集
  2. 设置当前jsp页面的编码(只能是高级的IDE才能生效,如果使用低级工具,则需要设置pageEncoding属性设置当前页面的字符集)
  • import:导包
  • errorPage:当前页面发生异常后,会自动跳转到指定的错误页面
  • isErrorPage:标识当前也是是否是错误页面
  1. true:是,可以使用内置对象exception
  2. false:否。默认值。不可以使用内置对象exception

2.include指令

include : 页面包含的。导入其他页面

例如: <%@include file="top.jsp"%>

A页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>A页面</h1>

B页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%--导入A页面--%>
<%@ include file="A.jsp" %>
<html>
<head>
    <title>B</title>
</head>
<body>
BBBBB
</body>
</html>

页面显示

java 会话技术 javaweb会话_数据_05

3.taglib指令

taglib : 导入标签库

prefix:前缀,自定义的

例如: <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

代码示例

<%--导入java包--%>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>

<%--contentType:设置响应体的mime类型以及字符集,设置当前jsp页面的编码--%>
<%--errorPage:当前页面发生异常后,会自动跳转到500.jsp页面--%>
<%@ page contentType="text/html;charset=gbk" errorPage="500.jsp"   pageEncoding="GBK" language="java" buffer="16kb" %>

<%--设置标签库 prefix:给使用的标签库取名字 uri:要导入的标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>


  </body>
</html>

使用

java 会话技术 javaweb会话_数据_06

向使用xml标签一样

3.内置对象

在jsp页面中不需要创建,直接使用的对象,一共有9个

变量名

真实类型

作用

pageContext

PageContext

当前页面共享数据,还可以获取其他八个内置对象

request

HttpServletRequest

一次请求访问的多个资源(转发)

session

HttpSession

一次会话的多个请求间

application

ServletContext

所有用户间共享数据

response

HttpServletResponse

响应对象

page

Object

当前页面(Servlet)的对象 this

out

JspWriter

输出对象,数据输出到页面上

config

ServletConfig

Servlet的配置对象

exception

Throwable

异常对象

3.EL表达式

概念:Expression Language 表达式语言

作用:替换和简化jsp页面中java代码的编写

语法:${表达式}

例如          ${3>4}

网页显示

java 会话技术 javaweb会话_html_07

注意

  • jsp默认支持el表达式的。如果要忽略el表达式
  1. 设置jsp中page指令中:**isELIgnored=“true”** 忽略当前jsp页面中所有的el表达式
  2. ${表达式} :忽略当前这个el表达式

1.运算符

算数运算符

算数运算符: + - * /(div) %(mod)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<hr>

<h3>算数运算符</h3>

${3 + 4}<br> <%--结果为7--%>

${3 / 4}<br> <%--结果为0.75--%>

${3 div 4}<br> <%--结果为0.75--%>

${3 % 4}<br> <%--结果为3--%>

${3 mod 4}<br> <%--结果为3--%>

</body>
</html>

比较运算符

比较运算符: > < >= <= == !=

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<hr>

<h3>比较运算符</h3>

${3 == 4}<br>  <%--结果为 false--%>

</body>
</html>

逻辑运算符

逻辑运算符: &&(and) ||(or) !(not)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<hr>

<h3>逻辑运算符</h3>

${3 > 4  && 3 < 4}<br> <%--结果为 false--%>

${3 > 4  and 3 < 4}<br> <%--结果为 false--%>

</body>
</html>

空运算符

空运算符: empty

  • 功能:用于判断字符串、集合、数组对象是否为null或者长度是否为0
  • ${empty list}:判断字符串、集合、数组对象是否为null或者长度为0
  • ${not empty str}:表示判断字符串、集合、数组对象是否不为null 并且 长度>0

代码示例

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h3>empty运算符</h3>
<%

    String str = "";
    request.setAttribute("str",str);

    List list = new ArrayList();
    request.setAttribute("list",list);

%>
${not empty str}<br> <%--结果为false --%>

${not empty list}<br> <%--结果为false --%>

</body>
</html>

显示结果

java 会话技术 javaweb会话_java 会话技术_08

2.获取值

el表达式只能从域对象中获取值

语法

获取方式一 

1. ${域名称.键名}:从指定域中获取指定键的值
 * 域名称:
   1. pageScope		--> pageContext
   2. requestScope 	--> request
   3. sessionScope 	--> session
   4. applicationScope --> application(ServletContext)
   
   * 举例:在request域中存储了name=张三
   * 获取:${requestScope.name}

获取方式二
2. ${键名}:表示依次从最小的域中查找是否有该键对应的值,直到找到为止。

代码示例(获取值)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--存入数据--%>
<%
    request.setAttribute("name","张三");
    session.setAttribute("age",18);
%>

<%--获取数据--%>
${requestScope.name}
${sessionScope.age}

<%--如果没有,则在页面上什么都不显示(空字符串)--%>
${sessionScope.ss}
</body>
</html>

显示结果

java 会话技术 javaweb会话_数据_09

上面的案例是从域对象中获取值

获取对象

对象:${域名称.键名.属性名}

  • 本质上会去调用对象的getter方法

代码示例

User实体对象

public class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

jsp页面

<%@ page import="domain.User" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--存入数据--%>
<%
    User user = new User();
    user.setName("李四");
    user.setAge(21);

    request.setAttribute("u",user);
%>

<%--获取数据--%>
${requestScope.u}<br>
${requestScope.u.age}<br>
${requestScope.u.name}<br>
</body>
</html>

这里调用了User类中的getXxxx方法

网页显示

java 会话技术 javaweb会话_数据_10

获取List集合

语法:${域名称.键名[索引]}

代码示例

<%@ page import="domain.User" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--存入数据--%>
<%
    ArrayList<Integer> list = new ArrayList<>();
    list.add(100);
    list.add(200);
    list.add(300);

    request.setAttribute("list",list);
%>

<%--获取数据--%>
${requestScope.list}<br>
${requestScope.list[0]}<br>
${requestScope.list[1]}<br>
${requestScope.list[2]}<br>
</body>
</html>

显示结果

java 会话技术 javaweb会话_数据_11

获取Map集合

语法

  • ${域名称.键名.key名称}
  • ${域名称.键名[“key名称”]}

代码示例

<%@ page import="domain.User" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.HashMap" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--存入数据--%>
<%
    HashMap<String, String> map = new HashMap<>();

    map.put("小明","哈哈哈");
    map.put("小红","呵呵呵");
    map.put("小王","嘻嘻嘻");

    request.setAttribute("people",map);
%>

<%--获取数据--%>
${requestScope.people}<br>
${requestScope.people.小红}<br>
${requestScope.people["小王"]}<br>

</body>
</html>

显示结果

java 会话技术 javaweb会话_html_12

注意:如果map集合的K是Integer类,无法实现上面的功能

4.JSTL基础

概念:JavaServer Pages Tag Library JSP标准标签库,是由Apache组织提供的开源的免费的jsp标签

作用:用于简化和替换jsp页面上的java代码

1.使用步骤

  1. 导入jstl相关jar包
  2. 引入标签库:taglib指令: <%@ taglib %>
  3. 使用标签

2.常用的JSTL标签

if标签

1. if:相当于java代码的if语句
	1. 属性:
	  * test 必须属性,接受boolean表达式
	       * 如果表达式为true,则显示if标签体内容,如果为false,则不显示标签体内容
	       * 一般情况下,test属性值会结合el表达式一起使用
    2. 注意:
	      * c:if标签没有else情况,想要else情况,则可以在定义一个c:if标签

代码示例

<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <title>if标签</title>
</head>
<body>
    <c:if test="true">
        <h1>我是真...</h1>
    </c:if>
    <br>

    <c:if test="${not empty list}">
        遍历集合...
    </c:if>
    <br>

    <c:if test="${number % 2 != 0}">
            ${number}为奇数
    </c:if>

    <c:if test="${number % 2 == 0}">
       ${number}为偶数
    </c:if>

</body>
</html>

choose标签

2. choose:相当于java代码的switch语句
	1. 使用choose标签声明         			相当于switch声明
    2. 使用when标签做判断         			相当于case
    3. 使用otherwise标签做其他情况的声明    	相当于default

代码示例

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <title>choose标签</title>
</head>
<body>

    <%--
        完成数字编号对应星期几案例
            1.域中存储一数字
            2.使用choose标签取出数字         相当于switch声明
            3.使用when标签做数字判断         相当于case
            4.otherwise标签做其他情况的声明  相当于default
    --%>

    <%
        request.setAttribute("number",51);
    %>

    <c:choose>
        <c:when test="${number == 1}">星期一</c:when>
        <c:when test="${number == 2}">星期二</c:when>
        <c:when test="${number == 3}">星期三</c:when>
        <c:when test="${number == 4}">星期四</c:when>
        <c:when test="${number == 5}">星期五</c:when>
        <c:when test="${number == 6}">星期六</c:when>
        <c:when test="${number == 7}">星期天</c:when>

        <c:otherwise>数字输入有误</c:otherwise>
    </c:choose>


</body>
</html>

foreach标签

3. foreach:相当于java代码的for语句

代码示例

<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<html>
<head>
    <title>foreach标签</title>
</head>
<body>

<%--

    foreach:相当于java代码的for语句
        1. 完成重复的操作
            for(int i = 0; i < 10; i ++){

            }
            * 属性:
                begin:开始值
                end:结束值
                var:临时变量
                step:步长
                varStatus:循环状态对象
                    index:容器中元素的索引,从0开始
                    count:循环次数,从1开始
        2. 遍历容器
            List<User> list;
            for(User user : list){

            }

            * 属性:
                items:容器对象
                var:容器中元素的临时变量
                varStatus:循环状态对象
                    index:容器中元素的索引,从0开始
                    count:循环次数,从1开始


--%>

<c:forEach begin="1" end="10" var="i" step="2" varStatus="s">
    ${i} <h3>${s.index}<h3> <h4> ${s.count} </h4><br>

</c:forEach>

    <hr>


    <%
        List list = new ArrayList();
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");

        request.setAttribute("list",list);


    %>

    <c:forEach items="${list}" var="str" varStatus="s">

            ${s.index} ${s.count} ${str}<br>

    </c:forEach>


</body>
</html>