JSP整理

什么是 jsp,它有什么用?

  • jsp 的全换是 java server pages。Java 的服务器页面。
  • jsp 的主要作用是代替 Servlet 程序回传html 页面的数据。
  • 因为 Servlet 程序回传 html 页面数据是一件非常繁锁的事情。开发成本和维护成本都极高。

Servlet 回传 html 页面数据的代码:

public class PringHtml extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException {
// 通过响应的回传流回传 html 页面数据
resp.setContentType("text/html; charset=UTF-8");
PrintWriter writer = resp.getWriter();
writer.write("<!DOCTYPE html>\r\n");
writer.write(" <html lang=\"en\">\r\n");
writer.write(" <head>\r\n");
writer.write(" <meta charset=\"UTF-8\">\r\n");
writer.write(" <title>Title</title>\r\n");
writer.write(" </head>\r\n");
writer.write(" <body>\r\n");
writer.write(" 这是 html 页面数据 \r\n");
writer.write(" </body>\r\n");
writer.write("</html>\r\n");
writer.write("\r\n");
}

jsp 回传一个简单 html 页面的代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
这是 html 页面数据
</body>
</html>

jsp的声明周期

JSP也是Servlet,运行时只有一个实例,JSP初始化和销毁时也会调Servlet的init()和destroy()方法。另外,JSP还有自己初始化和销毁的方法

jsp 的本质是什么?

jsp 页面本质上是一个 Servlet程序。
当我们第一次访问 jsp 页面的时候。Tomcat 服务器会帮我们把 jsp 页面翻译成为一个 java 源文件。并且对它进行编译成为.class 字节码程序。我们打开 java 源文件不难发现其里面的内容是:

在这里插入图片描述

我们跟踪原代码发现,HttpJspBase 类。它直接地继承了 HttpServlet 类。也就是说。jsp 翻译出来的 java 类,它间接了继承了 HttpServlet 类。也就是说,翻译出来的是一个 Servlet 程序。
在这里插入图片描述

总结:通过翻译的 java 源代码我们就可以得到结果:jsp 就是 Servlet 程序。
大家也可以去观察翻译出来的 Servlet 程序的源代码,不难发现。其底层实现,也是通过输出流。把 html 页面数据回传给客户端。

public void _jspService(final javax.servlet.http.HttpServletRequest request, final
javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)
&& !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or
HEAD");
return;
}
final javax.servlet.jsp.PageContext pageContext;
javax.servlet.http.HttpSession session = null;
final javax.servlet.ServletContext application;
final javax.servlet.ServletConfig config;
javax.servlet.jsp.JspWriter out = null;
final java.lang.Object page = this;
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
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;
out.write("\r\n");
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");
out.write(" a.jsp 页面\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}

jsp 的三种语法

jsp 头部的 page 指令
jsp 的 page 指令可以修改 jsp 页面中一些重要的属性,或者行为。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
errorPage 属性 设置当 jsp 页面运行时出错,自动跳转去的错误页面路径。

errorPage 表示错误后自动跳转去的路径 ,这个路径一般都是以斜杠打头,它表示请求地址为 http://ip:port/工程路径/映射到代码的 Web 目录

viii. isErrorPage 属性 设置当前 jsp 页面是否是错误信息页面。默认是 false。如果是 true 可以获取异常信息。ix. session 属性 设置访问当前 jsp 页面,是否会创建 HttpSession 对象。默认是 true。x. extends 属性 设置 jsp 翻译出来的 java 类默认继承谁
jsp 中的常用脚本
声明脚本(极少使用)
声明脚本的格式是: <%! 声明 java 代码 %>
作用:可以给 jsp 翻译出来的 java 类定义属性和方法甚至是静态代码块。内部类等。
如下:
1、声明类属性
2、声明 static 静态代码块
3、声明类方法
4、声明内部类

<%--1、声明类属性--%>
<%!
private Integer id;
private String name;
private static Map<String,Object> map;
%>
<%--2、声明 static 静态代码块--%>
<%!
static {
map = new HashMap<String,Object>();
map.put("key1", "value1");
map.put("key2", "value2");
map.put("key3", "value3");
}
%>
<%--3、声明类方法--%>
<%!
public int abc(){
return 12;
}
%>
<%--4、声明内部类--%>
<%!
public static class A {
private Integer id = 12;
private String abc = "abc";
}
%>

表达式脚本(常用)

表达式脚本的格式是:<%=表达式%>
表达式脚本的作用是:jsp页面上输出数据。

表达式脚本的特点:

1、所有的表达式脚本都会被翻译到_jspService() 方法中
2、表达式脚本都会被翻译成为 out.print()输出到页面上
3、由于表达式脚本翻译的内容都在_jspService() 方法中,所以_jspService()方法中的对象都可以直接使用。
4、表达式脚本中的表达式不能以分号结束。
如下示例:

  1. 输出整型
  2. 输出浮点型
  3. 输出字符串
  4. 输出对象
<%=12 %> <br>
<%=12.12 %> <br>
<%="我是字符串" %> <br>
<%=map%> <br>
<%=request.getParameter("username")%>

在这里插入图片描述
代码脚本
代码脚本的格式是:

<%
java 语句
%>

代码脚本的作用是:可以在 jsp 页面中,编写我们自己需要的功能(写的是 java 语句)

代码脚本的特点是:

1、代码脚本翻译之后都在_jspService 方法中
2、代码脚本由于翻译到_jspService()方法中,所以在_jspService()方法中的现有对象都可以直接使用。
3、还可以由多个代码脚本块组合完成一个完整的 java 语句。
4、代码脚本还可以和表达式脚本一起组合使用,在 jsp 页面上输出数据。

如下示例:

  1. 代码脚本----if 语句
  2. 代码脚本----for 循环语句
  3. 翻译后 java 文件中_jspService 方法内的代码都可以写
<%--练习:--%>
<%--1.代码脚本----if 语句--%>
<%
int i = 13 ;
if (i == 12) {
%>
<h1>国哥好帅</h1>
<%
	} else {
%>
<h1>国哥又骗人了!</h1>
<%
	}
%>
<br>
<%--2.代码脚本----for 循环语句--%>
<table border="1" cellspacing="0">
<%
	for (int j = 0; j < 10; j++) {
%>
<tr>
	<td><%=j + 1%></td>
</tr>
<%
	}
%>
</table>
<%--3.翻译后 java 文件中_jspService 方法内的代码都可以写--%>
<%
	String username = request.getParameter("username");
	System.out.println("用户名的请求参数值是:" + username);
%>

jsp中的三种注释

html 注释

<!-- 这是 html 注释 -->
html 注释会被翻译到 java 源代码中。
在_jspService 方法里,以 out.writer 输出到客户端

html 注释会被翻译到 java 源代码中。在_jspService 方法里,以 out.writer 输出到客户端。

java 注释

<%
		// 单行 java 注释
		/* 多行 java 注释 */
%>

java 注释会被翻译到 java。

jsp 注释

<%-- 这是 jsp 注释 --%>

jsp 注释可以注掉,jsp面中所有代码。

jsp 的九大内置对象

jsp 中的内置对象,是指 Tomcat 在翻译 jsp 页面成为 Servlet 源代码后,内部提供的九大对象,叫内置对象。
在这里插入图片描述
在这里插入图片描述

jsp 四大域对象

四个域对象分别是:
pageContext (PageContextImpl 类) 当前 jsp 页面范围内有效
request (HttpServletRequest 类) 一次请求内有效
session (HttpSession 类) 一个会话范围内有效(打开浏览器访问服务器,直到关闭浏览器)
application (ServletContext 类) 整个 web 工程范围内都有效(只要 web 工程不停止,数据都在)
域对象是可以像 Map 一样存取数据的对象。四个域对象功能一样。不同的是它们对数据的存取范围。虽然四个域对象都可以存取数据。在使用上它们是有优先顺序的。四个域在使用的时候,优先顺序分别是,他们从小到大的范围的顺序。
pageContext ====>>> request ====>>> session ====>>>application

<body>
	<h1>scope.jsp 页面</h1>
<%
// 往四个域中都分别保存了数据
	pageContext.setAttribute("key", "pageContext");
	request.setAttribute("key", "request");
	session.setAttribute("key", "session");
	application.setAttribute("key", "application");
%>
	pageContext 域是否有值:<%=pageContext.getAttribute("key")%> <br>
	request 域是否有值:<%=request.getAttribute("key")%> <br>
	session 域是否有值:<%=session.getAttribute("key")%> <br>
	application 域是否有值:<%=application.getAttribute("key")%> <br>
<%
	request.getRequestDispatcher("/scope2.jsp").forward(request,response);
%>
</body>
<body>
	<h1>scope2.jsp 页面</h1>
	pageContext 域是否有值:<%=pageContext.getAttribute("key")%> <br>
	request 域是否有值:<%=request.getAttribute("key")%> <br>
	session 域是否有值:<%=session.getAttribute("key")%> <br>
	application 域是否有值:<%=application.getAttribute("key")%> <br>
</body>

jsp 中的 out 输出和 response.getWriter 输出的区别

response 中表示响应,我们经常用于设置返回给客户端的内容(输出)
out 也是给用户做输出使用的。
在这里插入图片描述
由于 jsp 翻译之后,底层源代码都是使用 out 来进行输出,所以一般情况下。我们在 jsp 页面中统一使用 out 来进行输出。避免打乱页面输出内容的顺序。

out.write() 输出字符串没有问题
out.print() 输出任意数据都没有问题(都转换成为字符串后调用的 write 输出)

深入源码,浅出结论:在 jsp 页面中,可以统一使用 out.print()来进行输出。

jsp中常见的标签

jsp 静态包含
<%@ include file=""%> 就是静态包含
file 属性指定你要包含的 jsp 页面的路径,地址中第一个斜杠 / 表示为 http://ip:port/工程路径/ 映射到代码的 web 目录
静态包含的特点:
1、静态包含不会翻译被包含的 jsp 页面。
2、静态包含其实是把被包含的 jsp 页面的代码拷贝到包含的位置执行输出。

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

jsp 动态包含
<jsp:include page=""></jsp:include> 这是动态包含

page 属性是指定你要包含的 jsp 页面的路径。
动态包含也可以像静态包含一样。把被包含的内容执行输出到包含位置
动态包含的特点:
1、动态包含会把包含的 jsp 页面也翻译成为 java 代码
2、动态包含底层代码使用如下代码去调用被包含的 jsp 页面执行输出。
JspRuntimeLibrary.include(request, response, “/include/footer.jsp”, out, false);
3、动态包含,还可以传递参数

	<jsp:include page="/include/footer.jsp">
	<jsp:param name="username" value="bbj"/>
	<jsp:param name="password" value="root"/>
	</jsp:include>

动态包含的底层原理
在这里插入图片描述
jsp 标签-转发
<jsp:forward page=""></jsp:forward> 是请求转发标签,它的功能就是请求转发。
page 属性设置请求转发的路径。

<jsp:forward page="/scope2.jsp"></jsp:forward>

面试重点
jsp与servlet的区别

  • JSP是Servlet技术的扩展,本质上就是Servlet的简易方式。JSP编译后是“类servlet”。
  • Servlet和JSP最主要的不同点在于:Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML里分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。
  • JSP侧重于视图,Servlet主要用于控制逻辑。

JSP是如何被执行的?执行效率比SERVLET低吗?

  • 当客户端向一个jsp页面发送请求时,Web Container将jsp转化成servlet的源代码(只在第一次请求时),然后编译转化后的servlet并加载到内存中执行,执行的结果response到客户端。
  • jsp只在第一次执行的时候会转化成servlet,以后每次执行,web容器都是直接执行编译后的servlet,所以jsp和servlet只是在第一次执行的时候不一样,jsp慢一点,以后的执行都是相同的。

servlet

什么是 Servlet
1、Servlet 是 JavaEE 规范之一。规范就是接口
2、Servlet 就 JavaWeb 三大组件之一。三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器。
3、Servlet 是运行在服务器上的一个 java 小程序,它可以接收客户端发送过来的请求,并响应数据给客户端。
Servlet 的生命周期
1、执行 Servlet 构造器方法
2、执行 init 初始化方法
第一、二步,是在第一次访问,的时候创建 Servlet 程序会调用。
3、执行 service 方法
第三步,每次访问都会调用。
4、执行 destroy 销毁方法
第四步,在 web工程停止的时候调用。
ServletConfig类
ServletConfig 类从类名上来看,就知道是 Servlet 程序的配置信息类。
Servlet 程序和 ServletConfig 对象都是由 Tomcat 负责创建,我们负责用。
Servlet 程序默认是第一次访问的时候创建,ServletConfig 是每个 Servlet 程序创建时,就创建一个对应的 ServletConfig 对象。
ServletConfig 类的三大作用
1、可以获取 Servlet 程序的别名 servlet-name 的值
2、获取初始化参数 init-param
3、获取 ServletContext
如下所示:
web.xml文件如下配置:

<!-- servlet 标签给 Tomcat 配置 Servlet 程序 -->
<servlet>
<!--servlet-name 标签 Servlet 程序起一个别名(一般是类名) -->
<servlet-name>HelloServlet</servlet-name>
<!--servlet-class 是 Servlet 程序的全类名-->
<servlet-class>com.atguigu.servlet.HelloServlet</servlet-class>
<!--init-param 是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>username</param-name>
<!--是参数值-->
<param-value>root</param-value>
</init-param>
<!--init-param 是初始化参数-->
<init-param>
<!--是参数名-->
<param-name>url</param-name>
<!--是参数值-->
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</init-param>
</servlet>
<!--servlet-mapping 标签给 servlet 程序配置访问地址-->
<servlet-mapping>
<!--servlet-name 标签的作用是告诉服务器,我当前配置的地址给哪个 Servlet 程序使用-->
<servlet-name>HelloServlet</servlet-name>
<!--
url-pattern 标签配置访问地址 <br/>
/ 斜杠在服务器解析的时候,表示地址为:http://ip:port/工程路径 <br/>
/hello 表示地址为:http://ip:port/工程路径/hello <br/>
-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2 init 初始化方法");
// 1、可以获取 Servlet 程序的别名 servlet-name 的值
System.out.println("HelloServlet 程序的别名是:" + servletConfig.getServletName());
// 2、获取初始化参数 init-param
System.out.println("初始化参数 username 的值是;" + servletConfig.getInitParameter("username"));
System.out.println("初始化参数 url 的值是;" + servletConfig.getInitParameter("url"));
// 3、获取 ServletContext 对象
System.out.println(servletConfig.getServletContext());
}

ServletContext 类
什么是 ServletContext?
1、ServletContext 是一个接口,它表示 Servlet 上下文对象
2、一个 web 工程,只有一个 ServletContext 对象实例。
3、ServletContext 对象是一个域对象。
4、ServletContext 是在 web 工程部署启动的时候创建。在 web 工程停止的时候销毁
什么是域对象?
域对象,是可以像 Map 一样存取数据的对象,叫域对象。
这里的域指的是存取数据的操作范围,整个 web 工程。
存数据 取数据 删除数据
Map put() get() remove()
域对象函数:
setAttribute()
getAttribute()
removeAttribute();

ServletContext 类的四个作用
1、获取 web.xml 中配置的上下文参数 context-param
2、获取当前的工程路径,格式: /工程路径
3、获取工程部署后在服务器硬盘上的绝对路径
4、像 Map 一样存取数
ServletContext 演示代码

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
// 1、获取 web.xml 中配置的上下文参数 context-param
ServletContext context = getServletConfig().getServletContext();
String username = context.getInitParameter("username");
System.out.println("context-param 参数 username 的值是:" + username);
System.out.println("context-param 参数 password 的值是:" +
context.getInitParameter("password"));
// 2、获取当前的工程路径,格式: /工程路径
System.out.println( "当前工程路径:" + context.getContextPath() );
// 3、获取工程部署后在服务器硬盘上的绝对路径
/**
* / 斜杠被服务器解析地址为:http://ip:port/工程名/ 映射到 IDEA 代码的 web 目录<br/>
*/
System.out.println("工程部署的路径是:" + context.getRealPath("/"));
System.out.println("工程下 css 目录的绝对路径是:" + context.getRealPath("/css"));
System.out.println("工程下 imgs 目录 1.jpg 的绝对路径是:" + context.getRealPath("/imgs/1.jpg"));
}

web.xml 中的配置

<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
	<param-name>username</param-name>
	<param-value>context</param-value>
</context-param>
<!--context-param 是上下文参数(它属于整个 web 工程)-->
<context-param>
	<param-name>password</param-name>
	<param-value>root</param-value>
</context-param>

HttpServletRequest 类的常用方法

i. getRequestURI() 获取请求的资源路径
ii. getRequestURL() 获取请求的统一资源定位符(绝对路径)
iii. getRemoteHost() 获取客户端的 ip 地址
iv. getHeader() 获取请求头
v. getParameter() 获取请求的参数
vi. getParameterValues() 获取请求的参数(多个值的时候使用)
vii. getMethod() 获取请求的方式 GET 或 POST
viii. setAttribute(key, value); 设置域数据
ix. getAttribute(key); 获取域数据
x. getRequestDispatcher() 获取请求转发对象

EL表达式

什么是 EL 表达式,EL 表达式的作用?
EL 表达式的全称是:Expression Language。是表达式语言。
EL 表达式的什么作用:EL 表达式主要是代替 jsp 页面中的表达式脚本在 jsp 页面中进行数据的输出。
因为 EL 表达式在输出数据的时候,要比 jsp 的表达式脚本要简洁很多。
EL 表达式的格式是:${表达式}
EL 表达式在输出 null 值的时候,输出的是空串。jsp 表达式脚本输出 null 值的时候,输出的是 null
如下:

<body>
<%
	request.setAttribute("key","值");
%>
表达式脚本输出 key 的值是:
<%=request.getAttribute("key1")==null?"":request.getAttribute("key1")%><br/>
EL 表达式输出 key 的值是:${key1}
</body>

EL 表达式搜索域数据的顺序
EL 表达式主要是在 jsp 页面中输出数据。主要是输出域对象中的数据。当四个域中都有相同的 key 的数据的时候,EL 表达式会按照四个域的从小到大的顺序去进行搜索,找到就输出。

<body>
<%
//往四个域中都保存了相同的 key 的数据。
	request.setAttribute("key", "request");
	session.setAttribute("key", "session");
	application.setAttribute("key", "application");
	pageContext.setAttribute("key", "pageContext");
%>
${ key }
</body>

EL 表达式输出 Bean 的普通属性,数组属性。List 集合属性,map 集合属性

  1. 需求——输出 Person 类中普通属性,数组属性。list 集合属性和 map 集合属性。
    person类:
public class Person {
// i.需求——输出 Person 类中普通属性,数组属性。list 集合属性和 map 集合属性。
	private String name;
	private String[] phones;
	private List<String> cities;
	private Map<String,Object> map;
	public int getAge() {
	return 18;
}
<body>
<%
	Person person = new Person();
	person.setName("国哥好帅!");
	person.setPhones(new String[]{"18610541354","18688886666","18699998888"});
	List<String> cities = new ArrayList<String>();
	cities.add("北京");
	cities.add("上海");
	cities.add("深圳");
	person.setCities(cities);
	Map<String,Object>map = new HashMap<>();
	map.put("key1","value1");
	map.put("key2","value2");
	map.put("key3","value3");
	person.setMap(map);
	pageContext.setAttribute("p", person);
%>
	输出 Person:${ p }<br/>
	输出 Person 的 name 属性:${p.name} <br>
	输出 Person 的 pnones 数组属性值:${p.phones[2]} <br>
	输出 Person 的 cities 集合中的元素值:${p.cities} <br>
	输出 Person 的 List 集合中个别元素值:${p.cities[2]} <br>
	输出 Person 的 Map 集合: ${p.map} <br>
	输出 Person 的 Map 集合中某个 key 的值: ${p.map.key3} <br>
	输出 Person 的 age 属性:${p.age} <br>
</body>

EL 表达式——运算
语法:${ 运算表达式 }
关系运算符
在这里插入图片描述
逻辑运算符
在这里插入图片描述
算数运算符
在这里插入图片描述
empty 运算
empty 运算可以判断一个数据是否为空,如果为空,则输出 true,不为空输出 false。
以下几种情况为空:
1、值为 null 值的时候,为空
2、值为空串的时候,为空
3、值是 Object 类型数组,长度为零的时候
4、list 集合,元素个数为零
5、map 集合,元素个数为零
如下示例:

<body>
<%
	// 1、值为 null 值的时候,为空
	request.setAttribute("emptyNull", null);
	// 2、值为空串的时候,为空
	request.setAttribute("emptyStr", "");
	// 3、值是 Object 类型数组,长度为零的时候
	request.setAttribute("emptyArr", new Object[]{});
	// 4、list 集合,元素个数为零
	List<String> list = new ArrayList<>();
	// list.add("abc");
	request.setAttribute("emptyList", list);
	// 5、map 集合,元素个数为零
	Map<String,Object> map = new HashMap<String, Object>();
	// map.put("key1", "value1");
	request.setAttribute("emptyMap", map);
%>
	${ empty emptyNull } <br/>
	${ empty emptyStr } <br/>
	${ empty emptyArr } <br/>
	${ empty emptyList } <br/>
	${ empty emptyMap } <br/>
</body>

三元运算
表达式 1?表达式 2:表达式 3
如果表达式 1 的值为真,返回表达式 2 的值,如果表达式 1 的值为假,返回表达式 3 的值。
示例:

${ 12 != 12 ? "帅呆":"骗人" 

“.”点运算 和 [] 中括号运算
.点运算,可以输出 Bean 对象中某个属性的值。
[]中括号运算,可以输出有序集合中某个元素的值。
并且[]中括号运算,还可以输出 map 集合中 key 里含有特殊字符的 key 的值

<body>
<%
	Map<String,Object> map = new HashMap<String, Object>();
	map.put("a.a.a", "aaaValue");
	map.put("b+b+b", "bbbValue");
	map.put("c-c-c", "cccValue");
	request.setAttribute("map", map);
%>
	${ map['a.a.a'] } <br>
	${ map["b+b+b"] } <br>
	${ map['c-c-c'] } <br>
</body>

EL 表达式的 11 个隐含对象
EL 个达式中 11 个隐含对象,是 EL 表达式中自己定义的,可以直接使用。
在这里插入图片描述
在这里插入图片描述
pageContext的使用

在这里插入图片描述
== EL 表达式其他隐含对象的使用==
在这里插入图片描述

输出请求参数 username 的值:${ param.username } <br>
输出请求参数 password 的值:${ param.password } <br>
输出请求参数 username 的值:${ paramValues.username[0] } <br>
输出请求参数 hobby 的值:${ paramValues.hobby[0] } <br>
输出请求参数 hobby 的值:${ paramValues.hobby[1] } <br

JSTL标签库

JSTL 标签库 全称是指 JSP Standard Tag Library JSP 标准标签库。是一个不断完善的开放源代码的 JSP 标签库。
EL 表达式主要是为了替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本。这样使得整个 jsp 页面变得更佳简洁。
JSTL 由五个不同功能的标签库组成。
在这里插入图片描述
在 jsp 标签库中使用 taglib 指令引入标签库。

CORE 标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
XML 标签库
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
FMT 标签库
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
SQL 标签库
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
FUNCTIONS 标签库
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %

JSTL 标签库的使用步骤
1、先导入 jstl 标签库的 jar 包。
taglibs-standard-impl-1.2.1.jar
taglibs-standard-spec-1.2.1.jar
2、第二步,使用 taglib 指令引入标签库。
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
core 核心库使用
i. <c:set />(使用很少)
作用:set 标签可以往域中保存数据。

	<%--	域对象.setAttribute(key,value);
		scope 属性设置保存到哪个域
		page 表示 PageContext 域(默认值)
		request 表示 Request 域
		session 表示 Session 域
		application 表示 ServletContext 域
		var 属性设置 key 是多少
		value 属性设置值
		--%>
保存之前:${ sessionScope.abc } <br>
<c:set scope="session" var="abc" value="abcValue"/>
保存之后:${ sessionScope.abc } <br>

ii. <c:if /> -------if 标签用来做 if 判断。

<%--
	if 标签用来做 if 判断。
	test 属性表示判断的条件(使用 EL 表达式输出)
--%>
<c:if test="${ 12 == 12 }">
	<h1>12 等于 12</h1>
</c:if>
<c:if test="${ 12 != 12 }">
	<h1>12 不等于 12</h1>
</c:if>

iii. <c:choose> <c:when> <c:otherwise>标签
作用:多路判断。跟 switch … case … default

<%--
iii.<c:choose> <c:when> <c:otherwise>标签
作用:多路判断。跟 switch ... case .... default 非常接近
choose 标签开始选择判断
when 标签表示每一种判断情况
test 属性表示当前这种判断情况的值
otherwise 标签表示剩下的情况
<c:choose> <c:when> <c:otherwise>标签使用时需要注意的点:
1、标签里不能使用 html 注释,要使用 jsp 注释
2、when 标签的父标签一定要是 choose 标签
--%>
<%
	request.setAttribute("height", 180);
%>
<c:choose>
<%-- 这是 html 注释 --%>
<c:when test="${ requestScope.height > 190 }">
	<h2>小巨人</h2>
</c:when>
<c:when test="${ requestScope.height > 180 }">
	<h2>很高</h2>
</c:when>
<c:when test="${ requestScope.height > 170 }">
	<h2>还可以</h2>
</c:when>
<c:otherwise>
<c:choose>
	<c:when test="${requestScope.height > 160}">
<h3>大于 160</h3>
</c:when>
<c:when test="${requestScope.height > 150}">
	<h3>大于 150</h3>
</c:when>
<c:when test="${requestScope.height > 140}">
	<h3>大于 140</h3>
</c:when>
<c:otherwise>
	其他小于 140
</c:otherwise>
</c:choose>
</c:otherwise>
</c:choose>

iv. <c:forEach />
作用:遍历输出使用。
遍历 1 到 10,

<%--1.遍历 1 到 10,输出
begin 属性设置开始的索引
end 属性设置结束的索引
var 属性表示循环的变量(也是当前正在遍历到的数据)
for (int i = 1; i < 10; i++)
--%>
<table border="1">
<c:forEach begin="1" end="10" var="i">
<tr>
<td>第${i}行</td>
</tr>
</c:forEach>
</table>

遍历 Object 数组

<%-- 2.遍历 Object 数组
for (Object item: arr)
items 表示遍历的数据源(遍历的集合)
var 表示当前遍历到的数据
--%>
<%
request.setAttribute("arr", new String[]{"18610541354","18688886666","18699998888"});
%>
<c:forEach items="${ requestScope.arr }" var="item">
${ item } <br>
</c:forEach>

遍历map集合

<%
	Map<String,Object> map = new HashMap<String, Object>();
	map.put("key1", "value1");
	map.put("key2", "value2");
	map.put("key3", "value3");
	// for ( Map.Entry<String,Object> entry : map.entrySet()) {
	// }
	request.setAttribute("map", map);
%>
<c:forEach items="${ requestScope.map }" var="entry">
<h1>${entry.key} = ${entry.value}</h1>
</c:forEach>

遍历 List 集合

public class Student {
//4.编号,用户名,密码,年龄,电话信息
private Integer id;
private String username;
private String password;
private Integer age;
private String phone;
<%--4.遍历 List 集合---list 中存放 Student 类,有属性:编号,用户名,密码,年龄,电话信息--%>
<%
	List<Student> studentList = new ArrayList<Student>();
	for (int i = 1; i <= 10; i++) {
	studentList.add(new Student(i,"username"+i ,"pass"+i,18+i,"phone"+i));
	}
	request.setAttribute("stus", studentList);
%>
<table>
	<tr>
		<th>编号</th>
		<th>用户名</th>
		<th>密码</th>
		<th>年龄</th>
		<th>电话</th>
		<th>操作</th>
	</tr>
<%--
	items 表示遍历的集合
	var 表示遍历到的数据
	begin 表示遍历的开始索引值
	end 表示结束的索引值
	step 属性表示遍历的步长值
	varStatus 属性表示当前遍历到的数据的状态
	for(int i = 1; i < 10; i+=2)
--%>
<c:forEach begin="2" end="7" step="2" varStatus="status" items="${requestScope.stus}" var="stu">
<tr>
	<td>${stu.id}</td>
	<td>${stu.username}</td>
	<td>${stu.password}</td>
	<td>${stu.age}</td>
	<td>${stu.phone}</td>
	<td>${status.step}</td>
</tr>
</c:forEach>
</table>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值