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 依赖
然后进入到 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
配置好 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 的内容:
热部署 tomcat,请求 jsp2.jsp,跳转到了我们定义好了图片的界面。注意如果代码没有错是不会跳的
上面是 500 错误,可能还会有 404 错误,erro 文件夹中增加 404.jsp,如下内容
然后配置 web.xml,配置信息表示出那种错误,对应去找到对应的 jsp
热部署 tomcat,请求 jsp2.jsp,正常显示之前的信息,然后输入一个肯定不存在的页面,回车
进入了 404 错误页面
错误跳转:
与
<%@ page errorPage="error/500.jsp" %>
这两种方式都用于处理 JSP 页面中的错误,但它们在应用范围和使用场景上有所不同。下面是两者的对比和详细解释:
1.
这是在 web.xml 配置文件中为 HTTP 错误代码设置错误页面的方式。它是 Web 应用级别的配置,适用于整个应用中的所有请求,而不仅仅是某个特定的 JSP 页面。
示例:
解释:
使用场景:
全局配置:它适用于整个 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. 对比:
特性
4. 总结
<%@ page errorPage="..." %> 指令 是局部配置,仅在当前 JSP 页面中适用。它捕获该页面内的异常,并跳转到指定的错误页面,通常用于处理编程错误或其他运行时异常。
因此:
如果你需要处理 HTTP 错误(例如页面未找到、服务器内部错误等),可以使用 web.xml 中的
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" %>
<%--内置对象--%>
<%--从底层到高层作用于: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" %>
<%--内置对象--%>
<%
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" %>
<%--取出保存的值--%>
<%
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" %>
<%--
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" %>
<%
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开发的常用对象
使用需要导入依赖
JSP标签部分使用:
新建 jsptag.jsp ,内容如下:(通过 JSP 标签,跳转页面到)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
新建 jsptag2.jsp ,内容如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
这是一个 JSPtag2 页面
热部署 tomcat,请求 jsptag.jsp,跳转成功
重写 jsptag.jsp 如下:(使其转发时携带参数)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
测试 jsptag2.jsp 取出参数
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
名字: <%=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,内容如下:
由于 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" %>
if测试
<%----%>
<%--判断如果提交的用户名是管理员,则登录成功--%>
<%--自闭合标签--%>
c:choose、c:when
新建一个 corewhen.jsp ,内容如下
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--定义一个变量score,值为85--%>
你的成绩为优秀
你的成绩为一般
你的成绩为良好
你的成绩为不及格
不知道啥情况
c:forEach
<%
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, 步长
--%>