JAVAWeb(三) | JSP

JAVAWeb(三) | JSP

8. JSP

新建一个 jsp,hello.jsp,内容和 html 几乎一样,但是要处理动态页面,要请求 Servlet 类

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 目录,进入 IDEA

\to

→ Help

\to

→ Show Log in Explorer,会弹出 IDEA 的安装目录

点击进入目录下的 tomcat 目录,选择某个项目进入到如下目录:会发现 jsp 的文件就在这里(C:\Users\86182\AppData\Local\JetBrains\IntelliJIdea2023.1\tomcat)

我的目录如下:

C:\Users\15592\AppData\Local\JetBrains\IntelliJIdea2022.1\tomcat\3e92441c-ce9e-47df-b69e-9b63cc373253\work\Catalina\localhost\request\org\apache\jsp

发现页面转变成了Java 程序!

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

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

记事本点开上面的某个 jsp.java ,看一看源码,看到 index_jsp 继承了 HttpJspBase 这个父类,暂时没看到继承 Servlet

要查看 HttpJspBase 类,首先要到 maven 仓库找到 Jasper Runtime 添加 maven 依赖

tomcat

jasper-runtime

5.5.23

然后进入到 HttpJspBase 类里面发现继承了 HttpServlet JSP 本质上就是一个Servlet!

再看我们在 IDEA 中写的 index.jsp,如下:

在 index_jsp.java 中有对应的实现,如下:

因此我们在撰写 index.jsp 的时候只需要简单的撰写(如同 html 一样),内部会转换好,继续看 index_jsp.java 中的实现方法

从下面可以看出,JSP 本质上就是一个Servlet

//初始化

public void _jspInit() {

}

//销毁

public void _jspDestroy() {

}

//JSPService

public void _jspService(.HttpServletRequest request,HttpServletResponse response)

下面分析 JSP 执行过程

1. _jspService 中首先执行判断请求

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

throws java.io.IOException, javax.servlet.ServletException

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;

}

该段代码的主要目的是确保只有合法的 HTTP 请求方法(GET, POST, HEAD 或 OPTIONS)能够通过,其他方法将返回 405 错误,提示客户端不支持的请求方法。它特别适用于处理 JSP 页面请求,并为 OPTIONS 请求提供特别处理,明确指示服务器支持哪些方法。

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 //响应

applicationContext 实质上就是 servletContext

3. 输出页面前增加的代码

response.setContentType("text/html"); //设置文本响应的页面类型为 html

pageContext = _jspxFactory.getPageContext(this, request, response,

null, true, 8192, true);

_jspx_page_context = pageContext;

application = pageContext.getServletContext(); // ServletContext

config = pageContext.getServletConfig(); // Servlet 配置

session = pageContext.getSession(); // 获取 Session

out = pageContext.getOut();

_jspx_out = out;

这段代码展示了如何设置响应类型、初始化页面上下文、以及获取与 JSP 页面的执行相关的各个对象。每一行代码都在为 JSP 页面的执行做准备,确保请求被正确处理并生成适当的响应。

1. response.setContentType("text/html");

含义:设置响应的内容类型为 text/html,即告诉浏览器该响应是一个 HTML 页面。这是一个标准的 HTTP 头部,用于指示响应内容的 MIME 类型。在这里,它告诉客户端(如浏览器)返回的数据是 HTML 格式。如何使用:通常,JSP 页面在生成响应时会自动设置内容类型,但在某些情况下,也可以手动设置此内容类型。它通常在页面的开头部分调用。

2. pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);

含义:_jspxFactory.getPageContext() 方法用于创建一个 PageContext 对象。PageContext 是 JSP 页面中用于存储页面级别的信息和与请求/响应相关的对象的上下文。它是 JSP 页面的执行环境,提供了对页面范围内的各种对象(如 request、response、session、application 等)的访问。

this: 当前的 JSP 页面实例。request: HTTP 请求对象,包含来自客户端的请求信息。response: HTTP 响应对象,用于设置响应信息并返回给客户端。null: 在此处通常表示 errorPage,如果页面没有错误页处理器,则为 null。true: 表示是否自动生成错误页面。8192: 表示缓存的缓冲区大小(字节数)。true: 是否自动刷新输出流。 getPageContext() 方法会返回一个 PageContext 对象,这个对象会为 JSP 页面提供运行时环境。

3. _jspx_page_context = pageContext;

含义:将刚才获取的 pageContext 对象赋值给 _jspx_page_context(一个内部变量)。这个操作是为了让后续的代码可以使用这个 PageContext 对象来访问 JSP 的上下文信息。

4. application = pageContext.getServletContext();

含义:从 pageContext 中获取 ServletContext 对象,ServletContext 是表示整个 Web 应用的上下文。它用于提供关于 Web 应用的信息,并允许各个组件(如 Servlet 和 JSP)共享数据。

用途:你可以使用 application 对象在整个 Web 应用中存储数据(通过 setAttribute()),并可以通过 getAttribute() 获取共享的数据。

5. config = pageContext.getServletConfig();

含义:从 pageContext 获取 ServletConfig 对象,ServletConfig 是每个 Servlet(包括 JSP 页面)在启动时的配置信息。它提供了与当前 Servlet 相关的初始化参数和其他配置项。

用途:config 可以用来获取 JSP 页面或 Servlet 的初始化参数(通过 getInitParameter())。

6. session = pageContext.getSession();

含义:从 pageContext 获取 HttpSession 对象,HttpSession 用于存储与特定用户会话相关的数据。

用途:session 对象允许你存储和检索与当前会话相关的数据(例如,用户登录状态、购物车信息等)。你可以使用 session.setAttribute() 来保存会话数据,使用 session.getAttribute() 来访问数据。

7. out = pageContext.getOut();

含义:从 pageContext 获取 JspWriter 对象,JspWriter 是用于输出 HTML 内容的对象。

用途:out 用于在 JSP 页面中输出动态生成的内容。你可以使用 out.print() 或 out.println() 方法来输出 HTML 内容或其他文本到客户端浏览器。

8. _jspx_out = out;

含义:将 out 对象赋值给 _jspx_out(一个内部变量)。这个操作确保可以在后续的代码中继续使用 out 对象进行内容输出。

总结

这段代码展示了 JSP 页面底层如何设置响应类型、创建和管理页面上下文、以及获取与页面相关的各类对象(如 ServletContext、HttpSession、JspWriter 等)。这些对象在 JSP 页面的执行过程中用于与客户端和服务器进行交互。

4. 以上的这些个对象我们可以在JSP页面中直接使用!

比如页面设置

请求

Session 获取与设置

同时 JSP 内可以写 java 代码,为什么可以直接用,是因为第 3 步,输出页面前增加的代码部分已经配置好了,写 java 代码时,放入到 <% %> 中

在 JSP 页面中,内置对象如 response、application、config、session、out 和 request 可以用于多种不同的用途。以下是每个对象的多种使用示例:

1. response (HttpServletResponse)

设置内容类型:

<%

response.setContentType("text/html");

%>

设置响应头:

<%

response.setHeader("Cache-Control", "no-cache");

%>

重定向到另一个页面:

<%

response.sendRedirect("https://www.example.com");

%>

发送错误响应:

<%

response.sendError(HttpServletResponse.SC_NOT_FOUND, "Page not found");

%>

2. application (ServletContext)

设置全局属性:

<%

application.setAttribute("appVersion", "1.0.0");

%>

获取全局属性:

<%

String version = (String) application.getAttribute("appVersion");

out.println("App Version: " + version);

%>

共享数据:

<%

application.setAttribute("totalVisitors", 1000);

%>

获取应用初始化参数:

<%

String dbUrl = application.getInitParameter("databaseURL");

out.println("Database URL: " + dbUrl);

%>

3. config (ServletConfig)

获取初始化参数:

<%

String param = config.getInitParameter("maxConnections");

out.println("Max Connections: " + param);

%>

获取当前 Servlet 名称:

<%

String servletName = config.getServletName();

out.println("Servlet Name: " + servletName);

%>

4. session (HttpSession)

设置会话属性:

<%

session.setAttribute("username", "john_doe");

%>

获取会话属性:

<%

String user = (String) session.getAttribute("username");

out.println("Welcome, " + user);

%>

获取会话 ID:

<%

String sessionId = session.getId();

out.println("Session ID: " + sessionId);

%>

检查会话是否存在:

<%

if (session.isNew()) {

out.println("This is a new session.");

}

%>

5. out (JspWriter)

输出文本:

<%

out.println("Hello, JSP World!");

%>

输出 HTML 元素:

<%

out.println("

Welcome to the JSP page!

");

%>

输出 JavaScript 代码:

<%

out.println("");

%>

格式化输出:

<%

out.printf("Current time: %tT", new java.util.Date());

%>

6. request (HttpServletRequest)

获取请求参数:

<%

String name = request.getParameter("name");

out.println("Hello, " + name);

%>

获取请求头信息:

<%

String userAgent = request.getHeader("User-Agent");

out.println("User-Agent: " + userAgent);

%>

获取客户端 IP 地址:

<%

String clientIp = request.getRemoteAddr();

out.println("Client IP: " + clientIp);

%>

获取请求方法:

<%

String method = request.getMethod();

out.println("Request Method: " + method);

%>

获取请求中的属性:

<%

String attribute = (String) request.getAttribute("userRole");

out.println("User Role: " + attribute);

%>

假设我们现在新建一个 hello.jsp 内容如下,然后重启 tomcat

在启动 tomcat 还未完成的过程中,找到刚刚 IDEA 中的 tomcat 对应的项目目录下,发现之前的什么都没有了 (本来应该有:C:\Users\15592\AppData\Local\JetBrains\IntelliJIdea2022.1\tomcat\28f4f38f-a9f6-4d87-ad9e-3e377fc1b4d3\work\Catalina\localhost\ROOT\org\apache\jsp)

启动完成后才出现了 index_jsp.java

然后请求 hello.jsp,成功

刚刚的文件夹产生了 hello_jsp.java !

进入到 hello_jsp.java ,发现除了下图这里输出部分不一样,其他都一样

通过上面的流程,我们知道要去访问浏览器才会生成对应 jsp 的 java 代码!

执行流程总结: 程序员通过电脑上网,上网本质是访问服务器,服务器中存在多个 web 容器(tomcat),tomcat 可以存放很多网站,访问到 web 容器,回去判断对应的请求,如果是 JSP,会去找 JSP 的页面,找到 JSP 不能直接使用,首先需要进行转换为 JAVA 文件,这是 web 容器去做得,转换后得到 xxx_jsp.java,然后将 xxx_jsp.java 编译为 class 文件,xxx_jsp.class,xxx_jsp.class 返回给服务器,然后我们得到的就是这个服务器处理完的 xxx_jsp.class ,这个就是 Servlet!访问 JSP 本质还是 Servlet

下面我们在 hello.jsp 中撰写一段 java 代码,<%=name%> 是把 name 取出

然后重启 tomcat

此时文件夹中还没有 hello.jsp

下面请求 hello.jsp,成功取出数据

进入到 hello_jsp.java,发现 java 代码原封不动的放入了进入,并执行了 out.print(name); 输出

在JSP页面中;只要是 JAVA代码就会原封不动的输出;如果是HTML代码,就会被转换为:

out.write("\r\n");

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

8.3、JSP基础语法

先新建一个 JSP 项目

注意新项目配置 maven 仓库

pom.xml 中导入依赖,比之前多了一个 jstl-api

还需要一个 standard

javax.servlet

javax.servlet-api

4.0.1

javax.servlet.jsp

javax.servlet.jsp-api

2.3.3

javax.servlet.jsp.jstl

jstl-api

1.2

taglibs

standard

1.1.2

配置好 tomcat。

最后将原始创建的 index.jsp 删除掉,再新建一个 index.jsp,为什么这样,因为新建的 index.jsp 多了一行

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

这一行可以解决中文乱码问题,否则后续操作就会产生中文乱码现象!

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

8.3.1、JSP表达式

在 index.jsp 中添加如下代码

<%--JSP表达式

作用:用来将程序的输出,输出到客户端

<%= 变量或者表达式%>

--%>

<%= new java.util.Date()%>

在 tomcat 启动的状态下,按下 Ctrl + F10,弹出如下框,选择 Redeploy,实际上是 tomcat 的热部署,就不需要重新启动 tomcat 了

访问后就成功打印时间了!


:分割线

8.3.2、jsp脚本片段

<%--jsp脚本片段--%>

<%

int sum = 0;

for (int i = 1; i <=100 ; i++) {

sum+=i;

}

out.println("

Sum="+sum+"

");

%>

在 tomcat 启动的状态下,按下 Ctrl + F10,弹出如下框,选择 Redeploy,实际上是 tomcat 的热部署,就不需要重新启动 tomcat 了,然后刷新浏览器

下面这个情况是不被允许的,因为上面那个片段已经产生了 x 这个变量,下面就不能再定义了,但是下面那个片段可以直接使用上面定义好的。 打印输出

<%

int x = 10;

out.println(x);

%>

这是一个JSP文档

<%

int y = 2;

out.println(y);

%>


在代码嵌入HTML元素

<%--在代码嵌入HTML元素--%>

<%

for (int i = 0; i < 5; i++) {

%>

Hello,World <%=i%>

<%

}

%>

下面看一下 通过 编译产生的 xxx_ jsp.java 代码,该有的都有

8.3.3 JSP 声明: <%! %> 定义方法和全局变量

<%!

static {

System.out.println("Loading Servlet!");

}

private int globalVar = 0;

public void kuang(){

System.out.println("进入了方法Kuang!");

}

%>

JSP声明: 会被编译到JSP生成Java的类中!其他的,就会被生成到_jspService方法中!

在JSP中嵌入Java代码即可!

除了上述通过 <%=%> 取值外,还可以通过 ${} 的方式取值

<%%> 片段 <%=%> 表达式输出值 <%!%> 定义全局方法变量 <%–注释–%> 注释

JSP 中同样可以用 html 的注释,我们来看下区别

<%--我是 JSP 的注释--%>

代码中写入

热部署 tomcat,然后刷新页面,注释没有被显示出来

右击页面,查看页面源代码,能够看到 html 的注释,而看不到 jsp 的注释 JSP的注释,不会在客户端显示,HTML就会!

下面新建 jsp2,输入一个除 0 错误,

热部署 tomcat,并访问 jsp2.jsp,报错异常

下面有这样一个需求:当发生如下错误时,不弹出如上的页面,而是弹出我们指定的页面

额外tips:JSP 也支持像 java import 那样导包,比如如下

新建文件夹 error,新建 500.jsp,并放入如下内容:

然后在 jsp2.jsp 中添加错误跳转操作:<%@ page errorPage="error/500.jsp" %>

热部署 tomcat,请求 jsp2.jsp,跳转到了我们自定义的界面

下面不显示字,跳转后显示图片,新建 img,随便放入一张图,更改 jsp2.jsp 的内容:500

热部署 tomcat,请求 jsp2.jsp,跳转到了我们定义好了图片的界面。注意如果代码没有错是不会跳的

上面是 500 错误,可能还会有 404 错误,erro 文件夹中增加 404.jsp,如下内容

然后配置 web.xml,配置信息表示出那种错误,对应去找到对应的 jsp

404

/error/404.jsp

500

/error/500.jsp

热部署 tomcat,请求 jsp2.jsp,正常显示之前的信息,然后输入一个肯定不存在的页面,回车

进入了 404 错误页面

错误跳转:

404

/error/404.jsp

500

/error/500.jsp

<%@ page errorPage="error/500.jsp" %>

这两种方式都用于处理 JSP 页面中的错误,但它们在应用范围和使用场景上有所不同。下面是两者的对比和详细解释:

1. 配置(在 web.xml 中)

这是在 web.xml 配置文件中为 HTTP 错误代码设置错误页面的方式。它是 Web 应用级别的配置,适用于整个应用中的所有请求,而不仅仅是某个特定的 JSP 页面。

示例:

404

/error/404.jsp

500

/error/500.jsp

解释:

配置指示当服务器发生特定的 HTTP 错误时(如 404 或 500),应该跳转到哪个错误页面。:指定捕获的错误代码(如 404 或 500)。:指定错误页面的 URL,当发生指定的错误时,用户会被重定向到该页面。

使用场景:

全局配置:它适用于整个 Web 应用。当某个特定错误(如 404 或 500)发生时,无论是来自哪个 Servlet 或 JSP 页面,都会跳转到指定的错误页面。适用 HTTP 错误:此配置捕获的是 HTTP 错误(如 404、500、403 等)并将其重定向到自定义页面。

示例:

当用户访问不存在的页面时(如 /nonexistent.jsp),Web 容器会返回 404 错误并重定向到 /error/404.jsp 页面。当服务器发生内部错误时(如空指针异常),Web 容器会返回 500 错误并重定向到 /error/500.jsp 页面。

2. <%@ page errorPage="error/500.jsp" %> 配置(JSP 指令)

这是在 JSP 页面中指定错误处理页面的方式。它用于在当前 JSP 页面发生异常时,转向指定的错误页面。

示例:

<%@ page errorPage="error/500.jsp" %>

解释:

errorPage 指令用于指定当当前 JSP 页面抛出异常时,转向哪个错误页面。在当前页面发生未捕获的异常时,JSP 容器会自动将用户重定向到指定的错误页面。

使用场景:

局部配置:它仅适用于当前的 JSP 页面。只有在该页面内部发生异常时,才会跳转到指定的错误页面。适用 JSP 内部错误:它只捕获 JSP 页面内抛出的异常,而不会捕获 HTTP 错误或其他类型的错误。

示例:

如果在 index.jsp 页面中发生了未处理的异常(如 NullPointerException),并且该页面配置了 errorPage 指令,用户会被重定向到 error/500.jsp 页面。

3. 对比: 配置 vs <%@ page errorPage="..." %> 指令

特性 配置 (web.xml)<%@ page errorPage="..." %> 指令作用范围Web 应用级别,全局配置单个 JSP 页面捕获类型HTTP 错误(如 404、500 等)JSP 页面内抛出的异常(如 NullPointerException 等)配置位置web.xml 配置文件JSP 页面顶部的指令错误处理处理所有请求中的 HTTP 错误仅处理当前 JSP 页面中的异常适用场景用于 HTTP 错误(如 404、500)用于 JSP 页面内的异常处理(如编程错误、空指针等)错误页面可以为不同的错误代码配置不同的错误页面仅为该 JSP 页面配置一个错误页面

4. 总结

配置 是全局配置,适用于整个 Web 应用,捕获 HTTP 错误(如 404、500)并重定向到指定的错误页面。它位于 web.xml 文件中,并且不依赖于单个 JSP 页面。

<%@ page errorPage="..." %> 指令 是局部配置,仅在当前 JSP 页面中适用。它捕获该页面内的异常,并跳转到指定的错误页面,通常用于处理编程错误或其他运行时异常。

因此:

如果你需要处理 HTTP 错误(例如页面未找到、服务器内部错误等),可以使用 web.xml 中的 配置。如果你只需要处理单个 JSP 页面内的异常,应该使用 <%@ page errorPage="..." %> 指令。

8.4、JSP指令(了解即可,重点是上面基础语法部分)

<%@page args.... %>

<%@include file=""%>

<%--@include会将两个页面合二为一--%>

<%@include file="common/header.jsp"%>

网页主体

<%@include file="common/footer.jsp"%>


<%--jSP标签

jsp:include:拼接页面,本质还是三个

--%>

网页主体

<%@include file=""%>,包含其他的 jsp 文件进来,比如在 common 文件夹下定义 header.jsp 和 footer.jsp,然后最外层文件夹创建一个 jsp3.jsp 为主页面,并调用 header.jsp 和 footer.jsp

jsp3.jsp 页面内容如下

热部署 tomcat,请求 jsp3.jsp

如何直接访问 header 页面,通过项目下完整的目录:localhost:8080/common/header.jsp

下面使用 jsp 标签

<%--jSP标签

jsp:include:拼接页面,本质还是三个

--%>

网页主体

同样达到了上面的效果

下面看一下两者的区别,进入到 jsp3_jsp.java 的代码当中。

先看如下代码情况:

网页主体

相当于拼接页面,本质还是三个(推荐使用的方式)

下面这种情况

<%@include file="common/header.jsp"%>

网页主体

<%@include file="common/footer.jsp"%>

将其他两个 jsp 中的内容一起放入到了 jsp3.jsp 当中!,使其合二为一了

合二为一会出现一个问题,比如在 header.jsp 中我定义了一个 int i,然后在主页面 jsp3.jsp 中,我先引入 header.jsp ,然后又定义了一个 int i,请求的时候就会报 500 的错!

main 下面就只放 java 和 resources 文件夹,不要存放其他任何文件夹

8.5、9 大内置对象

PageContext 代表一个页面,存东西Request 存东西ResponseSession 存东西Application 【SerlvetContext】 存东西config 【SerlvetConfig】 配置out 输出page ,不用了解exception

新建一个 pageContextDemo01.jsp,放入以下内容,实现存东西

脚本片段 <% %> 中的代码,会原封不动的生成到 JSP.java 中,这里面的代码必须保证 java 语法的正确性!即不能出现 JSP 类型的注释,如:<%--取出保存的值--%>

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

Title

<%--内置对象--%>

<%--从底层到高层作用于:page -> request -> session -> application,application--%>

<%

pageContext.setAttribute("name1","future1号"); //保存的数据只在一个页面中有效

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

session.setAttribute("name3","future3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器

application.setAttribute("name4","future4号"); //保存的数据只在服务器中有效,从打开服务器到关闭服务器

%>

<%--取出保存的值--%>

<%

String name1 = (String) pageContext.getAttribute("name1");

String name2 = (String) request.getAttribute("name2");

String name3 = (String) session.getAttribute("name3");

String name4 = (String) application.getAttribute("name4");

String name5 = (String) application.getAttribute("name5"); // 不存在

%>

<%--使用 EL 表达式输出--%>

取出的值为:

${name1}

${name2}

${name3}

<%=name4%>

<%=name5%>

热部署 tomcat,请求 pageContextDemo01.jsp,不存在的值打印出了 null(因为使用 <%=name5%> 取值),如果使用 ${name5},会自动过滤,不会打印出任何东西

现有三个 page,三个 Servlet 请求:s1, s2, s3,三个 page 是三个不一样的浏览器,但是现在想存东西。下面有几种方法,首先是 request 作用域:比如第一个 page 请求 s1,携带了一个 name 数据,如果 s1 不转发,这个数据就不会存在了,但是可以通过转发,比如 s1 转发到 s2,s2 就拿到了这个数据

可以在服务器中存数据(session),三个浏览器 page,会产生三个 sesison,每个浏览器对应一个 session,但是无论是在 session 几存东西,所有 page 都可以拿到 session 1, 2, 3 的数据,因为数据是在服务器上的。

从底层到高层作用于:page -> request -> session -> application,application 都没找到,就不存在了,JVM 有一个双亲委派机制,也是逐渐找包的过程

pageContextDemo01.jsp 代码以及内容如下

<%--

Created by IntelliJ IDEA.

User: 15592

Date: 2024/7/28

Time: 20:37

To change this template use File | Settings | File Templates.

--%>

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

Title

<%--内置对象--%>

<%

pageContext.setAttribute("name1","future1号"); //保存的数据只在一个页面中有效

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

session.setAttribute("name3","future3号"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器

application.setAttribute("name4","future4号"); //保存的数据只在服务器中有效,从打开服务器到关闭服务器

%>

<%--取出保存的值--%>

<%

String name1 = (String) pageContext.getAttribute("name1");

String name2 = (String) request.getAttribute("name2");

String name3 = (String) session.getAttribute("name3");

String name4 = (String) application.getAttribute("name4");

String name5 = (String) application.getAttribute("name5"); // 不存在

%>

<%--使用 EL 表达式输出--%>

取出的值为:

${name1}

${name2}

${name3}

<%=name4%>

<%=name5%>

下面新建 pageDemo02.jsp,内容如下:(相当于只保留了 pageContextDemo01.jsp 中取值的部分)

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

Title

<%--取出保存的值--%>

<%

String name1 = (String) pageContext.getAttribute("name1");

String name2 = (String) request.getAttribute("name2");

String name3 = (String) session.getAttribute("name3");

String name4 = (String) application.getAttribute("name4");

String name5 = (String) application.getAttribute("name5"); // 不存在

%>

<%--使用 EL 表达式输出--%>

取出的值为:

${name1}

${name2}

${name3}

<%=name4%>

<%=name5%>

上述两个 pageDemo02 ,pageContextDemo01 是完全不同的页面,热部署 tomcat 后,先请求 pageContextDemo01 再请求 pageDemo02

发现只能取出 3 号,4 号,1, 2 号没有了,因为 3 4 号是用 session 和 application,1,2 号是使用 pageContext 和 request。

新建一个 pageDemo03.jsp ,找到 pageContext.setAttribute 的实现

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

Title

<%--

public static final int PAGE_SCOPE = 1;

public static final int REQUEST_SCOPE = 2;

public static final int SESSION_SCOPE = 3;

public static final int APPLICATION_SCOPE = 4;

// scope 作用域

public void setAttribute(String name, Object attribute, int scope) {

switch (scope) {

case 1:

this.mPage.put(name, attribute);

break;

case 2:

this.mRequest.put(name, attribute);

break;

case 3:

this.mSession.put(name, attribute);

break;

case 4:

this.mApp.put(name, attribute);

break;

default:

throw new IllegalArgumentException("Bad scope " + scope);

}

}

--%>

<%

pageContext.setAttribute("hello1", "hello", PageContext.SESSION_SCOPE);

session.setAttribute("hello1", "hello");

%>

PageContext 类下有如下的 scope,用于设置作用域,默认是在当前页面有效,pageContext.setAttribute(“hello1”, “hello”, PageContext.SESSION_SCOPE); 等价于 session.setAttribute(“hello1”, “hello”); 提高到了 session 作用域下

public static final int PAGE_SCOPE = 1;

public static final int REQUEST_SCOPE = 2;

public static final int SESSION_SCOPE = 3;

public static final int APPLICATION_SCOPE = 4;

新建 pageContextDemo02.jsp,内容如下,实现跳转,下面两种跳转方式等价

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

Title

<%

pageContext.forward("/index.jsp"); // 页面端跳转

// request.getRequestDispatcher("/index.jsp").forward(request,response); // servlet 后台跳转

%>

成功跳转

request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!

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

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

pageContext.forward("/index.jsp"); 这种类型实际上就是实现了请求转发,这样 request 携带的内容可以在转发的页面中读取到

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

EL表达式: ${ }

获取数据执行运算获取web开发的常用对象

使用需要导入依赖

javax.servlet.jsp.jstl

jstl-api

1.2

taglibs

standard

1.1.2

JSP标签部分使用:

新建 jsptag.jsp ,内容如下:(通过 JSP 标签,跳转页面到)

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

Title

新建 jsptag2.jsp ,内容如下:

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

Title

这是一个 JSPtag2 页面

热部署 tomcat,请求 jsptag.jsp,跳转成功

重写 jsptag.jsp 如下:(使其转发时携带参数)

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

Title

测试 jsptag2.jsp 取出参数

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

Title

名字: <%=request.getParameter("name")%>

年龄: <%=request.getParameter("age")%>

热部署 tomcat,请求 jsptag,获取成功

前面还讲了一个 标签,这里不再赘述

JSTL表达式

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

格式化标签(基本不用)

SQL标签(基本不用)

XML 标签(基本不用)

核心标签 (掌握部分)

上述的代码不需要记忆,查找即可,查找地址: https://www.runoob.com/jsp/jsp-jstl.html

JSTL 可以不使用,写 java 代码一样的可以!

JSTL 标签库使用步骤

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

c:if

if 测试,新建一个 coreif.jsp,内容如下:

表示自己请求自己,然后 get 获取自己的表单

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

<%--引入 JSTL 核心标签库,我们才能使用 JSTL 标签--%>

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

Title

if测试


<%--

EL表达式获取表单中的数据:${param.参数名}

--%>

由于 tomcat 中没有 jstl 和 standard 的包,要手动粘贴到 tomcat 的 lib 文件夹下

加入包后重新启动 tomcat,请求 coreif.jsp

继续用 coreif.jsp 下执行 if 条件命令,如果用户名输入成功则返回 true,否则返回 false

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

<%--引入 JSTL 核心标签库,我们才能使用 JSTL 标签--%>

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

Title

if测试


<%----%>

<%--

EL表达式获取表单中的数据

${param.参数名}

--%>

<%--判断如果提交的用户名是管理员,则登录成功--%>

<%-- 这个过程会获取到 isAdmin 为 true or false --%>

<%--自闭合标签--%>

<%-- 输出上述的登录状态 --%>

c:choose、c:when

新建一个 corewhen.jsp ,内容如下

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

Title

<%--定义一个变量score,值为85--%>

你的成绩为优秀

你的成绩为一般

你的成绩为良好

你的成绩为不及格

不知道啥情况

c:forEach

<%

ArrayList people = new ArrayList<>();

people.add(0,"张三");

people.add(1,"李四");

people.add(2,"王五");

people.add(3,"赵六");

people.add(4,"田六");

request.setAttribute("list",people);

%>

<%--

var , 每一次遍历出来的变量

items, 要遍历的对象

begin, 哪里开始

end, 到哪里

step, 步长

--%>




相关推荐

公司简介

公司简介

08-23 👁 5330
海燕直播观看,修身养性!文班亚马在少林寺的一天,是怎么度过的?
一生颠沛流离,拍拍网无奈退场的背后