web基础3-servlet入门2(session、cookie、JSP和bean概念)

web基础3-servlet入门2(session、cookie、JSP和bean概念)

一、Cookie 、Session

7.1 会话

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

有状态会话:

一个客户来过商店,下次再来这个商店,我们需要知道这个客户曾经来过,这个过程可以称之为会话;

你能怎么证明你是商店的客户?

你 商店

1.发票 商店给你发票

2.商店登记 商店标记你来过了(会员)

一个网站,怎么证明你来过?

客户端 服务端

1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了=》cookie

2.服务器登记你来过了,下次你来的时候我来匹配你=》session

7.2 常见应用场景

网站登陆之后,你下次不用登陆了,第二次访问直接就上去了

7.3 保存会话的两种技术

  • 客户端技术

服务端怎么发给客户端:响应

客户端怎么把东西带到服务端:请求

<servlet>
    <servlet-name>CookieServlet</servlet-name>
    <servlet-class>com.happy.servlet.CookieServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>CookieServlet</servlet-name>
    <url-pattern>/cookie</url-pattern>
</servlet-mapping>
package com.happy.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

public class CookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //服务器,告诉你,你来的时间,把这个时间封装成为一个信件,你下次来,我就知道你来了
        //解决中文乱码
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();

//        cookie,服务器从客户端获取cookie
//        从这里返回数组,说明cookie可能存在多个
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {

                String name = cookie.getName();
                if (name.equals("time")) {
                    System.out.println("==============");
                    String value = cookie.getValue();
                    long ltime = Long.parseLong(value);
                    Date date = new Date(ltime);
                    System.out.println("上次访问时间是=>" + date.toLocaleString());
                    out.write("您上次访问时间=>" + date.toLocaleString() + "\n");
                    continue;
                }
                if (name.equals("name")) {
                    System.out.println("==============");
                    String value = cookie.getValue();
                    System.out.println(name + ":" + value);
                    out.write("您的姓名是=>" + value + "\n");
                    continue;
                }

            }
        } else {
            out.write("这是您第一次访问本站");
        }
//        服务器给客户端响应一个cookie
//        Date date = new Date();
//        SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
//        System.out.println(formatter.format(date));
//        String time = formatter.format(date);
        long ltime = System.currentTimeMillis();

//        cookie只能存string不能存对象,有局限性
        Cookie cookie1 = new Cookie("time", String.valueOf(ltime));
//        设置时间的有效期为1天
        cookie1.setMaxAge(24*60*60);
        Cookie cookie2 = new Cookie("name2", "happy");
        Cookie cookie3 = new Cookie("name2", "happy3");
        response.addCookie(cookie1);
        response.addCookie(cookie2);
        response.addCookie(cookie3);

    }

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

7.3.1.1 cookie的有效期

cookie默认有效期为:打开访问地址到关闭浏览器的一次会话

改变cookie有效期

//        设置时间的有效期为1天
        cookie1.setMaxAge(24*60*60);

7.3.1.2 cookie操作步骤和API
  1. 从请求中拿到cookie信息

  2. 服务器响应客户端cookie

    Cookie[] cookies=req.getCookies();   //获得Cookie数组
    cookie.getName();    //获得cookie的key
    cookie.getValue();   //获得cookie的value
    //创建一个cookie
    new Cookie("name","happy");
    //设置cookie的有效期
    cookie.setMaxAge(24*60*60);
    //响应给客户端一个cookie
    resp.addCookie(cookie1)
    resp.addCookie(cookie2)
    

    注意:new Cookie("name","happy")中的key是全局唯一,如果有重复以最后一次为准,既覆盖

7.3.1.3 cookie的保存地址

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

7.3.1.4 cookie的特性

一个网站cookie是否存在上限!细节问题

  • 一个cookie只能保存一个信息

  • 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie

  • cookie大小有限制4kb

  • 300个cookie浏览器上限。

  • cookie只能存字符串数据(因为在客户端),而session可以存对象

    new cookie(String st1,String str2);
    session.setAttribute(String var1, Object var2);
    
7.3.1.5 删除cookie

核心代码:修改cookie的有效期并立即返回

Cookie cookie1 = new Cookie(cookieName,"");
cookie1.setMaxAge(0);
response.addCookie(cookie1);

详细代码如下

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>删除cookie</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/cookiedel">
    您要删除的cookie的name:<input type="text" name="name"/><br/>
    <input type="submit">
</form>
</body>
</html>

<servlet>
    <servlet-name>CookieDelServlet</servlet-name>
    <servlet-class>com.happy.servlet.CookieDelServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>CookieDelServlet</servlet-name>
    <url-pattern>/cookiedel</url-pattern>
</servlet-mapping>
package com.happy.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

public class CookieDelServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
//        获取前端传来的参数cookie名字
        String cookieName=request.getParameter("name");
        PrintWriter out = response.getWriter();
        Cookie[] cookies = request.getCookies();
        for (Cookie cookie : cookies) {
            if(cookie.getName().equals(cookieName)) {
                Cookie cookie1 = new Cookie(cookieName,"");
                cookie1.setMaxAge(0);
                response.addCookie(cookie1);
                break;
            }
        }
        out.println("您删除了cookie:"+cookieName);
    }

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

7.3.1.6 Urlencode编码解码

如果遇到cookie值中文出现乱码,可以编码解码。

URLEncoder.encode("高兴","utf-8")
URLEncoder.Decode(cookie.getValue(),"utf-8")

7.3.2 session

  • 服务端技术(也依赖于cookie)

主要服务器登记你来过,利用这个技术,可以保存用户的会话信息。我们可以把信息和数据放在session中。

  • 可以在服务器,给每一个用户创建一个session对象(建议)

  • 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在。注意是一个浏览器一个session,不同浏览器不同session

  • 用户登陆之后,整个网站它都可以访问了

  • session的应用:保存用户或者购物车的信息

7.3.2.1 session和cookie的关系

session的唯一标志SessionId存在一个cookie当中。cookie的name为JSESSIONID

7.3.2.2 session的操作步骤和API
package com.happy.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;

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

        PrintWriter out = response.getWriter();
//        得到session
        HttpSession session = request.getSession();
        session.setAttribute("name","高兴");
        Object id = session.getAttribute("id");
        String sessionId = session.getId();
        System.out.println(sessionId);

        boolean aNew = session.isNew();
        if(aNew){
            out.write("session创建成功,sessionID为:"+sessionId);
        }else{
            out.write("session已经存在了,sessionID为:"+sessionId);
        }

//        尝试从cookie里拿sessionId
        for (Cookie cookie : request.getCookies()) {
            if(cookie.getName().equals("JSESSIONID")){
                System.out.println("cookie里的JSESSIONID值为:"+cookie.getValue());
            }
        }

//        给session中增加东西
    }

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

结果如下:可见一样

删除session的cookie,session也消失

删除前查看session情况

删除后查看session情况:原来sessionId被删除了

7.3.3.3 删除session

除了上面删除session所依赖的name为JSESSIONID的cookie以外,一般不用这种方式,还有两种方式:

手动删除

在代码中显示的手动注销,使用session.invalidate()

package com.happy.servlet;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

public class InvalidateSessionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession();
        session.invalidate();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}
web.xml配置删除

也可以在web.xml中通过配置,全局设置session的有效期。

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">

    <servlet>
        <servlet-name>CookieServlet</servlet-name>
        <servlet-class>com.happy.servlet.CookieServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CookieServlet</servlet-name>
        <url-pattern>/cookie</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>CookieDelServlet</servlet-name>
        <servlet-class>com.happy.servlet.CookieDelServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CookieDelServlet</servlet-name>
        <url-pattern>/cookiedel</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ChineseCookieServlet</servlet-name>
        <servlet-class>com.happy.servlet.ChineseCookieServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ChineseCookieServlet</servlet-name>
        <url-pattern>/chinese</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>SessionServlet</servlet-name>
        <servlet-class>com.happy.servlet.SessionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SessionServlet</servlet-name>
        <url-pattern>/session</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>GetSessionServlet</servlet-name>
        <servlet-class>com.happy.servlet.GetSessionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetSessionServlet</servlet-name>
        <url-pattern>/getsession</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>InvalidateSessionServlet</servlet-name>
        <servlet-class>com.happy.servlet.InvalidateSessionServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>InvalidateSessionServlet</servlet-name>
        <url-pattern>/invalidate</url-pattern>
    </servlet-mapping>

    <!--设置session的时间-->
    <session-config>
<!--        1分钟后session自动失效,以分钟为单位-->
        <session-timeout>1</session-timeout>
    </session-config>
</web-app>



        

7.3.3 cookie和session的区别

cookie session
技术分类 客户端技术 主要是服务端技术
使用cookie保存信息程度 保存所有信息在cookie里 只保存sessionId在一个name为JESESSIONID的cookie里
保存信息位置 都保存在客户端 除了一个存JESESSIONID的cookie,其余保存在服务器的一个用户(一个浏览器的)独占session对象中
保存信息类型 只能保存字符串类数据 可以保存object类型
数量 可以有多个cookie 一个浏览器只有一个session
创建方法 通过new一个cookie对象存放一个键值对 通过getSession后,再用session.setAttribute
销毁方法 new一个同名cookie,并设置cookie.setMaxAge(0); 1. session.invalidate,销毁所有session里的数据,
2. web.xml配置全局session timeout

7.3.2 session和ServletContext域(ApplicationContext)的区别

session ServletContext
域范围 一个浏览器内共享数据(不论这个浏览器内多少窗口) 所有Servelet共享数据,多个浏览器甚至不同用户共享数据。
应用场景 保存用户专属数据,如:1. 登陆(保存登陆信息)等;2.购物车信息 可用于计数,如某页面访问量
使用频率 极低

二、JSP

2.1 什么是JSP

Java Server Pages:Java服务器端页面,也和Servlet一样用于开发动态web

最大特点:写JSP就像在写HTML

2.2 JSP和HTML区别

HTML JSP
动静态 HTML只给用户提供静态的数据 HTML只给用户提供动态的数据
嵌入代码 只能嵌入前端js代码 除了js代码,JSP页面中可以嵌入后端JAVA代码

2.3 JSP原理1-基础原理

JSP是怎么运行的:

发现页面转变成了JAVA程序。

C:\Users\pcuser\AppData\Local\JetBrains\IntelliJIdea2021.2\tomcat\4be3f694-8291-4810-983d-7d84643de4d0\work\Catalina\localhost\cookie\org\apache\jsp

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

  • Jsp最后也会变成java类

JSP本质上就是一个Servlet,核心方法如下

//初始化  
  public void _jspInit() {
  }
//销毁
  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)

2.4 JSP Servlet处理步骤

查看核心方法

2.4.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.4.2 内置9大对象初识

final javax.servlet.jsp.PageContext pageContext;      //页面上下文
javax.servlet.http.HttpSession session = null;		  //session
final javax.servlet.ServletContext application;   //application实际为ServletContext改名
final javax.servlet.ServletConfig config;		//配置
javax.servlet.jsp.JspWriter out = null;			//out
final java.lang.Object page = this;		 	//page:代表当前页
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;

//传入参数
final javax.servlet.http.HttpServletRequest request,      //请求
final javax.servlet.http.HttpServletResponse response     //响应

2.4.3 输出页面前增加的代码

servlet帮忙完成初始化的工作

try {
      response.setContentType("text/html;charset=UTF-8");
      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;

2.4.4 以上这些对象可以在JSP页面中直接使用

通过set.jsp负责通过jsp servlet的api接口直接set session

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>set session by jsp</h1>
<%
  session.setAttribute("happy518","happy5188");
  out.print("你set session attribute happy518");
%>
<a href="${pageContext.servletContext.contextPath}/get.jsp" target="_blank">通过打开这个超链接测试session是否set进去了</a>
</body>
</html>

通过get.jsp负责通过jsp servlet的api接口直接get session

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>getSession by jsp</h1>
<%
    Object happy518 = session.getAttribute("happy518");
    out.print(happy518);
%>
</body>
</html>

可以看到,当第一次访问对应jsp页面的时候,生成了对应的servlet.java

2.5 JSP原理2-编译servlet原理

jsp转成java遵循以下:

  1. 把html页面代码,转换成out.write 到java文件

  2. 把java代码(<%java 代码%>包裹的),原封不动的输出到java

  3. 把<%=name%>用out.print(name)转成到java

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>删除cookie</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/cookiedel">
    您要删除的cookie的name:<input type="text" name="name"/><br/>
    <input type="submit">
</form>

<%
String name="happy";
%>
name:<%=name%>
</body>
</html>

转成java

out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("    <title>删除cookie</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("<form action=\"");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${pageContext.request.contextPath}", java.lang.String.class, (javax.servlet.jsp.PageContext)_jspx_page_context, null));
out.write("/cookiedel\">\r\n");
out.write("    您要删除的cookie的name:<input type=\"text\" name=\"name\"/><br/>\r\n");
out.write("    <input type=\"submit\">\r\n");
out.write("</form>\r\n");
out.write("\r\n");

String name="happy";

out.write("\r\n");
out.write("name:");
out.print(name);
out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");

2.6 JSP脚本基础语法

任何语言都有自己的语法,JSP也不例外,JSP作为JAVA技术的一种应用,它拥有一些自己扩充的语法,了解即可,java所有语法都支持。

2.6.1 JSP注释

<%--  JSP表带式--%>

2.6.2 JSP表达式

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  $END$
<%--  JSP表带式--%>
  <%=new java.util.Date()%>

  </body>
</html>

java+jsp写循环html

2.6.3 JSP脚本片段

脚本片段用<% 代码 %>包裹

<%--
  Created by IntelliJ IDEA.
  User: pcuser
  Date: 2022/4/20
  Time: 21:26
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  $END$
<%--  JSP表带式--%>
  <%=new java.util.Date()%>
<%
  for (int i=0;i<10;i++){
    out.print(i);
  }
%>

  <%
    for (int i=0;i<10;i++){
  %>
  <%=i%>
    <h1>hello world</h1>
  <%
    }
  %>

  </body>
</html>

for (int i=0;i<10;i++){
  
      out.write('\n');
      out.write(' ');
      out.write(' ');
      out.print(i);
      out.write("\n");
      out.write("    <h1>hello world</h1>\n");
      out.write("  ");

    }

2.6.4 JSP声明

声明代码用<%!代码%>包裹

<%!
  static{
    System.out.println("Loading jsp servlet");

  }
  private int globalvar=0;
  public  void happy(){
    System.out.println("编写了方法,进入方法区的代码");
  }
%>
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {


    static{
      System.out.println("Loading jsp servlet");

    }
    private int globalvar=0;
    public  void happy(){
      System.out.println("编写了方法,进入方法区的代码");
    }
  
  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

2.6.5 JSP表达式 VS JSP脚本片段 VS JSP声明

JSP表达式 JSP脚本片段 JSP声明
代码在service中 代码在service中 代码会被放在类中

2.6.6 JSP注释 VS HTML注释

jsp的注释内容不在客户端显示,而html的注释会在客户端显示。

<!--html注释 -->
<%--jsp注释 --%>

2.7 JSP指令

基本语法:

<%@ %>

2.7.1 指定编码

<%@ page contentType>指定编码

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

2.7.2 定制错误页面

2.7.2.1 JSP <%@ page errorPage %>

定义前

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

</body>
</html>

报错页面如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page errorPage="error/500.jsp" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
  $END$
<%--  JSP表带式--%>
  <!--  html注释 -->
  <%=new java.util.Date()%>
<%
  for (int i=0;i<10;i++){
    out.print(i);
  }
%>

  <%
    for (int i=0;i<10;i++){
  %>
  ${i}
    <h1>hello world${i}</h1>
  <%
    }
  %>

  <%!
    static{
      System.out.println("Loading jsp servlet");

    }
    private int globalvar=0;
    public  void happy(){
      System.out.println("编写了方法,进入方法区的代码");
    }
  %>

  </body>
</html>

错误500自定页面如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>500自定义页面</h1>
<img src="${pageContext.request.contextPath}/img/img.png" alt="显示500图片"/>
</body>
</html>

2.7.2.2 web.xml 的error-page
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <error-page>
        <error-code>404</error-code>
<!--        第一个/代表当前项目-->
        <location>/error/404.jsp</location>
    </error-page>
    <error-page>
        <error-code>500</error-code>
        <!--        第一个/代表当前项目-->
        <location>/error/500.jsp</location>
    </error-page>

</web-app>

2.8 JSP标签

2.8.1 jsp:include

2.8.2 jsp:forward

2.8.3 jsp:param

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsptag</title>
</head>
<body>
<h1>jsptag1</h1>
<%--<jsp:param></jsp:param>相当于http://localhost:8080/jsp/jsp2.jsp?name1=happy--%>
<jsp:forward page="/jsptag2.jsp">
    <jsp:param name="name1" value="jsparam1"/>
</jsp:forward>

</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsptag2</title>
</head>
<body>
<h1>jsptag2</h1>
<hr>
request.getAttribute("name1")方式获取:
<%=request.getAttribute("name1")%>
<hr>
el表达式$name1获取:
${name1}
<hr>
request.getParameter("name1")方式获取:
<%=request.getParameter("name1")%>
<hr>
el表达式$param.name1获取:
${param.name1}
</body>
</html>

2.9 JSTL标签(标准标签库)

JSP标准标签库是一个JSP标签集合,它封装了JSP应用的通用核心功能。

JSTL支持通用的,结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。

除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。

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

根据JSTL标签提供的功能,可以将其分为5个类别:

  1. 核心标签
  2. 格式化标签
  3. SQL标签
  4. XML标签
  5. JSTL函数

2.9.1 核心标签

使用步骤
  1. 使用前,导入头文件,引入对应的taglib
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  1. 在tomcat也需要引入jstl的包,否者会报错:JSTL解析错误。
  2. 使用其中的方法
<c:if>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<form action="jsptag3.jsp" method="get">
    姓名:<input type="text" name="name" value="${param.name}">
    单位:<input type="text" name="unit" >
    <input type="submit" value="提交"></input>
</form>
<%--<% if(request.getParameter("name").equals("admin")){--%>
<%--    request.getRequestDispatcher("/success.jsp").forward(request,response);--%>
<%--}--%>
<%--%>--%>
<c:if test="${param.name=='admin'}" var="isAdmin">
    <c:out value="管理员欢迎您"></c:out>
    <%pageContext.forward("/success.jsp");%>
</c:if>
<c:out value="${isAdmin}"></c:out>

</body>
</html>

<c:choose>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<c:set var="score" value="72"></c:set>

<c:choose>
    <c:when test="${score>=90}">
        <c:out value="您的成绩为优秀"></c:out>
    </c:when>
    <c:when test="${score>=80}">
        <c:out value="您的成绩为良好"></c:out>
    </c:when>
    <c:when test="${score>=60}">
        <c:out value="您的成绩为及格"></c:out>
    </c:when>
    <c:when test="${score<60}">
        <c:out value="您的成绩为不及格"></c:out>
    </c:when>

</c:choose>
</body>
</html>

<c:forEach>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
cForEach.jsp:
<%
    ArrayList<String> peoples = new ArrayList<String>();
    peoples.add("张三");
    peoples.add("李四");
    peoples.add("王五");
    peoples.add("赵六");
    request.setAttribute("peoples",peoples);
%>
<hr>
<c:forEach var="people" items="${peoples}">
    <c:out value="${people}"></c:out>
</c:forEach>
<hr>
begin="1" end="3" step="2"
<br>
<c:forEach var="people" items="${peoples}" begin="1" end="3" step="2">
    <c:out value="${people}"></c:out>
</c:forEach>

</body>
</html>

2.10 JSP九大内置对象详解

2.10.1 9大对象比较及原理

序号 对象名 对应java对象 作用
1 request 存东西,和取封装的request请求参数。作用域介于PageContext和Session之间
2 response 返回对象
3 PageContext 存东西,作用域最小。
4 session 存东西
5 application 存东西
6 config pageContext.getServletConfig(); 获取配置文件参数
7 out
8 page
9 exception 不同于前8个对象,对用户不可见

2.10.2 域范围set和get

从底层到高层(作用域),page=》request=》session=》application

和类加载器的双亲委派机制比较:

注意:同类加载器的双亲委派机制类似,当有多个域存在同一个变量名的时候,用el表达式${}获取和findAttribute从低到高寻找,但不同的是,类加载器使用高层的,而这里使用较低层即精确的。

场景一:访问独立两个页面

1.一个页面set域:

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

    <style>
        h1,h2,h3,h4,hr{
            margin: 0;
        }
    </style>
</head>
<body>
<%--内置对象--%>
<%--方式一set--%>
<%
    //    保存的数据只在一个页面中有效
pageContext.setAttribute("name1","page域");
//    保存的数据只在一次请求中有效,请求转发会携带这个数据
request.setAttribute("name2","request域");
//    保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
session.setAttribute("name3","session域");
//    保存的数据在整个应用服务器中,从打开服务器到关闭服务器
application.setAttribute("name4","application域");
%>
<%--方式二set--%>
<%pageContext.setAttribute("var1","方式2:PAGE_SCOPE",PageContext.PAGE_SCOPE);%>
<%pageContext.setAttribute("var2","方式2:REQUEST_SCOPE",PageContext.REQUEST_SCOPE);%>
<%pageContext.setAttribute("var3","方式2:SESSION_SCOPE",PageContext.SESSION_SCOPE);%>
<%pageContext.setAttribute("var3","方式2:APPLICATION_SCOPE",PageContext.APPLICATION_SCOPE);%>

<%--故意设置个重复值 给page和application域--%>
<%--<%pageContext.setAttribute("var1","方式2:APPLICATION_SCOPE",PageContext.APPLICATION_SCOPE);%>--%>
<%
//    保存的数据只在一个页面中有效
    Object name1 = pageContext.getAttribute("name1");
    Object name2 = pageContext.getAttribute("name2");
    Object name3 = pageContext.getAttribute("name3");
    Object name4 = pageContext.getAttribute("name4");
%>

<hr/>
<h3>使用pageContext.getAttribute获取数据</h3>
<h3>默认只能获取page域的</h3>
<h4><%=name1%></h4>
<h4><%=name2%></h4>
<h4><%=name3%></h4>
<h4><%=name4%></h4>


<%
    //从底层到高层(作用域),page=》request=》session=》application
    Object name11 = pageContext.findAttribute("name1");
    Object name22 = pageContext.findAttribute("name2");
    Object name33 = pageContext.findAttribute("name3");
    Object name44 = pageContext.findAttribute("name4");
%>
<hr/>
<h3>使用pageContext.findAttribute获取数据</h3>
<h4><%=name11%></h4>
<h4><%=name22%></h4>
<h4><%=name33%></h4>
<h4><%=name44%></h4>


<hr/>
<h3>使用EL表达式$获取,相当于findAttribute获取数据</h3>
<h4>${name1}</h4>
<h4>${name2}</h4>
<h4>${name3}</h4>
<h4>${name4}</h4>
<h4>${name5}</h4>
</body>
</html>

一个页面get域:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>get</title>
</head>
<body>
<%Object name3 = session.getAttribute("name3");%>

<h3>跨页面,用el表达式获取session域里变量name3(用session设置):<br>${name3}</h3>
<hr/>
<h3>跨页面,用el表达式获取SESSION_SCOPE和APPLICATION_SCOPE域里,都有的变量var3(用pagecontext设置):<br>${var3}</h3>
</body>
</html>

效果如下:

pageContext.jsp:

get.jsp:

场景二:一个页面转发另一个页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%pageContext.setAttribute("var1","方式2:PAGE_SCOPE",PageContext.PAGE_SCOPE);%>
<%pageContext.setAttribute("var2","方式2:REQUEST_SCOPE",PageContext.REQUEST_SCOPE);%>
<%pageContext.setAttribute("var3","方式2:SESSION_SCOPE",PageContext.SESSION_SCOPE);%>
<%pageContext.setAttribute("var4","方式2:APPLICATION_SCOPE",PageContext.APPLICATION_SCOPE);%>
<%pageContext.setAttribute("var3","方式2:APPLICATION_SCOPE",PageContext.APPLICATION_SCOPE);%>
<%pageContext.forward("/forward.jsp");
//相当于以前的下面方式
//request.getRequestDispatcher("/forward.jsp").forward(request,response);
%>
</body>
</html>

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

page域:
${var1}
<hr>
request域:
${var2}
<hr>
session域:
${var3}
<hr>
application域:
${var4}
<hr>
</body>
</html>

2.11 EL表达式详解

  1. 获取数据
  2. 执行运算
  3. 获取web开发的常用对象
  4. 调用java方法

三、JavaBean

3.1 定义

实体类:

Javabean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须要有对应get/set方法

作用:一般用来和数据库的字段做映射 ORM

  • 表=》类
  • 行记录=》对象(实例)
  • 字段=》属性

3.2 JavaBean和数据库表的对应关系

people表:

id name age address
1 高兴 30 香港
2 高兴2 25 成都
3 高兴3 18 北京
Class People{
    private int id;
    private String name;
    private int age;
    private String address;
}	
posted @ 2022-04-24 08:18  高兴518  阅读(97)  评论(0)    收藏  举报