JavaWeb-02

7、Cookie、Session

7.1 会话

会话:用户打开了一个浏览器,点击了很多超链接,访问了多个web资源,关闭浏览器,这个过程可以称之为会话。

有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学曾经来过,称之为有状态会话。

一个网站如何证明你来过了?

客户端 服务端

  1. 服务端给客户端一个信件,客户端下次访问客户端带上信件就可以了;cookie
  2. 服务端登记你来过了,下次来的时候来匹配你;session

7.2 保存会话的两种技术

cookie

  • 客户端技术(响应,请求)

session

  • 服务端技术,利用这个技术,可以保存用户的会话信息。我们可以把信息或数据放在Session中!

常见场景:网站登录之后,你下次不同再登录,第二次访问直接可以上去。

7.3 Cookie

在这里插入图片描述

  1. 从请求中拿到cookie信息
  2. 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); // 获得Cookie
cookie.getName(); // 获得cookie中的key
cookie.getValue() // 获得cookie中的value
new Cookie("lastLoginTime", System.currentTimeMillis()+""); // 新建一个cookie
cookie.setMaxAge(24*60*60); // 设置cookie的有效期
resp.addCookie(cookie); // 响应给客户端一个cookie

cookie:一般会保存在本地的用户目录下 appdata;

一个网站cookie是否存在上限?

  • 一个Cookie只能保存一个信息;
  • 一个web站点可以浏览器发送多个Cookie,最多存放20个Cookie;
  • Cookie大小有限制4kB
  • 300个Cookie浏览器的上限

删除Cookie:

  • 不设置有效期,关闭浏览器,自动失效;
  • 设置有效期时间为0;

编码解码:

URLEncoder.encode("王木木","utf-8");
URLDecoder.decode(cookie.getValue(),"utf-8");

7.4 Session(重点)

在这里插入图片描述
什么是Session:

  • 服务器会给每一个用户(浏览器)
  • 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
  • 用户登录之后,整个网站都可以访问! --> 保存用户的信息,保存购物车的信息

Session与Cookie的区别:

  • Cookie是把用户的数据写给用户的浏览器,浏览器保存
  • Session把用户的数据写到用户独占的Session中,服务端保存(保存重要的信息,减少服务器资源的浪费)
  • Session对象由服务器创建

使用场景:

  • 保存一个登录用户的信息
  • 购物车信息
  • 在整个网站中经常使用的数据,我们将它保存在Session中

使用Session:

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        // 得到Session
        HttpSession session = req.getSession();

        // 给Session存东西
        session.setAttribute("name",new Person("王木木",18));

        // 获取Session的ID
        String sessionId = session.getId();

        // 判断Session是不是新创建的
        if (session.isNew()) {
            resp.getWriter().write("session 创建成功,ID:" + sessionId);
        } else {
            resp.getWriter().write("session已经在服务器中存在了,ID" + sessionId);
        }

        // Session创建的时候做了什么事情:
        //Cookie cookie = new Cookie("JSESSIONID",sessionId);
        //resp.addCookie(cookie);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

// 得到Session
HttpSession session = req.getSession();

Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());

HttpSession session = req.getSession();
session.removeAttribute("name");
// 手动注销session
session.invalidate();

会话自动过期:web.xml配置

<!--设置Session默认的失效时间-->
<session-config>
    <!--15分钟后,Session自动失效,以分钟为单位-->
    <session-timeout>15</session-timeout>
</session-config>

8、JSP

8.1 什么是JSP

Java Server Pages:Java服务端页面,也和Servlet一样,用于动态Web技术!

最大的特点:

  • 写JSP就像是写HTML
  • 区别
    • HTML只给用户提供静态的数据
    • JSP页面中可以嵌入Java代码,为用户提供动态数据

8.2 JSP原理

思路:JSP到底怎么执行的?

  • 代码层面没有任何问题

  • 服务器内部工作

    Tomcat中有一个work目录

    IDEA中使用Tomcat的会在IDEA的Tomcat中生成一个work目录
    在这里插入图片描述
    我电脑的地址:

    C:\Users\won_j\.IntelliJIdea2019.3\system\tomcat\Unnamed_javaweb-session-cookie\work\Catalina\localhost\ROOT\org\apache\jsp
    

    发现页面转变成了Java程序!
    在这里插入图片描述

浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!

JSP最终也会被转换成为一个Java类。

JSP本质上就是一个Servlet!

打开index_jsp.java

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports

发现有继承HttpJspBase,进入HttpJspBase类,发现

public abstract class HttpJspBase extends HttpServlet implements HttpJspPage

进一步分析index_jsp.java

// 初始化
public void _jspInit() {
  }
// 销毁
  public void _jspDestroy() {
  }
// JSPService
  public void _jspService(HttpServletRequest request, HttpServletResponse response)
  1. 判断请求

    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
        final java.lang.String _jspx_method = request.getMethod();
        if ("OPTIONS".equals(_jspx_method)) {
            response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
            return;
        }
        if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
            response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
            return;
        }
    }
    
  2. 内置一些对象

    final javax.servlet.jsp.PageContext pageContext; // 页面上下文
    javax.servlet.http.HttpSession session = null;   // session
    final javax.servlet.ServletContext application;  // applicationContext
    final javax.servlet.ServletConfig config;        // config
    javax.servlet.jsp.JspWriter out = null;          // out
    final java.lang.Object page = this;              // page
    HttpServletRequest request                       // 请求
    HttpServletResponse response                     // 响应
    
  3. 输出页面前增加的代码

    response.setContentType("text/html");            // 设置响应的页面类型
    pageContext = _jspxFactory.getPageContext(this, request, response,
                                              null, true, 8192, true);
    _jspx_page_context = pageContext;
    application = pageContext.getServletContext();
    config = pageContext.getServletConfig();
    session = pageContext.getSession();
    out = pageContext.getOut();
    _jspx_out = out;
    
  4. 以上的这些个对象,我们可以在JSP页面中直接使用!
    在这里插入图片描述
    在hello.jsp中,设置变量name并输出到页面上:

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

在访问这个页面之前,并没有存在相应的两个文件。
在这里插入图片描述

当访问之后,打开hello_jsp.java文件,发现:

out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("    <title>Title</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");

String name = "wonjack";

out.write("\r\n");
out.write("\r\n");
out.write("name:");
out.print(name);    // 对于变量的输出,用了out.print()
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");

在JSP页面中:

只要是Java代码,就会原封不动的输出;

如果是HTML代码,就会被转换为:

out.write("<html>\r\n");

这样的格式,输出到前端!

8.3 JSP基础语法

任何语言都有自己的语法,Java中有。JSP作为java技术的一种应用,它拥有一些自己扩充的语法(了解,知道即可),Java所有语法都支持!

JSP表达式
 <%--JSP表达式
  作用:用来将程序的输出,输出到客户端
  <%= 变量或者表达式%>
  --%>
  <%= new java.util.Date()%>
脚本片段
 <%--jsp脚本片段--%>
  <%
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
      sum += i;
    }
    out.println("<h1>Sum="+sum+"</h1>");
  %>
脚本片段的再实现
  <%
    int x = 10;
    out.println(x);
  %>
  <p>这是一个JSP文档</p>

  <%
    int y = 2;
    out.println(y);
  %>
  <hr>

  <%--在代码中嵌入HTML元素--%>
  <%
    for (int i = 0; i < 5; i++) {
  %>

  <h1>hello,u meet!<%=i%></h1>
  <%
    }
  %>
JSP声明

8.4 JSP指令

修改了web.xml文件,必须要重启Tomcat!

<%@ page args…… %>

<%--定制错误页面--%>
<%@ page errorPage="error/500.jsp" %>
<%--显式地声明这是一个错误页面--%>
<%@ page isErrorPage="true" %>
<%@ page pageEncoding="UTF-8" %> 
<%-- @include会将两个页面合二为一 --%>
<%@ include file="common/header.jsp"%>
<h1>网页主体</h1>
<%@ include file="common/footer.jsp"%>

<hr>

<%--JSP标签
jsp:include:拼接页面,本质上还是三个
一般用这个,灵活性更高
--%>
<jsp:include page="/common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="/common/footer.jsp"/>

在这里插入图片描述

8.5 九大内置对象

  • PageContext
  • Request 存东西
  • Response 存东西
  • Session 存东西
  • Application【ServletContext】 存东西
  • Config【ServletConfig】
  • Out
  • Page,不同了解
  • Exception

pageDemo01.jsp

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

<%--内置对象--%>
<%
    
    pageContext.setAttribute("name1","王木1号"); // 保存的作用域只在一个页面中有效
    request.setAttribute("name2","王木2号"); // 保存的数据只在一次请求中有效,请求转发会携带这个数据
    session.setAttribute("name3","王木3号"); // 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
    application.setAttribute("name4","王木4号"); // 保存的数据只在服务器中有效,从打开服务器到关闭服务器
%>
<%--脚本片段中的代码,会被原封不动生成到_jsp.java
要求:这里面的代码:必须保证Java语法的正确性
--%>
<%
    // pageContext取出,我们通过寻找的方式来
    // 从底层到高层(作用域)
    String name1 = (String) pageContext.findAttribute("name1");
    String name2 = (String) pageContext.findAttribute("name2");
    String name3 = (String) pageContext.findAttribute("name3");
    String name4 = (String) pageContext.findAttribute("name4");
    String name5 = (String) pageContext.findAttribute("name5"); // 不存在

%>

<%--使用EL表达式输出 ${} --%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<%--如果不存在则不在页面上输出--%>
<h3>${name5}</h3>
<%--如果不存在,则输出null--%>
<h3><%=name5%></h3>

</body>
</html>

输出:
在这里插入图片描述

pageDemo02.jsp直接去取pageDemo01.jsp中的数据:

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

<%--脚本片段中的代码,会被原封不动生成到_jsp.java
要求:这里面的代码:必须保证Java语法的正确性
--%>
<%
    // pageContext取出,我们通过寻找的方式来
    // 从底层到高层(作用域):page -> request -> session -> application
    String name1 = (String) pageContext.findAttribute("name1");
    String name2 = (String) pageContext.findAttribute("name2");
    String name3 = (String) pageContext.findAttribute("name3");
    String name4 = (String) pageContext.findAttribute("name4");
    String name5 = (String) pageContext.findAttribute("name5"); // 不存在

%>

<%--使用EL表达式输出 ${} --%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<%--如果不存在则不在页面上输出--%>
<h3>${name5}</h3>
<%--如果不存在,则输出null--%>
<h3><%=name5%></h3>

</body>
</html>

输出:
在这里插入图片描述
request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完就没用的!

session:客户端向服务器发送请求,产生的数据,用户用完一会儿还有用,比如:购物车;

application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;

pageDemo01.jsp中添加:

pageContext.forward("/pageDemo02.jsp");

访问pageDemo01.jsp,会有:
在这里插入图片描述
原因如下:

request.setAttribute("name2","王木2号"); // 保存的数据只在一次请求中有效,请求转发会携带这个数据

8.6 JSP 标签、JSTL标签、EL表达式

        <!--JSTL表达式的依赖-->        
		<dependency>
            <groupId>javax.servlet.jsp.jstl</groupId>
            <artifactId>jstl-api</artifactId>
            <version>1.2</version>
        </dependency>
        <!--standard标签库-->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

EL表达式:${}(Expression Language) 是为了使JSP写起来更加简单。表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法,让Jsp的代码更加简化。

  • 获取数据
  • 执行运算
  • 获取文本开发的常用对象
  • 调用Java方法

JSP标签

<%--jsp:include--%>
<%--
http://localhost:8080/jsptag.jsp?name=jackwon&age=18
--%>
<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name" value="jackwon"/>
    <jsp:param name="age" value="18"/>
</jsp:forward>

JSTL表达式

JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和Java代码一样!

格式化标签

SQL标签

XML标签

核心标签(掌握部分)

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

在这里插入图片描述
JSTL标签库使用步骤

  • 引入对应的taglib
  • 使用其中的方法
  • 在Tomcat也需要引入JSTL的包,否则会报错:JSTL解析错误

c:if

<body>

<h4>if测试</h4>
<hr>

<form action="coreif.jsp" method="get">
   <%--
   EL表达式获取表单中的数据
   ${param.参数名}
   --%>
   <input type="text" name="username" value="${param.username}">
   <input type="submit" value="登录">
</form>

<%--判断如果提交的用户名是管理员,则登录成功--%>
<%--<%--%>
<%--    if (request.getParameter("username").equals("admin")) {--%>
<%--        out.print("登录成功");--%>
<%--    }--%>
<%--%>--%>
<c:if test="${param.username=='admin'}" var="isAdmin">
   <c:out value="管理员欢迎您!"/>
</c:if>
<%--自闭和标签--%>
<c:out value="${isAdmin}"/>
</body>

c:choose c:when

<body>
<%--定义了一个变量score,值为85--%>
<c:set var="score" value="85"/>

<c:choose>
    <c:when test="${score>=90}">你的成绩为优秀</c:when>
    <c:when test="${score>=80}">你的成绩为良好</c:when>
    <c:when test="${score>=70}">你的成绩为一般</c:when>
    <c:when test="${score<=80}">你的成绩为及格</c:when>
    
</c:choose>

</body>

c:foreach

<%--
var,每一次遍历出来的变量
items,要遍历的对象
begin,哪里开始
end,到哪里
step,步长

--%>
<c:forEach var="people" items="${list}">
    <c:out value="${people}"/><br>
</c:forEach>

<hr>
<c:forEach var="people" items="${list}" begin="1" end="3" step="2">
    <c:out value="${people}"/><br/>
</c:forEach>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值