Geeks_Z の Blog Geeks_Z の Blog
首页
  • 学习笔记

    • 《HTML》
    • 《CSS》
    • 《JavaWeb》
    • 《Vue》
  • 后端文章

    • Linux
    • Maven
    • 汇编语言
    • 软件工程
    • 计算机网络概述
    • Conda
    • Pip
    • Shell
    • SSH
    • Mac快捷键
    • Zotero
  • 学习笔记

    • 《数据结构与算法》
    • 《算法设计与分析》
    • 《Spring》
    • 《SpringMVC》
    • 《SpringBoot》
    • 《SpringCloud》
    • 《Nginx》
  • 深度学习文章
  • 学习笔记

    • 《PyTorch》
    • 《ReinforementLearning》
    • 《MetaLearning》
  • 学习笔记

    • 《高等数学》
    • 《线性代数》
    • 《概率论与数理统计》
  • 增量学习
  • 哈希学习
GitHub (opens new window)

Geeks_Z

AI小学生
首页
  • 学习笔记

    • 《HTML》
    • 《CSS》
    • 《JavaWeb》
    • 《Vue》
  • 后端文章

    • Linux
    • Maven
    • 汇编语言
    • 软件工程
    • 计算机网络概述
    • Conda
    • Pip
    • Shell
    • SSH
    • Mac快捷键
    • Zotero
  • 学习笔记

    • 《数据结构与算法》
    • 《算法设计与分析》
    • 《Spring》
    • 《SpringMVC》
    • 《SpringBoot》
    • 《SpringCloud》
    • 《Nginx》
  • 深度学习文章
  • 学习笔记

    • 《PyTorch》
    • 《ReinforementLearning》
    • 《MetaLearning》
  • 学习笔记

    • 《高等数学》
    • 《线性代数》
    • 《概率论与数理统计》
  • 增量学习
  • 哈希学习
GitHub (opens new window)
  • Linux

  • Java

  • 微服务笔记

  • MySQL

  • Nginx

  • HTML

  • CSS

  • JavaWeb

    • JavaWeb目录结构
    • HTTP
    • JSP
      • JSP
        • 调用和运行原理
        • JSP语法
        • JSP 声明
        • JSP表达式
        • JSP注释
        • JSP 指令
        • JSP 动作
        • JSP 九大内置对象
        • out隐式对象
        • pageContext对象
        • 四大域对象
        • JSP代码脚本
        • 控制流语句
        • 决策声明
        • 循环语句
        • 在JSP页面中创建方法
        • 在JSP页面中使用数组
        • 在JSP中使用Java Bean
        • Beans的规则:
        • jsp与JavaBean
        • JSP 运算符
        • JSP 字面量
        • JSP Session
        • JSP Cookies信息处理
        • 删除Cookies
        • jsp映射和查错
        • jsp 中的out 输出和response.getWriter 输出的区别
        • JSP常用标签
        • jsp 静态包含
        • jsp 动态包含
        • JSP标签-转发
        • EL表达式
        • JSTL表达式
        • c:forEach标签
        • 判断语句
        • forEach
        • forToken
        • fmt:formatNumber 格式化数字
        • fmt:formatDate 格式化日期
        • fn:
        • JSP执行过程
        • 1.JSP编译
        • 2.JSP初始化
        • 3.JSP执行
        • 4.JSP清理
    • JavaScript
    • Ajax
    • JSON
    • Cookie
    • Session
    • Request
    • Response
    • Servlet
    • Tomcat
    • EL表达式
  • Vue

  • Git

  • 开发规范

  • SpringCloud微服务权限系统

  • bug

  • Software

  • ProgramNotes
  • JavaWeb
Geeks_Z
2021-12-31
目录

JSP

JSP

JSP:Java Server Pages,一种动态web资源的开发技术

API文档

JSP 2.3 API - Apache Tomcat 8.0.30 (opens new window)

调用和运行原理

JSP的工作模式是请求/响应模式,客户端首先发出HTTP请求,JSP程序收到请求后进行处理并返回处理结果。在一个JSP文件第一次被请求时,JSP引擎(容器)把该JSP文件转换成为一个Servlet,而这个引擎本身也是一个Servlet。

JSP转换流程.png

JSP的运行过程具体如下:

  1. 客户端发出请求,请求访问JSP文件。

  2. JSP容器先将JSP文件转换成一个Java源文件(Java Servlet源程序),在转换过程中,如果发现JSP文件中存在任何语法错误,则中断转换过程,并向服务端和客户端返回出错信息。

  3. 如果转换成功,则JSP容器将生成的Java源文件编译成相应的字节码文件*.class。该class文件就是一个Servlet,Servlet容器会像处理其他Servlet一样来处理它。

    注意:若是文件中存在JSTL或者EL表达式的话,那么在何时解析这些变量呢?答案是在将JSP文件解析成对应的Java源文件的时候就对JSTL或者EL表达式进行解析了,也就是说,当从服务器往浏览器写出页面内容时,JSTL或者EL中的变量就已经被解析成具体的值了。

JSP本质是一个servlet.

每个JSP页面在第一次被访问时,WEB容器会把请求交给JSP引擎(即一个JAVA程序)处理。JSP引擎先将JSP翻译成一个_jspServlet(实质也是一个servlet),然后按照servlet的调用方式进行调用。

  • 服务器会将jsp先翻译成servlet,这个servlet位于tomcat服务器work目录,这jsp类的父类是org.apache.jasper.runtime.HttpJspBase,这个HttpJspBase类继承自HttpServlet
  • 向服务器发请求会调用servlet的service方法;同样地,访问jsp会调用这个JSP类的_jspService方法。
  • JSP中的标签语言会在_jspService方法中通过out.write()写出来;JSP中的Java代码会原封不动的搬到_jspService方法中。
  • 在_jspService方法中提前准备好了一些对象供JSP调用,如:out,page,application,request,response等等。
  • 由于第一次访问时会翻译成servlet,所以第一次访问较慢。

下面以demo1.jsp为例,展示对应的类%CATALINA_HOME%\work\Catalina\localhost\hello\org\apache\jsp\demo1_jsp.java中的部分代码

示例1:demo1.jsp

<%@ page import="java.util.Date" %><%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2016/1/27
  Time: 16:45
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>demo1</title>
</head>
<body>
当前时间时:
<%
    Date date = new Date();
    out.write(date.toGMTString());
%>
</body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

示例2:_jspService方法中代码片段

out.write("\r\n");
out.write("\r\n");
out.write("<html>\r\n");
out.write("<head>\r\n");
out.write("    <title>demo1</title>\r\n");
out.write("</head>\r\n");
out.write("<body>\r\n");
out.write("当前时间时:\r\n");

Date date = new Date();
out.write(date.toGMTString());

out.write("\r\n");
out.write("</body>\r\n");
out.write("</html>\r\n");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

示例3:_jspService方法中一些定义的对象

final javax.servlet.jsp.PageContext pageContext;
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;
1
2
3
4
5
6
7

JSP语法

JSP 声明

<%! declaration; [ declaration; ]+ ... %> 下面是简单的例子JSP声明:

<%! int i = 0; %> 
<%! int a, b, c; %> 
<%! Circle a = new Circle(2.0); %> 
1
2
3

JSP表达式

JSP表达式元素包含计算,转换为字符串,并插入出现在JSP文件的脚本语言表达式。

因为一个表达式的值被转换为字符串,可以在文本一行内使用表达式,不管它是否被标记使用在HTML,JSP文件中。

表达元素可以包含任何Java语言规范有效的表达式,但是不能使用一个分号来结束表达式。

下面是JSP表达式的语法: <%= expression %>

下面是简单的例子JSP表达式:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
	<head>
		<title>JSP表达式 </title>
	</head>
	<body>
		<p>
			今天是:<%=(new java.util.Date()).toLocaleString()%>
		</p>
	</body>
</html>
1
2
3
4
5
6
7
8
9
10
11

表达式脚本的特点:

1、所有的表达式脚本都会被翻译到_jspService() 方法中

2、表达式脚本都会被翻译成为out.print()输出到页面上

3、由于表达式脚本翻译的内容都在_jspService()方法中,所以_jspService()方法中的对象都可以直接使用。

4、表达式脚本中的表达式不能以分号结束。

JSP注释

JSP注释标记的文字或语句都会被JSP容器忽略。当想要隐藏或“注释掉”JSP页面的一部分,JSP注释是很有用的。

以下是JSP注释语法: <%-- This is JSP comment --%>

JSP注释示例:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html> 
<head><title>注释 - 示例</title></head>  
<body> 
<h2>A Test of Comments</h2> 
<%-- This comment will not be visible in the page source --%> 
</body> 
</html> 
1
2
3
4
5
6
7
8

还有少数特殊的结构可以使用一些情况,插入注释或字符,将被特殊处理。这里有一个整理汇总:

语法 目的
<%-- comment --%> JSP注释,它将被JSP引擎忽略
<!-- comment --> HTML注释,它将被浏览器忽略
<% 表示静态<%的字面量
%> 表示静态%>的字面量
\' 在使用单引号在属性中的单引号
\ " 双引号在属性使用双引号

JSP 指令

JSP指令影响的servlet类的整体结构。它通常有以下形式: <%@ directive attribute="value" %>

有三种类型的指令标记:

指令 描述
<%@ page ... %> 定义页面依赖属性,例如脚本语言,错误页面和缓冲的要求
<%@ include ... %> 包括在转换阶段的文件
<%@ taglib ... %> 声明了一个标签库,包含自定义动作,用在页面中

page指令语法:

<%@ page
[ language="java" ]
[ extends="package.class" ]
[ import="{package.class | package.*}, ..." ]
[ session="true | false" ]
[ buffer="none | 8kb | sizekb" ]
[ autoFlush="true | false" ]
[ isThreadSafe="true | false" ]
[ info="text" ]
[ errorPage="relativeURL" ]
[ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ]
[ isErrorPage="true | false" ]
%>
1
2
3
4
5
6
7
8
9
10
11
12
13
  • errorPage:错误提示页面。也可在web.xml的<error-page>标签配置,异常处理页面。在page指令设置的优先级高于在web.xml配置。
  • pageEncoding:JSP引擎以何种码表翻译JSP,该值需和JSP文件的保存编码一致,且若要在浏览器正确显示,还要和contentType一致。
  • contentType: 表示jsp 返回的数据类型是什么。也是源码中response.setContentType()参数值
  • autoFlush : 属性设置当out 输出流缓冲区满了之后,是否自动刷新冲级区。默认值是true
  • buffer 属性设置out 缓冲区的大小。默认是8kb
  • isErrorPage 属性设置当前jsp 页面是否是错误信息页面。默认是false。如果是true 可以获取异常信息
  • session 属性设置访问当前jsp 页面,是否会创建HttpSession 对象。默认是true
  • extends 属性设置jsp 翻译出来的java 类默认继承谁。

JSP 动作

JSP动作使用XML语法结构来控制Servlet引擎的行为。可以动态地插入文件,重用JavaBeans组件,用户转发到另一个页面,或为Java插件生成HTML。

只有一个用于动作元素的语法,因为它符合XML标准: <jsp:action_name attribute="value" />

动作元素基本上都是预先定义函数并有以下可用的JSP操作:

语法 目的
jsp:include 包括页面被一次请求的文件
jsp:useBean 查找或实例化一个JavaBean
jsp:setProperty 设置一个JavaBean的属性
jsp:getProperty 插入一个JavaBean的属性到输出
jsp:forward 转发请求到一个新的页面
jsp:plugin 生成特定浏览器的代码,使对象或嵌入标签Java插件
jsp:element 定义XML元素动态
jsp:attribute 定义动态定义XML元素的属性
jsp:body 定义动态定义的XML元素主体
jsp:text 用于编写模板文本在JSP页面和文档

​

JSP 九大内置对象

名称 类型 描述
out javax.servlet.jsp.JspWriter 这是用于将输出发送给客户端的PrintWriter对象
request javax.servlet.http.HttpServletReqeust 这是与请求相关联的HttpServletRequest对象
response javax.servlet.http.HttpServletResponse 这是用于响应客户端相关联的HttpServletResponse对象
config javax.servlet.ServletConfig 这是与页面关联的ServletConfig对象
session javax.servlet.http.HttpSession 这是与请求相关联的HttpSession对象
application jaax.servlet.ServletContext 这是应用程序上下文关联的ServletContext对象
page java.lang.Object 这是一个简单的代名词,是用来调用由转换servlet类中定义的方法
exception java.lang.Throwable Exception对象允许例外的数据由JSP指定访问
pageContext javax.servlet.jsp.PageContext 这封装采用类似更高的性能JspWriters服务器特定的功能
out隐式对象

out隐式对象:用于向客户端发送文本数据。通过调用pageContext对象的getOut方法返回,类型为JspWriter,作用和ServletResponse.getWriter返回的PrintWriter对象相似。

JspWriter相当于自带缓存功能的PrintWriter,设置page指令的buffer属性课调整缓存大小。满足如下条件之一,out对象才调用ServletResponse.getWriter方法,并通过返回的PrintWriter对象将out对象的缓冲区的内容真正写入到servlet引擎提供的缓冲区中:

  • 设置page指令的buffer属性关闭的out对象的缓存功能
  • out对象的缓冲区已满
  • 整个JSP页面结束

例子:

<%
    out.write("out.write<br/>");
	response.getWriter().write("response.getWriter.write<br/>");
%>
1
2
3
4

浏览器显示:

response.getWriter.write
out.write
1
2

可见,由于out有缓冲,所以后显示。

pageContext对象

pageContext对象:是JSP技术中最重要的一个对象,它代表JSP页面的运行环境

  • 封装了对其他8大隐式对象的引用(主要用于自定义标签开发)
  • 自身是一个域对象,可用来保存数据(page域存的东西只能在页面范围内拿得出来)
  • 封装了web开发中的一些常用操作(提供管理所有域的入口),如:引入和跳转其他资源、检索其他域对象中的属性等

Class PageContext的API文档

javax.servlet.jsp:Class PageContext (opens new window)

四大域对象

pageContext: (PageContextImpl 类) 当前jsp 页面范围内有效

Request 范围: (HttpServletRequest 类) 使用该JSP对象可以在请求服务任何地方使用(一次请求内有效)。

Session 范围: (HttpSession 类) 使用该JSP的对象可用于在属于同一个会话页面(一个会话范围内有效【打开浏览器访问服务器,直到关闭浏览器】)。

Application 范围: (ServletContext 类) 使用该JSP的对象可以在整个应用程序页面中使用(整个web 工程范围内都有效【只要web 工程不停止,数据都在】)。

四个域在使用的时候,优先顺序分别是,他们从小到大的范围的顺序。

pageContext =>>> request =>>> session =>>> application

将下面的代码编写到 scope1.jsp 文件,代码内容如下所示:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:set var="Pag" value="Page Value" scope="page" />
<c:set var="Req" value="Request Value" scope="request" />
<c:set var="Ses" value="Session Value" scope="session" />
<c:set var="App" value="Application Value" scope="application" />
<html>
<body>
    <h2>JSP对象范围示例一:</h2>
    <b>Page Scope</b> ::<c:out value="${Pag}" /><br>
    <b>Request Scope</b> ::<c:out value="${Req}" /><br>
    <b>Session Scope</b> ::<c:out value="${Ses}" /><br>
    <b>Application Scope</b>::<c:out value="${App}" /><br>
    <a href="scope2.jsp">下一页Session,Application范围</a>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

Page 范围:

使用此JSP对象可以在其中创建的页面内使用。

JSP代码脚本

<%
  java语句
%>
1
2
3

代码脚本的特点是:

1、代码脚本翻译之后都在_jspService 方法中

2、代码脚本由于翻译到_jspService()方法中,所以在_jspService()方法中的现有对象都可以直接使用。

3、还可以由多个代码脚本块组合完成一个完整的java 语句。

4、代码脚本还可以和表达式脚本一起组合使用,在jsp 页面上输出数据

控制流语句

JSP提供了Java的全部功能可以嵌入在Web应用程序。可以使用Java的所有API和构建块在JSP编程,包括决策语句,循环等。

决策声明

在if ... else块开头时就像一个普通的Scriptlet,但 Scriptlet 每一行是封闭的,包括scriptlet标记之间的HTML文本。创建一个JSP文件为:if-else.jsp,并写入以下代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%! int day = 3; %> 
<html> 
<head><title>IF...ELSE 示例</title></head> 
<body>
<% if (day == 1 | day == 7) { %>
<p> Today is weekend</p>
<% } else { %>
<p> Today is not weekend</p>
<% } %>
</body> 
</html>
1
2
3
4
5
6
7
8
9
10
11
12

switch...case 块,编写通过使用out.println()和内小脚本有一点不同,把下面代码保存到switch-case.jsp文件中,代码详细如下:

<%! int day = 3; %> 
<html> 
<head><title>SWITCH...CASE 示例</title></head> 
<body>
<% 
switch(day) {
case 0:
   out.println("It\'s Sunday.");
   break;
case 1:
   out.println("It\'s Monday.");
   break;
case 2:
   out.println("It\'s Tuesday.");
   break;
case 3:
   out.println("It\'s Wednesday.");
   break;
case 4:
   out.println("It\'s Thursday.");
   break;
case 5:
   out.println("It\'s Friday.");
   break;
default:
   out.println("It's Saturday.");
}
%>
</body> 
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
循环语句

还可以使用在Java中三种基本循环类型块:for, while,and do.while块在JSP编程中。

让我们来看看下面的for循环示例,把下面代码保存到 loop-for.jsp 文件中,代码详细如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%! int fontSize; %> 
<html> 
<head><title>FOR 循环示例</title></head> 
<body>
<%for ( fontSize = 1; fontSize <= 3; fontSize++){ %>
   <font color="green" size="<%= fontSize %>">
    JSP Tutorial
   </font><br />
<%}%>
</body> 
</html> 
1
2
3
4
5
6
7
8
9
10
11
12

while循环编写,把下面代码保存到 loop-while.jsp 文件中,代码详细如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%! int fontSize; %> 
<html> 
<head><title>WHILE循环示例</title></head> 
<body>
<h2>While循环示例:</h2>
<%while ( fontSize <= 5){ %>
   <font color="green" size="<%= fontSize %>">
    JSP Tutorial
   </font><br />
<%fontSize++;%>
<%}%>
</body> 
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
在JSP页面中创建方法

方法即是可以在一个JSP页面被用于执行特定操作的一个代码段。

创建一个方法示例:

<%!
public int mul(int a, int b){
    return a * b;
}
%>
1
2
3
4
5

两个数相乘的结果是:<%= mul(2, 2) %>

以上代码保存,并执行结果如下: 两个数相乘的结果是:4

另外,在上述例子中使用的方法是:mul,将返回一个整数值作为输出。 它需要两个整数“a”,“b”作为参数,以产生两个数字的乘积作为输出。

在JSP页面中使用数组

由于JSP不是一个完整的编程语言不具有数组的声明,但使用Java中的数据结构在JSP中使用是完全没有问题的。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String[] arr={"apple","orange","cherry"};
%>
<%
int j;
out.println("<p>数组中所有元素是:</p>");
for(j=0;j<arr.length;j++){
    out.println(arr[j]);
}
%>
1
2
3
4
5
6
7
8
9
10
11
在JSP中使用Java Bean

Java bean只不过是一个实现java.io.Serializable接口,并且使用set/get方法来投射类的属性。因为它们是一个Java bean类的实例并可重复使用,在JSP页面中提供了灵活性,。 嵌入一个Java bean到JSP网页,有三个基本动作或标签:<jsp:useBean>, <jsp:setProperty>, <jsp:getProperty>

  1. jsp:useBean 这个标签是用来给bean指定“id”和“scope”属性相关联。

  2. jsp:setProperty 这个标签被用于设置一个beans属性的值,主要使用“name”属性已经定义了相同的范围对象。其他属性是 "property", "param", "value"

  3. jsp:getProperty 这个标签是用来获取引用Bean实例属性并将其存储到隐式out对象。

Beans的规则:
  • 包应该是java bean的第一行
  • Bean应该有一个空的构造
  • 所有的bean中的变量应该设置有“get”,“set”方法。
  • 属性名应以大写字母开头在使用“set”,“get”方法时。
  • 例如变量“名称”的get,set方法就是getName(), setName(String)
  • 设置方法应该返回像一个空(void)值: "return void()"

jsp与JavaBean

JavaBean是一个遵循特定写法的java类,JavaBean常用于封装数据,具有如下热点:

  • 该java类必须有一个无参的构造函数
  • 属性必须私有化
  • 私有化的属性必须通过public类型的方法暴露给其他程序,并且方法的命名也必须遵循一定的命名规范。

JSP中提供了三个关于JavaBean的标签:

  • <jsp:useBean>:用于在JSP页面中查找或实例化一个JavaBean组件
  • <jsp:setProperty>:用于在JSP页面中设置一个JavaBean组件的属性
  • <jsp:getProperty>:用于在JSP页面中获取一个JavaBean组件的属性

一些细节

  • <jsp:useBean>标签的标签体只在实例化bean时才执行
  • <jsp:setProperty>可用请求参数给bean属性赋值,支持8种基本数据类型的转换(把客户机提交的字符串转成相应的8种基本类型赋到bean的属性上)
  • 在标签中将property="*",用所有请求参数为bean赋值,请求参数名称和bean属性名称必须要一致
  • 如果JavaBean实例对象的某个属性值为null,那么使用<jsp:getProperty>标签输出结果为**"null"字符串**

bean.java

package bean;
public class Counter
{
int count = 0;
String name;
public Counter() { }
public int getCount()
{
    return this.count;
}
public void setCount(int count){
    this.count = count;
} 
public String getName(){
    return this.name; 
} 
public void setName(String name){
    this.name=name; 
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

use-bean.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page language="java" %>
<%@ page import="bean.Counter" %>
</body>
<jsp:useBean id="counter" scope="page" class="bean.Counter" />
<jsp:setProperty name="counter" property="count" value="4" />
Get Value: <jsp:getProperty name="counter" property="count" /><BR>
<jsp:setProperty name="counter" property="name" value="baidu.com" />
Get Name: <jsp:getProperty name="counter" property="name" /><BR>
1
2
3
4
5
6
7
8
9

使用<jsp:useBean>动作包含bean.Counter这个bean,并设置此bean的id为counter,范围是page.使用<jsp:setProperty>设置id=counter的bean的count属性 的值为 4 ,以及设置name的值为 baidu.com. 并使用 <jsp:getProperty> 来获取它们的值。

JSP 运算符

JSP支持所有支持Java的逻辑和算术运算符。下表给出了所有的运算符,具有最高优先级将排在表的顶部, 运算级别最低的放在底部。

在一个表达式中,具有更高的优先级运算符将首先计算评估。

分类 操作符 关联
后缀 () [] . (点运算符) 左->右
一元 ++ - - ! ~ 右->左
乘法 * / % 左->右
加法 + - 左->右
位移 >> >>> << 左->右
关系 > >= < <= 左->右
相等 == != 左->右
位与/AND & 左->右
位XOR ^ 左->右
位OR | 左->右
逻辑AND && 左->右
逻辑OR | | 左->右
关系 ?: 右->左
赋值 = += -= *= /= %= >>= <<= &= ^= |= 右->左
逗号 , 左->右

JSP 字面量

JSP表达式语言定义了以下字面量:

  • Boolean: true 或 false
  • Integer: 与Java中的一样
  • Float: 与Java中的一样
  • String: 单引号和双引号; " 转义为 "。' 转义为 ', 以及 \ 转义为 \
  • Null: null

JSP Session

会话处理变得必不可少,当一个请求数据需要被持续保持以供进一步使用。 由于HTTP协议认为每个请求是一个新的请求,它不能保持过去访问的数据,因此会话处理就变得很重要。以下是一些来处理会话的方法。

  • JSP中每当发起一个请求,服务器产生一个存储在客户机的唯一会话ID。
  • Cookies存储信息在客户端浏览器
  • URL重写会话信息附加到URL的末尾
  • 隐藏的表单域将SessionID嵌入到GET和POST命令。

创建一个页面 session.jsp,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>Session示例</title></head>
<body>
<h2>Session示例:</h2> 
<form method = "post" action="session2.jsp">
<font>Username<input type = "text" name = "name"></font>
</font><br><br>
<input type = "submit" name = "submit" value = "提交" >
</form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12

创建另一个页面 session2.jsp,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>

<head><title>Session示例2</title></head>

<body> 
<%
String name = request.getParameter("name");
if((name!=null))
{
    session.setAttribute("username",name);
}
%>
<a href="session3.jsp">继续,跳转到session3.jsp</a>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

创建另一个页面 session3.jsp,代码如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>Session示例3</title></head> 
<body>
<font>欢迎您,</font> <%= session.getAttribute("username") %>
</body>
</html>
1
2
3
4
5
6
7

在第一个示例中的 "session1.jsp" 是用来提供一个表单以获得用户名。 当提交表单时它转到第二个文件session2.jsp,它调用表单的“action”属性。一个Session的属性使用 "session.setAttribute"设置在这里. 在第三个文件 "session3.jsp" 相同的值使用"session.getAttribute" 来显示出来。

JSP Cookies信息处理

Cookies和会话有一些相似的地方,唯一的区别是cookies 存储在浏览器。而会话存储在服务器端。让我们来看看在JSP中处理Cookies的一些例子:

示例代码: cookie1.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<body>
<form method = "post" action="cookie2.jsp">
<font>Username<input type = "text" name = "name"></font>
</font><br>
<input type = "submit" name = "submit" value = "submit" >
</form>
</body>
</html>
1
2
3
4
5
6
7
8
9
10

示例代码: cookie2.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ page language="java" import="java.util.*"%>
<%
String name=request.getParameter("name");
Cookie cookie = new Cookie ("name",name);
response.addCookie(cookie);
cookie.setMaxAge(50 * 50); //Time is in Minutes
%>
<a href="cookie3.jsp">Continue</a>
1
2
3
4
5
6
7
8
9

示例代码: cookie3.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<p>显示Cookie的值:</p>
<%
Cookie[] cookies = request.getCookies();
for (int i=0; i<cookies.length; i++){
    if(cookies[i].getName().equals("name"))
        out.println("Hello"+cookies[i].getValue());
}
%>
1
2
3
4
5
6
7
8
9

在第一个例子cookie1.jsp中,使用表单得到用户名。当表单提交进入第二页cookie2.jsp其中Cookie使用cookie.setMaxAge函数设置过期时间。在第三个页面cookie3.jsp中,cookie使用函数request.getCookies(),并使用循环是得到了字段username的值并显示。

删除Cookies

示例代码: cookie4.jsp

<%
Cookie cookie = new Cookie( "name", "" );
cookie.setMaxAge( 0 );
%>
1
2
3
4

另外,在上述例子中,我们已经创建的 cookie的新实例并使用一个null值并将cookie的age设定为0。 这将删除cookie。

  • JSP模板元素:JSP页面中的HTML内容。定义了网页的基本骨架,即结构和外观。
  • JSP表达式:用于将程序数据输出到客户端。如,<%=变量或表达式 %>脚本表达式(无分号),用于输出数据。
  • JSP脚本片段:用于在JSP页面中编写多行java代码,严格遵循java语法。一个JSP页面可有多个脚本片段,它们可以相互访问(和放在一对<% %>中一样),单个片段可不完整。
    • <% 代码 %>:定义的java代码,在service方法中。service方法中可以定义什么,该脚本中就可以定义什么。
    • <%! 代码 %>:定义的java代码,在jsp转换后的java类的成员位置。
    • <%= 代码 %>:定义的java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么。
  • JSP声明:JSP中代码默认翻译到servlet的service方法中,而JSP声明中的代码被翻译到_jspService方法外。语法:<%! java代码 %>。
  • JSP注释:格式<%-- 注释 --%>,注释的内容不会发给浏览器。
  • JSP指令:是为JSP引擎设计的,定义了三个指令:page指令,include指令,taglib指令。语法:<%@ 指令 属性名="值" %>。
    • page指令:定义各种属性,作用于整个JSP页面。
    • include指令:用于包含JSP文件(页头、页脚)。属于静态包含(编译时包含),它包含的所有JSP会编译成一个servlet。
    • taglib指令:用于在JSP页面导入标签库。
  • JSP标签:也称为jsp Action元素,用于在jsp页面中提供业务逻辑功能,避免在jsp页面中直接写java代码而难以维护
  • JSP内置对象:九大隐式对象,request,response,session,application,config,page,exception,out,pageContext

jsp映射和查错

jsp映射

在webxml的<servlet>标签中加<jsp-file>标签,其他的和servlet映射一样

查找jsp页面中的错误

  • JSP页面中的语法格式有问题,导致不能翻译成servlet源文件,JSP引擎将提示这类错误在JSP页面中的位置以及相关信息
  • JSP页面中的语法格式没有问题,但翻译承德servlet源文件出现java语法问题导致源文件编译不通过,JSP引擎将提示这类错误在JSP页面中的位置以及相关信息
  • JSP页面翻译成的servlet程序运行时出现异常,这和普通java程序运行时错误完全一样,java虚拟机将提示错误在servlet源文件中的位置以及相关信息

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

  • response 中表示响应,我们经常用于设置返回给客户端的内容(输出)
  • out 也是给用户做输出使用的。

image-20220301222541160

由于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"%>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

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>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

动态包含的底层原理

image-20220301223303292

JSP标签-转发

<%--
<jsp:forward page=""></jsp:forward> 是请求转发标签,它的功能就是请求转发
page 属性设置请求转发的路径
--%>
<jsp:forward page="/scope2.jsp"></jsp:forward>
1
2
3
4
5

EL表达式

一般的都是先将数据存储到Session,request,ServletContext等域对象中,再利用EL表达式来获取。

  • 语法
    • 以"${"符号开始,以"}"符号结束,具体格式:${表达式} 。
  • 获取数据
    • 类似page.findAttribute(); 先从page域中查找,没有找到去request域中查询,没找到去session域中找,没找到就去application域中找。
  • 注意:1. 在用EL表达式获取数据时,必须保证该数据存在于四个域对象其中的一个。 2. 在获取数据时,一定不要忘记加${}。

JSTL表达式

  • 使用时务必注意不要忘记导入JSTL的jar包:jstl.jar 和standard.jar 。
  • 要使用taglib指令导入Core标签库:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 。

c:forEach标签

  • 语法
<c:forEach [var="varName" items="collection" [varStatus="varStatusName"] [begin="begin"] [end="end"] [step="step"]>
	${varName}
</c:forEach>
1
2
3
  • 参数解释

    • var属性用于指将当前迭代到的元素保存到page域中的名称
    • items属性用于指定将要迭代的集合对象
    • varStatus用于指定当前迭代状态信息的对象保存到page域中的名称
    • begin属性用于指定从集合中第几个元素开始迭代,begin的索引值从0开始,如果没有指定items属性,就从begin指定的值开始迭代,知道迭代结束为止
    • step属性用于指定迭代的步长,即迭代因子的增量
  • 实例

    <c:forEach items="${userMap}" var="entry">
         ${entry.key}====${entry.value}
     </c:forEach>
    
    1
    2
    3
  • 注意:items里面需要使用到EL表达式的时候,一定不要忘记加${}

在页面中使用JSTL需要在jsp中 通过指令进行设置

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

prefix="c" 表示后续的标签使用都会以<c: 开头

<c:set var="name" value="${'gareen'}" scope="request" />

通过标签获取name: <c:out value="${name}" /> <br>

<c:remove var="name" scope="request" /> <br>

通过标签获取name: <c:out value="${name}" /> <br>
1
2
3
4
5
6
7

判断语句

JSTL通过<c:if test=""> 进行条件判断

但是JSTL没有<c:else,所以常用的办法是在<c:if的条件里取反

配合if使用的还有通过empty进行为空判断 empty可以判断对象是否为null,字符串长度是否为0,集合长度是否为0

<c:set var="hp" value="${10}" scope="request"/>

<c:if test="${hp<5}">
    <p>这个英雄要挂了</p>
</c:if>

<c:if test="${!(hp<5)}">
    <p>这个英雄觉得自己还有救</p>
</c:if>

<c:set var="weapon" value="${null}" scope="page"/>
<c:set var="lastwords" value="${''}" scope="page"/>
<%
    List lis = new ArrayList();
%>
<c:set var="items" value="${list}" scope="page"/>

<c:if test="${empty weapon}">
    <p>没有武器了</p>
</c:if>
<c:if test="${empty lastwords}">
    <p>挂了也没有遗言</p>
</c:if>
<c:if test="${empty items}">
    <p>物品栏为空</p>
</c:if>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

choose语句

<c:choose>
    <c:when test="${hp1<5}">
        <p>这个英雄觉得自己要挂了</p>
    </c:when>
    <c:otherwise>
        <p>这个英雄觉得自己还可以再抢救抢救</p>
    </c:otherwise>
</c:choose>
1
2
3
4
5
6
7
8

forEach

items="${heros}"表示遍历的集合 var="hero"表示把每一个集合中的元素放在hero上 varStatus="st"表示遍历的状态

<%
    List<String> heros = new ArrayList<String>();
    heros.add("塔姆");
    heros.add("艾克");
    heros.add("巴德");
    heros.add("雷克赛");
    heros.add("卡莉丝塔");
    request.setAttribute("heros",heros);
%>
<table width="200px" align="center" border="1" cellspacing="0">
    <tr>
        <td>编号</td>
        <td>英雄</td>
    </tr>
    <c:forEach var="hero" items="${heros}" varStatus="st">
        <tr>
            <td><c:out value="${st.count}"/> </td>
            <td><c:out value="${hero}"/> </td>
        </tr>
    </c:forEach>
</table>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

forToken

<c:forTokens专门用于字符串拆分,并且可以指定多个分隔符

<c:set var="heros" value="塔姆,艾克;巴德|雷克赛!卡莉丝塔" />
<c:forTokens items="${heros}" delims=":;|;!" var="hero">
    <c:out value="${hero}"/><br/>
</c:forTokens>
1
2
3
4

fmt:formatNumber 格式化数字

fmt 标签常用来进行格式化,其中fmt:formatNumber用于格式化数字 使用之前要加上

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix='fmt' %>  
1
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix='fmt' %>
<c:set var="moeny" value="888.8888"/>
<c:set var="pi" value="3.1415926"/>
<fmt:formatNumber type="number" value="${moeny}" minFractionDigits="2"/><br/>
<fmt:formatNumber type="number" value="${pi}" maxFractionDigits="2"/><br/>
1
2
3
4
5

<fmt:formatNumber表示格式化数字 minFractionDigits小数点至少要有的位数 maxFractionDigits小数点最多能有的位数

fmt:formatDate 格式化日期

<fmt:formatDate表示格式化日期 yyyy 表示年份 MM 表示月份 dd 表示日期 E表示星期几

a 表示是上午还是下午 HH表示小时 mm 表示分钟 ss 表示秒 S 表示毫秒 z 表示时区

<%
    Date now = new Date();
    pageContext.setAttribute("now",now);
%>
 
完整日期: <fmt:formatDate value="${now}" pattern="G yyyy年MM月dd日 E"/><br>
完整时间: <fmt:formatDate value="${now}" pattern="a HH:mm:ss.S z"/><br>
常见格式: <fmt:formatDate value="${now}" pattern="yyyy-MM-dd HH:mm:ss"/>
1
2
3
4
5
6
7
8

fn:

fn标签提供各种实用功能,首先使用之前使用加入如下指令

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %> 
1

用法举例: ${fn:substring(name, 0, 5)}

函数 描述
fn:contains(string, substring) 如果参数string中包含参数substring,返回true
fn:containsIgnoreCase(string, substring) 如果参数string中包含参数substring(忽略大小写),返回true
fn:endsWith(string, suffix) 如果参数 string 以参数suffix结尾,返回true
fn:escapeXml(string) 将有特殊意义的XML (和HTML)转换为对应的XML character entity code,并返回
fn:indexOf(string, substring) 返回参数substring在参数string中第一次出现的位置
fn:join(array, separator) 将一个给定的数组array用给定的间隔符separator串在一起,组成一个新的字符串并返回。
fn:length(item) 返回参数item中包含元素的数量。参数Item类型是数组、collection或者String。如果是String类型,返回值是String中的字符数。
fn:replace(string, before, after) 返回一个String对象。用参数after字符串替换参数string中所有出现参数before字符串的地方,并返回替换后的结果
fn:split(string, separator) 返回一个数组,以参数separator 为分割符分割参数string,分割后的每一部分就是数组的一个元素
fn:startsWith(string, prefix) 如果参数string以参数prefix开头,返回true
fn:substring(string, begin, end) 返回参数string部分字符串, 从参数begin开始到参数end位置,包括end位置的字符
fn:substringAfter(string, substring) 返回参数substring在参数string中后面的那一部分字符串
fn:substringBefore(string, substring) 返回参数substring在参数string中前面的那一部分字符串
fn:toLowerCase(string) 将参数string所有的字符变为小写,并将其返回
fn:toUpperCase(string) 将参数string所有的字符变为大写,并将其返回
fn:trim(string) 去除参数string 首尾的空格,并将其返回

JSP执行过程

以下是JSP遵循的过程

  • 编译
  • 初始化
  • 执行
  • 清理

JSP生命周期的四个主要阶段与Servlet生命周期非常相似。以下描述了四个阶段

1.JSP编译

当浏览器请求JSP时,JSP引擎首先检查是否需要编译页面。如果页面从未被编译,或者JSP从上一次编译以来JSP文件代码已被修改,那么JSP引擎将会编译页面。 编译过程包括三个步骤 -

  • 解析JSP。
  • 将JSP转换为servlet。
  • 编译servlet。

2.JSP初始化

当容器加载JSP时,它会在处理任何请求之前调用jspInit()方法。 如果需要执行特定于JSP的初始化,那么可以覆盖jspInit()方法 -

public void jspInit(){
   // Initialization code...
}
1
2
3

通常,初始化仅执行一次,并且与servlet的init()方法一样,一般会在jspInit()方法中初始化数据库连接,打开文件和创建查找表。

3.JSP执行

JSP生命周期的这个阶段表示所有与请求的交互,直到JSP被销毁为止。 每当浏览器请求JSP并且页面已被加载和初始化时,JSP引擎将调用JSP中的_jspService()方法。 _jspService()方法以HttpServletRequest和HttpServletResponse为参数,如下所示:

void _jspService(HttpServletRequest request, HttpServletResponse response) {
   // Service handling code...
}
1
2
3

根据请求调用JSP的_jspService()方法。它负责生成请求的响应,此方法还负责生成对所有七种HTTP方法的响应,即GET,POST,DELETE等。

4.JSP清理

JSP生命周期的清理阶段表示当JSP被容器从使用中移除时。 jspDestroy()方法是等效于servlet的destroy方法的JSP方法。当需要执行清理工作时,可以覆盖jspDestroy()方法,如:释放数据库连接或关闭打开的文件。 jspDestroy()方法具有以下形式

public void jspDestroy() {
   // Your cleanup code goes here.
}
1
2
3
上次更新: 2025/02/26, 08:57:57
HTTP
JavaScript

← HTTP JavaScript→

最近更新
01
RAIL
02-26
02
IOCTF
02-25
03
DGM
02-25
更多文章>
Theme by Vdoing | Copyright © 2022-2025 Geeks_Z | MIT License
京公网安备 11010802040735号 | 京ICP备2022029989号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式