JSP、EL 表达式、JSTL
JSP 介绍
JSP 简介
JSP 全称是 Java Server Page,它和 Servlet 一样,也是 Sun 公司推出的一套开发动态 web 资源的技术,称为 JSP/Servlet 规范。
JSP 的本质其实就是一个 Servlet。
JSP 与 Servlet 的区别
-
JSP 经编译后就变成了 Servlet(JSP 的本质就是 Servlet,JVM 只能识别 Java 的类,不能识别 JSP 的代码,于是 Web 容器将 JSP 的代码编译成 JVM 能够识别的 Java类)。
-
Servlet 和 JSP 最主要的不同点在于:Servlet 的应用逻辑在 Java 文件中,并且完全从表示层中的 HTML 里分离开来。而对于 JSP,Java 和 HTML 可以组合成一个扩展名为 .jsp 的文件。
-
JSP 是 Servlet 的一种简化,使用 JSP 只需要完成输出到客户端的内容(JSP 中的 Java 脚本如何镶嵌到一个类中,由 JSP 容器完成);而 Servlet 则是个完整的 Java 类,这个类的 service() 方法用于生成对客户端的响应。
-
JSP 更擅长于页面显示(视图),Servlet 更擅长于逻辑控制。
-
Servlet 中没有内置对象,JSP 中的内置对象都必须通过 HttpServletRequest 对象、 HttpServletResponse 对象以及 HttpServlet 对象得到。
JSP、HTML、Servlet 适用场景
类别 | 适用场景 |
---|---|
HTML | 只能开发静态资源,不能包含 java 代码,无法添加动态数据。 |
Servlet | 写 java 代码,可以输出页面内容,但是不够方便,开发效率低。 |
JSP | 包括了 HTML 的展示技术,同时具备 Servlet 输出动态资源的能力;但是不适合作为控制器来用。 |
JSP 简单入门
1. 创建 JavaWeb 工程:
2. 在 index.jsp 中编写内容:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP的入门</title>
</head>
<body>
这是第一个JSP页面
</body>
</html>
3. 测试运行:
JSP 执行详解
JSP 就是一个特殊的 Servlet,其执行过程如下:
- 客户端提交请求;
- Tomcat 服务器解析请求地址;
- 找到 JSP 页面;
- Tomcat 将 JSP 页面翻译成 Servlet 的 java 文件;
- 将翻译好的 .java 文件编译成 .class 文件;
- 返回到客户端浏览器上。
JSP 的 .java 文件内容分析:
当我们打开 index.jsp 翻译的 java 文件看到的就是public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
类的声明,接着我们在 Tomcat 的源码中找到该类的声明,如下图:
该图表明我们写的 JSP 的本质就是一个 HttpServlet。
同时,我们在 index_jsp.java 文件中找到了输出页面的代码,并且在浏览器端查看源文件,看到的内容是一样的。这也就是说明,我们的浏览器上的内容,在通过 JSP 展示时,本质都是用 out.write() 输出出来的。
至此,我们应该清楚地认识到,JSP 是一个特殊的 Servlet,主要是用于展示动态数据
。它展示的方式是用流把数据输出。而我们在使用 JSP 时,涉及的 HTML 部分,都与 HTML 的用法一致,这部分称为 JSP 中的模板元素,在开发过程中,先写好这些模板元素,因为它们决定了页面的外观。
JSP 语法
1)Java 代码块
在 JSP 中,可以使用 java 脚本代码,形式为:<% 此处写java代码 %>
。
但是在实际开发中,极少使用此种形式编写 java 代码。同时需要注意的是:
<%
在里面写java程序脚本,需要注意:这里面的内容由tomcat负责翻译,翻译之后是service方法的成员变量
%>
示例:
<!--Java代码块-->
<% out.println("这是Java代码块");%>
<hr/>
2)JSP 表达式
在 JSP 中,可以使用特定表达式语法,形式为:<%=表达式%>
。
JSP 在翻译完后是out.print(表达式内容);
,所以<%out.print("当前时间);%>
和<%="当前时间"%>
是等价的。
在实际开发中,这种表达式语法用的也很少。
示例:
<!--JSP表达式-->
<%="这是JSP表达式"%><br/>
就相当于<br/>
<%out.println("这是没有JSP表达式输出的");%>
3)JSP 声明
在 JSP 中也可以声明一些变量、方法、静态方法,形式为:<%! 声明的内容 %>
。
使用 JSP 声明时需要注意:
<%!
需要注意的是:写在里面的内容将会被tomcat翻译成全局的属性或者类方法
%>
示例:
<!--JSP声明-->
<%! String str = "声明语法格式";%>
<%=str%>
4)JSP 注释
在使用 JSP 时,它也有自己的注释,形式为:<%--注释--%>
。
需要注意的是:
-
在 JSP 中可以使用 HTML 的注释,但是只能注释 HTML 元素,不能注释 Java 程序片段和表达式。同时,被 HTML 注释部分会参与翻译,并且会在浏览器上显示。
-
JSP 的注释不仅可以注释 Java 程序片段,也可以注释 HTML 元素,并且被 JSP 注释的部分不会参与翻译成 .java 文件,也不会在浏览器上显示。
示例:
<%--JSP注释--%>
<!--HTML注释-->
5)语法示例
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>JSP语法</title>
</head>
<body>
<!--Java代码块-->
<% out.println("这是Java代码块");%>
<hr/>
<!--JSP表达式-->
<%="这是JSP表达式"%><br/>
就相当于<br/>
<%out.println("这是没有JSP表达式输出的");%>
<hr/>
<!--JSP声明-->
<%! String str = "声明语法格式";%>
<%=str%>
<hr/>
<%--JSP注释--%>
<!--HTML注释-->
</body>
</html>
JSP 语法运行结果:
JSP 指令
1)page 指令
language
:告知引擎,脚本使用的是 Java。默认是 Java,不写也行。
extends
:告知引擎,JSP 对应的 Servlet 的父类是哪个,不需要写,也不需要改。
import
:告知引擎,导入哪些包(类)。
注意:引擎会自动导入:java.lang.*, javax.servlet.*, javax.servlet.http.*, javax.servlet.jsp.*
导入的语法:
<%@pageimport=”java.util.Date, java.util.UUID”%>
或者:
<%@pageimport=”java.util.Date”%>
<%@pageimport=”java.util.UUID”%>
Eclipse 自动导入:Alt + /
session
:告知引擎是否产生 HttpSession 对象,即是否在代码中调用 request.getSession()。默认是 true。
buffer
:JspWriter 用于输出 JSP 内容到页面上。告知引擎,设定他的缓存大小。默认 8kb。
errorPage
:告知引擎,当前页面出现异常后,应该转发到哪个页面上(路径写法:/代表当前应用)。
- 当在 errorPage 上使用了 isErrorPage=true 之后,IE8 有时候不能正常显示。
- 配置全局错误页面:web.xml。
- 当使用了全局错误页面,就无须再写 errorPage 来实现转到错误页面,而是由服务器负责跳转到错误页面。
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>
isErrorPage
:告知引擎,是否抓住异常。如果该属性为 true,页面中就可以使用 exception 对象,打印异常的详细信息。默认值是 false。
contentType
:告知引擎,响应正文的 MIME 类型。
- contentType="text/html;charset=UTF-8" 相当于 response.setContentType("text/html;charset=UTF-8");
pageEncoding
:告知引擎,翻译 JSP 时(从磁盘上读取 JSP 文件)所用的码表。
- pageEncoding="UTF-8" 相当于告知引擎用 UTF-8 读取 JSP 。
isELIgnored
:告知引擎,是否忽略 EL 表达式,默认值是 false,不忽略。
2)include 指令
语法:<%@include file="" %>
,该指令表示包含外部页面。
- file 属性以
/
开头,表示当前应用。
使用示例:
静态包含 .java 文件内容:
3)taglib 指令
语法:<%taglib uri="" prefix=""%>
作用:该指令用于引入外部标签库(html 标签和 jsp 标签无需引入)。
属性:
- uri:外部标签的 URI 地址。
- prefix:使用标签时的前缀。
JSP 对象
九大隐式对象
什么是隐式对象呢?它指的是在 JSP 中,可以不声明就直接使用的对象。它只存在于 JSP 中,因为 Java 类中的变量必须要先声明再使用。
其实 JSP 中的隐式对象也并非是未声明,只是它是在翻译成 .java 文件时声明的,所以我们可以在 JSP 中直接使用。
隐式对象名称 | 类型 | 备注 |
---|---|---|
request | javax.servlet.http.HttpServletRequest | |
response | javax.servlet.http.HttpServletResponse | |
session | javax.servlet.http.HttpSession | page 指令可以控制开关 |
application | javax.servlet.ServletContext | |
page | Java.lang.Object | 当前 JSP 对应的 servlet 引用实例 |
config | javax.servlet.ServletConfig | |
exception | java.lang.Throwable | page 指令可以控制开关 |
out | javax.servlet.jsp.JspWriter | 字符输出流,相当于 printwriter |
pageContext | javax.servlet.jsp.PageContext | 重要 |
ageContext 对象
简介:
它是 JSP 独有的对象,Servlet 中没有这个对象。
ageContext 本身也是一个域(作用范围)对象,但是它可以操作其他 3 个域对象中的属性,而且还可以获取其他 8 个隐式对象。
生命周期:
它是一个局部变量,所以它的生命周期随着 JSP 的创建而开始,随着 JSP 的结束而消失。每个 JSP 页面都有一个独立的 PageContext。
常用方法:
四大域对象
域对象名称 | 范围 | 级别 | 备注 |
---|---|---|---|
PageContext | 页面范围 | 最小,只能在当前页面用 | 因范围太小,开发使用较少 |
ServletRequest | 请求范围 | 一次请求或当前请求转发用 | 当请求转发之后,再次转发时请求域丢失。开发使用较多 |
HttpSession | 会话范围 | 多次请求数据共享时使用 | 多次请求共享数据,但不同的客户端不能共享。。如存放用户的登录信息、购物车功能。开发使用较多 |
ServletContext | 应用范围 | 最大,整个应用都可以使用 | 因范围太大,尽量少用。如果对数据有修改则需要做同步处理 |
JSP 最佳使用场景:MVC 模型
MVC 模型:
-
M(model,模型)
:通常用于封装数据模型(实体类)。 -
V(view,视图)
:通常用于展示数据。动态展示用 JSP 页面,静态数据展示用 HTML。- JSP 擅长显示界面,不擅长处理程序逻辑。在 Web 开发中多用于展示动态界面。
-
C(controller,控制器)
:通常用于处理请求和响应。一般指的是 Servlet。- Servlet 擅长处理业务逻辑,不擅长输出显示界面。在 Web 开发中多用于控制程序逻辑(流程)。
JSP 综合案例
1)登录功能
index.jsp:主页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
</head>
<body>
<%--
获取会话域的数据
如果获取到了,则显示添加和查询功能
如果获取不到,则显示登录功能
--%>
<% Object username = session.getAttribute("username");
if(username == null || "".equals(username)){
%>
<a href="/web_demo/login.jsp">登录<a/>
<%}else { %>
<a href="/web_demo/add.jsp">添加<a/>
<a href="/web_demo/queryServlet">查询<a/>
<% } %>
</body>
</html>
login.jsp:登录页
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>登录页</title>
</head>
<body>
<form action="/web_demo/loginServlet" method="get" autocomplete="off">
姓名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<button type="submit">登录</button>
</form>
</body>
</html>
LoginServlet:获取登录页的用户名和密码
package com.demo;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取用户名和密码
String username = req.getParameter("username");
String password = req.getParameter("password");
// 校验用户名密码
// 用户名为空
if("".equals(username) || username == null){
// 重定向到登录页
resp.sendRedirect("/web_demo/login.jsp");
} else {
// 用户名不为空,存入会话域数据
req.getSession().setAttribute("username", username);
// 重定向到首页
resp.sendRedirect("/web_demo/index.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
2)添加功能
add.jsp:实现添加学生信息的表单项
<%--
Created by IntelliJ IDEA.
User: juno
Date: 2021/10/7
Time: 21:18
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>添加页</title>
</head>
<body>
<form action="/web_demo/addServlet" method="get" autocomplete="off">
学生姓名:<input type="text" name="username"><br/>
学生年龄:<input type="number" name="age"><br/>
学生成绩:<input type="number" name="score"><br/>
<button type="submit">保存</button>
</form>
</body>
</html>
AddServlet:获取学生信息并保存到文件中
package com.demo;
import com.demo.bean.Student;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取表单数据
String username = req.getParameter("username");
String age = req.getParameter("age");
String score = req.getParameter("score");
// 创建学生对象并赋值
Student student = new Student();
student.setAge(age);
student.setScore(score);
student.setUsername(username);
// 将新增数据写入文件中
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("d://student.txt", true));
bufferedWriter.write(username+","+age+","+score);
bufferedWriter.newLine();
bufferedWriter.close();
// 通过定时刷新功能响应给浏览器
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("添加成功!2秒后自动跳转到首页~");
resp.setHeader("Refresh", "2;URL=/web_demo/index.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
3)查看功能
QueryServlet:读取文件中的学生信息到集合中
package com.demo;
import com.demo.bean.Student;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
@WebServlet("/queryServlet")
public class QueryServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建字符输入流对象,关联读取的文件
BufferedReader bufferedReader = new BufferedReader(new FileReader("d://student.txt"));
// 创建集合对象,用于保存student对象
ArrayList<Student> arrayList = new ArrayList<>();
// 循环读取文件中的数据,将数据封装到Student对象中。再把多个学生对象添加到集合中
String line;
while((line = bufferedReader.readLine()) != null){
Student student = new Student();
String[] attribute = line.split(",");
student.setUsername(attribute[0]);
student.setAge(attribute[1]);
student.setScore(attribute[2]);
arrayList.add(student);
}
// 将集合对象存入会话域中
req.getSession().setAttribute("students", arrayList);
// 重定向到学生列表页面
resp.sendRedirect("/web_demo/query.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
query.jsp:展示学生信息列表
<%--
Created by IntelliJ IDEA.
User: juno
Date: 2021/10/7
Time: 23:41
To change this template use File | Settings | File Templates.
--%>
<%@ page import="com.demo.bean.Student" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>学生列表页</title>
</head>
<body>
<table width="600px" border="1px">
<tr>
<th>学生姓名</th>
<th>学生年龄</th>
<th>学生成绩</th>
</tr>
<% ArrayList<Student> students = (ArrayList<Student>) session.getAttribute("students");
for(Student student: students){
%>
<tr align="center">
<td><%= student.getUsername() %></td>
<td><%= student.getAge() %></td>
<td><%= student.getScore() %></td>
<tr/>
<% } %>
</table>
</body>
</html>
页面效果如下:
EL 表达式
EL 表达式介绍
基本概念:
EL 表达式,全称是 Expression Language,意为表达式语言。它是 Servlet 规范中的一部分,是 JSP2.0 规范加入的内容。
其作用是用于在 JSP 页面中获取数据,从而让我们的 JSP 脱离 Java 代码块和 JSP 表达式。
基本语法:
EL 表达式的语法格式非常简单:${表达式内容}
。
假定我们在请求域中存入了一个名称为 "message" 的数据,此时在 JSP 中获取的方式如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式入门案例</title>
</head>
<body>
<%--使用java代码在请求域中存入一个名称为message的数据--%>
<% request.setAttribute("message","Expression Language"); %>
Java代码块获取:<% out.print(request.getAttribute("message")); %>
<br/>
JSP表达式获取:<%= request.getAttribute("message") %>
<br/>
EL表达式获取:${message}
</body>
</html>
可以看出,有多种方式可以从请求域中获取数据,但是 EL 表达式写起来是最简单的方式。这也是以后我们在实际开发中,当使用 JSP 作为视图时,绝大多数都会采用的方式。
EL 表达式注意事项
EL 表达式没有空指针异常、没有数组下标越界、没有字符串拼接。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式的注意事项</title>
</head>
<body>
<%-- EL表达式的三个没有 --%>
第一个:没有空指针异常<br/>
<% String str = null;
request.setAttribute("testNull",str);
%>
${testNull}
<hr/>
第二个:没有数组下标越界<br/>
<% String[] strs = new String[]{"a","b","c"};
request.setAttribute("strs",strs);
%>
取第一个元素:${strs[0]}<br/>
取第六个元素:${strs[5]}
<hr/>
第三个:没有字符串拼接<br/>
<%--${strs[0]+strs[1]}--%>
${strs[0]}+${strs[1]}
</body>
</html>
运行效果:
EL 表达式的数据来源
EL 表达式只能从四大域中获取数据,调用的就是findAttribute(name,value);
方法,通过名称根据范围由小到大逐个域中查找,找到就返回,找不到就什么都不显示。
它可以获取对象,可以是对象中关联的其他对象,可以是一个 List 集合,也可以是一个 Map 集合。
使用:创建两个实体类(User 和 Address)并使用 EL 表达式获取输出
- User 实体类:
public class User implements Serializable{
private String name = "黑马";
private int age = 18;
private Address address = new Address();
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;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
- Address 实体类:
public class Address implements Serializable {
private String province = "北京";
private String city = "昌平区";
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
- JSP:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="com.itheima.domain.User" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>EL入门</title>
</head>
<body>
<%--
EL表达式的数据获取:
它只能在四大域对象中获取数据,不在四大域对象中的数据它取不到。
它的获取方式就是findAttribute(String name)
--%>
<br/>-----------获取对象数据---------------------<br/>
<% //1.把用户信息存入域中
User user = new User();
pageContext.setAttribute("u", user);
%>
${u}===============输出的是内存地址 <%--相当于调用 <%=pageContext.findAttribute("u")%> --%><br/>
${u.name} <%--相当于调用 <% User user = (User) pageContext.findAttribute("u");out.print(user.getName());%> --%><br/>
${u.age}
<br/>-----------获取关联对象数据------------------<br/>
${u.address}==========输出的address对象的地址<br/>
${u.address.province}${u.address.city}<br/>
${u["address"]['province']}
<br/>-----------获取数组数据---------------------<br/>
<% String[] strs = new String[]{"He", "llo", "Expression", "Language"};
pageContext.setAttribute("strs", strs);
%>
${strs[0]}==========取的数组中下标为0的元素<br/>
${strs[3]}
${strs[5]}===========如果超过了数组的下标,则什么都不显示<br/>
${strs["2"]}=========会自动为我们转换成下标<br/>
${strs['1']}
<br/>-----------获取List集合数据-----------------<br/>
<% List<String> list = new ArrayList<String>();
list.add("AAA");
list.add("BBB");
list.add("CCC");
list.add("DDD");
pageContext.setAttribute("list", list);
%>
${list}<br/>
${list[0]}<br/>
${list[3]}<br/>
<br/>-----------获取Map集合数据------------------<br/>
<% Map<String,User> map = new HashMap<String,User>();
map.put("aaa", new User());
pageContext.setAttribute("map", map);
%>
${map}<br/>
${map.aaa} <%--获取map的value,是通过get(Key) --%> <br/>
${map.aaa.name}${map.aaa.age}<br/>
${map["aaa"].name}
</body>
</html>
运行效果:
EL 表达式运算符
有两个特殊的运算符,使用方式如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page import="com.itheima.domain.User" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>EL两个特殊的运算符</title>
</head>
<body>
<%-- empty运算符:
它会判断:对象是否为null,字符串是否为空字符串,集合中元素是否是0个
--%>
<% String str = null;
String str1 = "";
List<String> slist = new ArrayList<String>();
pageContext.setAttribute("str", str);
pageContext.setAttribute("str1", str1);
pageContext.setAttribute("slist", slist);
%>
${empty str}============当对象为null返回true<br/>
${empty str1}==========当字符串为空字符串是返回true(注意:它不会调用trim()方法)<br>
${empty slist}==========当集合中的元素是0个时,是true
<hr/>
<%-- 三元运算符:
条件?真:假
--%>
<% request.setAttribute("gender", "female"); %>
<input type="radio" name="gender" value="male" ${gender eq "male"?"checked":""} >男
<input type="radio" name="gender" value="female" ${gender eq "female"?"checked":""}>女
</body>
</html>
运行效果:
EL 表达式的 11 个隐式对象
EL表达式除了能在四大域中获取数据,同时也为我们提供了隐式对象,可以让我们无需声明而直接使用,并且可以访问对象有返回值的方法。
11 个对象见下表(需要注意的是,它和 JSP 的隐式对象不是一回事):
EL 中的隐式对象 | 类型 | 对应的 JSP 隐式对象 | 备注 |
---|---|---|---|
PageContext | Javax.serlvet.jsp.PageContext | PageContext | 完全一样 |
ApplicationScope | Java.util.Map | 没有 | 应用域范围的对象数据 |
SessionScope | Java.util.Map | 没有 | 会话域范围的对象数据 |
RequestScope | Java.util.Map | 没有 | 请求域范围的对象数据 |
PageScope | Java.util.Map | 没有 | 页面域范围的对象数据 |
Header | Java.util.Map | 没有 | 请求消息头 key,值是 value(一个) |
HeaderValues | Java.util.Map | 没有 | 请求消息头 key,值是数组(一个头多个值) |
Param | Java.util.Map | 没有 | 请求参数 key,值是 value(一个) |
ParamValues | Java.util.Map | 没有 | 请求参数 key,值是数组(一个名称多个值) |
InitParam | Java.util.Map | 没有 | 全局参数,key 是参数名称,value 是参数值 |
Cookie | Java.util.Map | 没有 | Key 是 cookie 的名称,value 是 cookie 对象 |
示例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>EL表达式11个隐式对象</title>
</head>
<body>
<%-- applicationScope sessionScope requestScope pageScope 操作四大域对象中的数据 --%>
<%--获取四大域对象中的数据--%>
<%
pageContext.setAttribute("username", "zhangsan");
request.setAttribute("username", "zhangsan");
session.setAttribute("username", "zhangsan");
application.setAttribute("username", "zhangsan");
%>
${username} <br>
${requestScope.username} <br>
<%-- pageContext对象 可以获取其他三个域对象和JSP中八个隐式对象 --%>
<%-- 获取虚拟目录名称 --%>
${pageContext.request.contextPath} <%-- 等价于 <%= request.getContextPath() %> --%>
<%-- header headerValues 获取请求头数据 --%>
${header["connection"]} <br>
${headerValues["connection"][0]} <br>
<%-- param paramValues 获取请求参数数据 --%>
${param.username} <br>
${paramValues.hobby[0]} <br>
${paramValues.hobby[1]} <br>
<%-- initParam 获取全局配置参数 --%>
${initParam["pname"]} <br>
<%-- cookie 获取cookie信息 --%>
${cookie} <br> <%-- 获取Map集合 --%>
${cookie.JSESSIONID} <br> <%-- 获取map集合中第二个元素 --%>
${cookie.JSESSIONID.name} <br> <%-- 获取cookie对象的名称 --%>
${cookie.JSESSIONID.value} <%-- 获取cookie对象的值 --%>
</body>
</html>
JSTL
JSTL 介绍
JSTL 的全称是 JSP Standard Tag Libary,是 JSP 中标准的标签库。
JSTP 是由 Apache 实现的,由以下 5 个部分组成:
组成 | 作用 | 说明 |
---|---|---|
Core | 核心标签库 | 通用逻辑处理 |
Fmt | 国际化相关 | 需要不同地域显示不同语言时使用 |
Functions | EL 函数 | EL 表达式可以使用的方法 |
SQL | 操作数据库 | 很少用 |
XML | 操作XML | 很少用 |
使用要求:
要想使用 JSTL 标签库,需要先在 javaweb 工程中需要导入坐标。首先是要在工程的 WEB-INF 目录中创建一个 lib 目录,然后把 JSTL 的 jar 拷贝到 lib 目录中,再在 jar 包上点击右键,然后选择【Add as Libary】添加。如下图所示:
核心标签库
在实际开发中,用到的 JSTL 标签库主要以核心标签库为准,偶尔会用到国际化标签库的标签。
下表中把经常可能用到的标签列在此处,其余标签库可自行查阅:
标签名称 | 功能分类 | 分类 | 作用 |
---|---|---|---|
<c:if> | 流程控制 | 核心标签库 | 用于条件判断 |
<c:choose> <c:when> <c:otherwise> |
流程控制 | 核心标签库 | 用于多个条件判断 |
<c:foreache> | 迭代操作 | 核心标签库 | 用于循环遍历 |
JSTL 使用
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%-- 导入jstl标签库 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>JSTL的常用标签</title>
</head>
<body>
<%-- 演示 c:if --%>
<% pageContext.setAttribute("score", "F"); %>
<c:if test="${pageScope.score eq 'A'}">
优秀
</c:if>
<c:if test="${pageScope.score eq 'C'}">
一般
</c:if>
<hr/>
<%-- 演示 c:choose c:when c:otherwise --%>
<c:choose>
<c:when test="${pageScope.score eq 'A'}">
AAA
</c:when>
<c:when test="${pageScope.score eq 'B'}">BBB
</c:when>
<c:when test="${pageScope.score eq 'C'}">CCC
</c:when>
<c:when test="${pageScope.score eq 'D'}">DDD
</c:when>
<c:otherwise>其他</c:otherwise>
</c:choose>
<%-- 演示 c:forEach 它是用来遍历集合的
属性:
items:要遍历的集合,它可以是EL表达式取出来的
var:把当前遍历的元素放入指定的page域中。 var的取值就是key,当前遍历的元素就是value
注意:它不能支持EL表达式,只能是字符串常量
begin:开始遍历的索引
end:结束遍历的索引
step:步长。i+=step
varStatus:它是一个计数器对象。里面有两个属性,一个是用于记录索引。一个是用于计数。
索引是从0开始。计数是从1开始
--%>
<hr/>
<% List<String> list = new ArrayList<String>();
list.add("AAA");
list.add("BBB");
list.add("CCC");
list.add("DDD");
list.add("EEE");
list.add("FFF");
list.add("GGG");
list.add("HHH");
list.add("III");
list.add("JJJ");
list.add("KKK");
list.add("LLL");
pageContext.setAttribute("list",list);
%>
<c:forEach items="${list}" var="s" begin="1" end="7" step="2">
${s}<br/>
</c:forEach>
<hr/>
<c:forEach begin="1" end="9" var="num">
<a href="#">${num}</a>
</c:forEach>
<hr/>
<table>
<tr>
<td>索引</td>
<td>序号</td>
<td>信息</td>
</tr>
<c:forEach items="${list}" var="s" varStatus="vs">
<tr>
<td>${vs.index}</td>
<td>${vs.count}</td>
<td>${s}</td>
</tr>
</c:forEach>
</table>
</body>
</html>