簡化版設計之初就是為了從當前頁作用域對象讀取數據並輸出,所以從 request,session,application 讀取數據並輸出時應該避免使用簡化版EL表達式 ...
JSP 规范:
JSP 规范介绍:
-
来自于 JAVAEE 规范中的一种
-
JSP 规范制定了如何开发 JSP 文件代替响应对象将处理结果写入到响应体的开发流程
-
JSP 规范制定了 Http 服务器应该如何调用管理 JSP 文件
响应对象存在弊端:
-
适合将数据量较少的处理结果写入到响应体
-
如果处理结果数量过多,响应对象会增加开发难度
JSP 文件优势:
-
JSP 文件在互联网通信过程,是响应对象的替代品
-
降低将处理结果写入到响应体的开发工作量,降低处理结果维护难度
-
在 JSP 文件开发时,可以直接将处理结果写入到 JSP 文件不需要手写 print 命令,在 Http 服务器调用 JSP 文件时,根据 JSP 规范要求自动的将 JSP 文件书写的内容通过输出流写入到响应体
HTML 文件与 JSP 文件的区别:
-
资源文件类型不同:HTML 文件属于静态资源文件,其相关命令需要浏览器编译并执行;JSP文件属于动态资源文件,其相关命令需要在服务端编译并执行
-
调用形式不同:如果浏览器访问 HTML 文件,此时 Http 服务器直接通过一个输出流,将 HTML 文件中所有的内容写入到响应体;如果浏览器访问 JSP 文件。此时 Http 服务器根据JSP 规范来操作 JSP 文件【编辑---->编译----->调用】
JSP 文件运算原理
-
Tomcat 根据 JSP 规范,将被访问的 JSP 文件【编辑】为一个 java 文件,这个 Java 文件是 Servlet 接口实现类
(Tomcat 将 JSP 文件编辑后生成的 Java 文件,继承于 HttpJspBase,通过 Apache 官方文档查看其身份是 HttpServlet 的子类,所以 Tomcat 将 JSP 编辑为的文件是一个 Servlet 接口实现类)
-
Tomcat 根据 JSP 规范,调用 JVM,将这个java文件【编译】为 class 类型
(Http服务器【编辑】与【编译】JSP 文件的位置 --- work 文件夹)
-
Tomcat 根据 JSP 规范负责生成这个 class 文件的实例对象,这个实例对象是一个 Servelt 接口实例对象
-
Tomcat 根据 JSP 规范通过实例对象调用 class 文件中 _jspService 方法
-
_jspService 方法在运行时负责将 JSP文件中书写内容写入到响应体中
_jspService 方法:
- 作用:当一个 JSP 文件被访问时,Tomcat 调用的并不是当前 JSP 文件。而是 JSP 文件对应的 Servlet接口 实现类中 _jspService 方法,_jspService 方法负责将开发人员在 JSP 文件书写的所有内容写入到响应体中。
- 内部结构:【判断当前请求方式】Jsp 文件可以接收的请求方式有 POST,GET,HEAD
【声明局部变量】这些局部变量都可以在 JSP 文件开发时直接使用
【输出部分】这部分执行时将 JSP 文件内容通过输出流写入到响应体
在JSP文件中如何书写Java命令:
- 命令格式:
<%
这里随便写 java 代码
%>
<%=java的变量名%>
<%=java的表达式%>
- 命令作用:通知 Http 服务器将 JSP 文件中 Java 命令与其他普通执行结果进行区分;通知Tomcat将输出标记中【变量的值】或者输出标记中【表达式运算结果】写入到响应体
如何将 Servlet 中 doGet / doPost 方法执行结果交给 JSP 文件输出?
-
JSP 文件被访问时,并不是 JSP 文件在执行。而是对应的 Servlet 在执行
-
自定义 Serlvet 接口实现类与 JSP 文件之间的调用关系,等同于两个 Servlet 之间的调用关系
-
自定义 Servelt 接口实现类与 JSP 文件之间可以通过重定向方案或者请求转发方案进行调用,考虑到运行效率问题,一般采用【请求转发】
-
自定义 Servlet 接口实现类可以通过请求作用域对象将共享数据交给 JSP 来输出到响应体
EL 表达式:
EL 工具包介绍:
-
由 Java 技术开发一个的 jar 包
-
作用:降低 JSP 文件开发时 Java 命令开发强度
-
Tomcat 服务器本身自带了 EL 工具包
JSP文件中主要开发步骤:
【将作用域中存放的处理结果读取出来并写入到响应体】
-
第一步:从指定的作用域对象读取处理结果
-
第二步::将得到数据进行类型强转
-
第三步::将转换后的数据写入到响应体
<%
String value = (String)request.getAttribute("key");
%>
<%=value%>
EL 表达式命令格式:
${作用域对象别名.共享数据名}
- 命令作用执行时从指定的【作用域对象】中读取指定【共享数据】的内容并自动的写入到响应体中
- EL 提供 . 和 [ ] 两种运算符来导航数据。下列两者所代表的意思是一样的:
${sessionScope.user.sex}
${sessionScope.user["sex"]}
- . 和 [ ] 也可以同时混合使用,如下:
${sessionScope.shoppingCart[0].price}
- 当要存取的属性名称中包含一些特殊字符,如. 或 – 等并非字母或数字的符号,就一定要使用 [ ]
例如:${user.My-Name } //错误示范
${user["My-Name"] } //正确格式
- EL 表达式支持运算表达式:数学运算表达式 / 关系运算表达式 / 逻辑运算表达式
简化版 EL 表达式:
- 命令格式:${作用域对象别名}
- 工作原理:由于在EL简化版中没有指定作用域对象别名,所以EL表达式采用"猜测算法"
- 猜测算法:首先到【pageContext】定位共享数据,如果定位成功读取输出并结束执行;
如果在【pageCotnext】没有找到共享数据,到【request】定位共享数据,如果定位成功读取输出并结束执行;
如果在【request】没有找到共享数据,到【session】定位共享数据,如果定位成功读取输出并结束执行;
如果在【session】没有找到共享数据,到【application】定位共享数据,如果定位成功读取输出并结束执行;
如果在【application】没有找到共享数据,此时返回 null。
- 弊端:增加程序运行时间;可能导致定位数据错误。
- 使用场景:简化版设计之初就是为了从当前页作用域对象读取数据并输出,所以从 request,session,application 读取数据并输出时应该避免使用简化版。
EL 表达式将引用类型数据类型的属性输出:
- 命令格式:${作用域对象别名.共享数据名.属性名}
- 命令作用:从作用域对象读取到指定的引用变量,并将引用变量中指定属性内容写入到响应体