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的idpropertys: 属性名value: 属性值name:name属性是必需的,它表示要设置属性的是哪个Beanproperty: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的idpropertys: 属性名注意:当JavaBean中的属性名为xxx, 而获取该属性值的方法名为getyyy(), 则property="yyy", 而不是property="xxx"
// 文件地址: ./src/main/webapp/JSP行为/useBean/// 文件名称: TestBean.javapackage 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.javapackage JSP行为.plugin;import javax.swing.*;import java.awt.*;public class MyApplet extends JApplet {String img;@Overridepublic 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);}@Overridepublic 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=测试

