0x01 前言
JSP全称Java Server Pages,是一种动态网页开发技术
它使用JSP标签在HTML网页中插入Java代码,常用标签是<%java代码%>
JSP是为了简化Servlet的处理流程而出现的替代品
早期的Java EE因为只能使用Servlet来处理客户端请求而显得非常的繁琐和不便
于是就诞生了JSP方便快速的完成后端逻辑请求
从本质上说 JSP 就是一个Servlet ,因为JSP文件最终会被编译成class文件
而这个class文件实际上就是一个特殊的Servlet
0x02 JSP脚本标签
0x02.1 说明
脚本元素是JSP中使用最频繁的元素,脚本程序可以包含任意量的Java语句、变量、方法或表达式
0x02.2 JSP声明语句
0x02.2.1 语法格式
作用: 用于声明方法、属性、全局变量, 其中写的内容会直接编译在Servlet类中
语法格式:
<%!
常量
静态变量
实例变量
静态代码块
实例代码块
构造函数
实例⽅法
静态⽅法
%>
或者,您也可以编写与其等价的XML语句:
<jsp:declaration>
代码片段
</jsp:declaration>
0x02.2.2 小例子
<%!
int sum = 1;
String name = "name";
public String printName() {
return name + "ooooo";
}
%>
或是
<jsp:declaration>
int sum = 1;
String name = "name";
public String printName() {
return name + "ooooo";
}
</jsp:declaration>
0x02.3 JSP表达式
0x02.3.1 语法格式
作用: 用于将已经声明的变量或者表达式输出到网页上面
语法格式:
<%= 表达式 %>
或者,您也可以编写与其等价的XML语句:
<jsp:expression>
表达式
</jsp:expression>
0x02.3.2 小例子
// 输出今日时间
<%= (new java.util.Date()).toLocaleString() %>
或是
<jsp:expression>
(new java.util.Date()).toLocaleString()
</jsp:expression>
0x02.4 JSP脚本片段
0x02.4.1 语法格式
作用: JSP脚本片段(JSP Scriptlet),常常用于在Service方法中定义局部变量或者调用其他方法
语法格式:
<% Java代码 %>
或者,您也可以编写与其等价的XML语句:
<jsp:scriptlet>
代码片段
</jsp:scriptlet>
0x02.4.2 小例子
<%
out.println("Your IP address is " + request.getRemoteAddr());
%>
或是
<jsp:scriptlet>
out.println("Your IP address is " + request.getRemoteAddr());
</jsp:scriptlet>
0x02.5 小例子
// 目录结构
├── src
│ └── main
│ └── webapp
│ └── com
│ │ └── Servlet
│ │ └── ...
│ └── WEB-INF
│ │ └── web.xml
│ ├── ...
│ └── test2.jsp
// 文件名test2.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%
for (int i = 0; i < 3; i++) {
out.println(i);
}
%>
<%!
int sum = 1;
String name = "name";
public String printName() {
return name + "ooooo";
}
%>
<% int sum = 8; %>
<% out.println(sum++); %>
<%= this.sum %>
<%= this.name %>
<%= this.printName() %>
-------------------xml语法-----------------------
<jsp:declaration>
int a = 5;
</jsp:declaration>
<jsp:scriptlet>
out.println(a);
</jsp:scriptlet>
<jsp:expression>
(new java.util.Date()).toLocaleString()
</jsp:expression>
<jsp:scriptlet>
out.println("Your IP address is " + request.getRemoteAddr());
</jsp:scriptlet>
// 执行test2.jsp
0x03 JSP注释
0x03.1 说明
1. JAVA注释_1
作用: 单行注释
语法格式: //注释内容
2. JAVA注释_2
作用: 多行注释
语法格式: /*注释内容*/
3. JSP注释
作用: JSP注释
语法格式: <%--注释内容--%>
0x03.2 小例子
// 文件名test3.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
// JAVA注释
// int name = "laowang";
/* System.out.print(name); */
%>
<%--
int name = "xiaowang";
System.out.print(name);
--%>
// 执行test3.jsp
// 执行结果,啥也没有,因为被代码被注释了
0x04 JSP三大指令
指令 | 描述 |
---|---|
<%@ page … %> | 定义网页依赖属性,比如脚本语言、error页面、缓存需求等等 |
<%@ include … %> | 包含其它文件 |
<%@ taglib … %> | 引入标签库的定义 |
0x04.1 page指令
作用: Page指令为容器提供当前页面的使用说明。一个JSP页面可以包含多个page指令
语法格式: <%@ page 属性名1= "属性值1" 属性名2= "属性值2" ...%>
下表列出与Page指令相关的属性:
属性 | 描述 |
---|---|
buffer | 指定out对象使用缓冲区的大小 |
autoFlush | 控制out对象的缓存区 |
contentType | 指定当前JSP页面的MIME类型和字符编码 |
errorPage | 指定当JSP页面发生异常时需要转向的错误处理页面 |
isErrorPage | 指定当前页面是否可以作为另一个JSP页面的错误处理页面 |
extends | 指定servlet从哪一个类继承 |
import | 导入要使用的Java类 |
info | 定义JSP页面的描述信息 |
isThreadSafe | 指定对JSP页面的访问是否为线程安全 |
language | 定义JSP页面所用的脚本语言,默认是Java |
session | 指定JSP页面是否使用session |
isELIgnored | 指定是否执行EL表达式 |
isScriptingEnabled | 确定脚本元素能否被使用 |
例子1-指定页面编码-解决中文编码问题:
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
例子2-导入包:
<%@ page import="java.util.*,java.text.*" %>
0x04.2 include指令
作用: 包含其它文件
语法格式: <%@ include file="要被包含的页面"%>
例子1-包含一个通用jsp文件
<%@ include file="common/herder.jsp"%>
0x04.3 taglib指令
作用: 引入标签库的定义
语法格式: <%@ taglib ... %>
0x05 JSP内置/隐式的九大对象
0x05.1 说明
JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用
JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量
开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用
名称 | 类型 | 描述 |
---|---|---|
out | javax.servlet.jsp.JspWriter | 用于页面输出 |
request | javax.servlet.http.HttpServletRequest | 客户端请求对象,包含了所有客户端请求信息 |
response | javax.servlet.http.HttpServletResponse | 响应对象,主要用于服务器端设置响应信息 |
config | javax.servlet.ServletConfig | 服务器配置,可以取得初始化参数 |
session | javax.servlet.http.HttpSession | 用户请求会话信息 |
application | javax.servlet.ServletContext | 全局对象,所有用户的共享信息 |
page | java.lang.Object | 指当前页面转换后的Servlet类的实例 |
pageContext | javax.servlet.jsp.PageContext | JSP的页面容器 |
exception | java.lang.Throwable | 表示JSP页面所发生的异常,在错误页中才起作用 |
0x05.2 小例子
// 文件名test4.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
out.println("test");
out.println(request.getSession());
%>
// 执行test4.jsp
0x06 JSP行为
0x06.1 说明
这里直接抄一下菜鸟教程的JSP教程: https://www.runoob.com/jsp/jsp-syntax.html
JSP行为标签使用XML语法结构来控制servlet引擎
它能够动态插入一个文件,重用JavaBean组件,引导用户去另一个页面,为Java插件产生相关的HTML等等
行为标签只有一种语法格式,它严格遵守XML标准
<jsp:action_name attribute="value" />
行为标签基本上是一些预先就定义好的函数,下表罗列出了一些可用的JSP行为标签:
语法 | 描述 |
---|---|
jsp:include | 用于在当前页面中包含静态或动态资源 |
jsp:useBean | 寻找和初始化一个JavaBean组件 |
jsp:setProperty | 设置JavaBean组件的值 |
jsp:getProperty | 将JavaBean组件的值插入到output中 |
jsp:forward | 从一个JSP文件向另一个文件传递一个包含用户请求的request对象 |
jsp:param | 一般和jsp:forward配合使用 用于在转发时增加额外的请求参数 请求参数的值可以通过HttpServletRequest类的getParameter()方法获得 |
jsp:plugin | 用于在生成的HTML页面中包含Applet和JavaBean对象 |
jsp:element | 动态创建一个XML元素 |
jsp:attribute | 一般和jsp:element配合使用 定义动态创建的XML元素的属性 |
jsp:body | 一般和jsp:element配合使用 定义动态创建的XML元素的主体 |
jsp:text | 用于封装模板数据 |
0x06.2 小例子
// 目录结构
├── src
│ └── main
│ └── webapp
│ └── com
│ │ └── ...
│ └── WEB-INF
│ │ └── web.xml
│ ├── ...
│ └── JSP行为
│ │ ├── ...
│ │ │ └── ...
0x06.2.1 jsp:include
// jsp:include使用详解
注: 代码审计时可以看看page参数参数是否可控,可控表示有漏洞,可以尝试加载管理员界面绕过权限校验
jsp:include的语法为: <jsp:include page="URL" flush="true"></jsp:include>
page: 被包含文件的相对路径
flush: 在包含文件之前是否清空缓存, 默认为false
// 文件地址: ./src/main/webapp/JSP行为/include/
// 文件名称: head.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<div>这是一个头部</div>
// 文件地址: ./src/main/webapp/JSP行为/include/
// 文件名称: test1.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<jsp:include page="${param.value}" flush="true"></jsp:include>
<div>这是一个test1.jsp</div>
</body>
// 打开: http://127.0.0.1:8081/mavenJspTest_war/JSP行为/include/test1.jsp?value=head.jsp
0x06.2.2 jsp:userBean/jsp:setProperty/jsp:getProperty
// jsp:userBean使用详解
jsp:userBean的语法为: <jsp:userBean id="beanId" class="className" scope="value"/>
id: JavaBean对象的名称
class: javaBean的全类名
scope: JavaBean对象的作用域
可设置的作用域:
page(当前页面有效)
request(当前请求有效)
session(当前会话有效)
application(整个应用有效)
有了JavaBean之后可以使用jsp:setProperty/jsp:getProperty行为来对JavaBean的属性进行操作
// jsp:setProperty使用详解
jsp:setProperty的语法为: <jsp:setProperty name="beanName" property="propertyName" value="" param=""/>
name: JavaBean的id
propertys: 属性名
value: 属性值
name:
name属性是必需的,它表示要设置属性的是哪个Bean
property:
property属性是必需的, 它表示要设置哪个属性
有一个特殊用法: 如果property的值是"*",表示所有名字和Bean属性名字匹配的请求参数都将被传递给相应的属性set方法
value:
value属性是可选的, 该属性用来指定Bean属性的值
字符串数据会在目标类中通过标准的valueOf方法自动转换成数字、boolean、Boolean、 byte、Byte、char、Character
例如:
boolean和Boolean类型的属性值(比如"true")通过Boolean.valueOf转换
int和Integer类型的属性值(比如"42")通过Integer.valueOf转换
value和param不能同时使用,但可以使用其中任意一个
param:
param属性是可选的, 它指定用哪个请求参数作为Bean属性的值
如果当前请求没有参数, 则什么事情也不做, 系统不会把null传递给Bean属性的set方法
因此, 你可以让Bean自己提供默认属性值, 只有当请求参数明确指定了新值时才修改默认属性值
注意: value和param属性不能同时使用, 但可以使用其中任意一个
它们的区别是:
1. value是自定义属性的值, param是将请求参数(比如前端表单数据)作为值,注入到该property中
2. param的值应该对应前端, 请求参数的name属性名, 表明哪个请求参数将注入到该property中
jsp:getProperty的语法为: <jsp:getProperty name="beanName" property="propertyName" />
name: JavaBean的id
propertys: 属性名
注意:当JavaBean中的属性名为xxx, 而获取该属性值的方法名为getyyy(), 则property="yyy", 而不是property="xxx"
// 文件地址: ./src/main/webapp/JSP行为/useBean/
// 文件名称: TestBean.java
package JSP行为.useBean;
public class TestBean {
private String userName;
private String password;
private int age;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
// 文件地址: ./src/main/webapp/JSP行为/useBean/
// 文件名称: register.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%
request.setCharacterEncoding("utf-8");
%>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>注册成功</title>
</head>
<jsp:useBean id="user" scope="page" class="JSP行为.useBean.TestBean"/>
<jsp:setProperty name="user" property="*"/>
<jsp:setProperty property="userName" name="user" param="userName"/>
<jsp:setProperty property="password" name="user" param="password"/>
<jsp:setProperty property="age" name="user" param="age"/>
<body>
<div>注册成功:</div>
<div>使用Bean的属性方法</div>
<div>用户名: <%=user.getUserName()%></div>
<div>密 码: <%=user.getPassword()%></div>
<div>年 龄: <%=user.getAge()%></div>
<hr>
<div>使用getProperty</div>
<div>用户名: <jsp:getProperty name="user" property="userName"/></div>
<div>密 码: <jsp:getProperty name="user" property="password"/></div>
<div>年 龄: <jsp:getProperty name="user" property="age"/></div>
</body>
</html>
// 文件地址: ./src/main/webapp/JSP行为/useBean/
// 文件名称: register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form action="register.jsp" method="post">
<table>
<tr>
<td>姓名:<input type="text" name="userName"></td>
</tr>
<tr>
<td>密码:<input type="text" name="password"></td>
</tr>
<tr>
<td>年龄:<input type="text" name="age"></td>
</tr>
<tr>
<td align="center"><input type="submit"></td>
</tr>
</table>
</form>
</body>
</html>
// 打开: http://127.0.0.1:8081/mavenJspTest_war/JSP行为/useBean/register.html
0x06.2.3 jsp:forward/jsp:param
// jsp:forward使用详解
<jsp:forword page="URL">
...
</jsp:forward>
page: 要跳转的地址
// jsp:param使用详解
<jsp:param name="属性名" value="值" />
name: 属性名
value: 值
// 文件地址: ./src/main/webapp/JSP行为/forword/
// 文件名称: a.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>跳转前页面</title>
</head>
<body>
<%
String username = "testname";
%>
<jsp:forward page="b.jsp">
<jsp:param name="name" value="<%=username%>"/>
<jsp:param name="other" value="test-test-test"/>
</jsp:forward>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>跳转后页面,同时接收参数</title>
</head>
<body>
<div> 参数一: <%=request.getParameter("name")%> </div>
<div> 参数二: <%=request.getParameter("other")%> </div>
</body>
</html>
// 打开: http://127.0.0.1:8081/mavenJspTest_war/JSP行为/forword/b.jsp
// 打开以后会显示b.jsp的内容,并且链接还是a.jsp的
0x06.2.4 jsp:plugin
<jsp:plugin>动作元素的语法格式如下:
<jsp:plugin>
type="bean | applet"
name="Applet名称"
code="java类名"
codebase="Java类所在目录"
align="对齐方式"
height="高度"
width="宽度"
hspace="水平间距"
vspace="垂直间距"
archive="预先加载的类列表"
jreversion="JRE版本"
iepluginurl="URL"
nspluginurl="URL"
</jsp:plugin>
各属性及属性名称如下所示 | |
---|---|
属性 | 属性作用 |
type | 用来指定插件类型, 可以是Bean和Applet |
name | 用来指定Applet或Bean名称 |
code | 用来指定所执行的Java类名, 必须以class结尾 |
codebase | 用来指定所执行的Java类所在的目录 |
align | 用来指定Applet或Bean显示时的对齐方式 |
height | 用来指定Applet或Bean显示时的高度 |
width | 用来指定Applet或Bean显示时的宽度 |
hspace | 用来指定Applet或Bean显示时的距离屏幕左右的距离, 单位是像素 |
vspace | 用来指定Applet或Bean显示时的距离屏幕上下的距离, 单位是像素 |
archive | 用来指定Applet或Bean执行前预先加载的类的列表 |
iepluginurl | 用来指定IE用户能够使用的JRE下载地址 |
nspluginurl | 用来指定Netscape Navigator用户能够使用的JRE下载地址 |
注: 网上抄的例子,因为我是mac说我组件不匹配,我也不知道是否能成功
// 文件地址: ./src/main/webapp/JSP行为/plugin/
// 文件名称: MyApplet.java
package JSP行为.plugin;
import javax.swing.*;
import java.awt.*;
public class MyApplet extends JApplet {
String img;
@Override
public void paint(Graphics g) {
Image image = getImage(getCodeBase(), img);
//绘制一张图片
g.drawImage(image, 0, 0, 400, 400, this);
g.setColor(Color.blue);
g.setFont(new Font("宋体", 2, 24));
//绘制一个字符串
g.drawString("jsp:plugin-test", 40, 170);
g.setColor(Color.pink);
g.setFont(new Font("NewsRoman", 2, 10));
//绘制一个日期字符串
g.drawString(new java.util.Date().toString(), 10, 109);
}
@Override
public void init() {
//获取plugin指令中的参数
img = getParameter("image");
}
}
// 文件地址: ./src/main/webapp/JSP行为/plugin/
// 文件名称: index.jsp
<%@ page language="java" contentType="text/html;charset=utf-8" %>
<html>
<head>
<meta charset="utf-8">
<title>jsp:plugin动作标签</title>
</head>
<body>
<h2>jsp:plugin动作标签</h2>
<jsp:plugin align="middle" type="applet" code="JSP行为.plugin.MyApplet" codebase="." width="200" height="200">
<jsp:params>
<jsp:param name="image" value="test.png"/>
</jsp:params>
<jsp:fallback>error happens when insert applet</jsp:fallback>
</jsp:plugin>
</body>
</html>
// 打开: http://127.0.0.1:8081/mavenJspTest_war/JSP行为/plugin/index.jsp
0x06.2.5 jsp:element/jsp:attribute/jsp:body
// jsp:element使用详解
<jsp:element name="e">
...
</jsp:element>
name: XML元素标签的名称
注意:
<jsp:element>中可以包含<jsp:attributee>和<jsp:body>
它只有一个属性name,name的值就是XML元素标签的名称
// jsp:attribute使用详解
<jsp:element name="e">
<jsp:attribute name="a">
...
</jsp:attribute>
</jsp:element>
name: XML元素标签的名称
// jsp:body使用详解
<jsp:element name="e">
<jsp:body>
...
</jsp:body>
</jsp:element>
// 文件地址: ./src/main/webapp/JSP行为/attribute/
// 文件名称: test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:element name="xmlElement1">
<jsp:attribute name="xmlElementAttr1">${param.test1}</jsp:attribute>
<jsp:body>jsp:body1</jsp:body>
</jsp:element>
<jsp:element name="xmlElement2">
<jsp:attribute name="xmlElementAttr2"><%=request.getParameter("test2")%></jsp:attribute>
<jsp:body>jsp:body2</jsp:body>
</jsp:element>
// 打开: http://127.0.0.1:8081/mavenJspTest_war/JSP行为/attribute/test.jsp?test1=test1111&test2=test2222
0x06.2.6 jsp:text
<jsp:text>允许在JSP页面和文档中使用写入文本的模板
<jsp:text>不能包含其它动作元素,只能只能包含文本和EL表达式
// jsp:text使用详解
jsp:text的语法为: <jsp:text>模板数据</jsp:text>
// 文件地址: ./src/main/webapp/JSP行为/text/
// 文件名称: a.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>jsp:text</title>
</head>
<body>
<jsp:text>${param.value}</jsp:text>
<jsp:text>模板数据</jsp:text>
<jsp:text>
EL表达式测试2*2=${2*2}
</jsp:text>
</body>
</html>
// 打开: http://127.0.0.1:8081/mavenJspTest_war/JSP行为/text/a.jsp?value=测试