服务器渲染技术
一、jsp
1.jsp注意事项
jsp页面不能像HTML页面一样直接用浏览器运行,它只能通过浏览器访问Tomcat来访问jsp页面
如何设置jsp模版
2.jsp运行原理
jsp页面本质是一个Servlet程序,其性能是和java关联的
第一次访问jsp页面的时候。Tomcat服务器会把jsp页面解析成为一个java源文件,并且对它进行编译成为.class字节码程序。sum.jsp对应的sum_jsp.java和sum_jsp.class文件
- sum_jsp.java是jsp对应的Servlet
- sum_jsp.class是对应的字节码文件
- 这两文件在Tomcat启动时的Using CATALINA_BASE:对应的目录下
分析一下sum_jsp.java的源码,可以看出本质就是Servlet
要看源码类图和分析类图,需要加入jasper.jar这个包**[在Tomcat/lib包下]**
看到新的类不要慌,去看熟悉它的继承体系,更便于我们了解这个类或者说技术
3. page指令(常用的)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
language表示jsp翻译后是什么语言文件,只支持java
contentType表示jsp返回的数据类型,对应源码中response.setContentType()参数值
pageEncoding属性表示当前jsp页面文件本身的字符集
import属性跟java源代码中一样,用于导包,导类
4. 声明脚本基本语法
声明脚本的格式是:<%! 声明java代码%>,注意:这个格式声明的属性、方法、静态代码块和内部类等是成员,是属于该jsp所对应的java类的成员
作用:可以在脚本语法中定义jsp需要的属性、方法、静态代码块和内部类等
表达式脚本的格式是:<%= 表达式%>
表达式脚本的作用是:在jsp页面上输出数据
脚本中的表达式不能以分号结束
代码脚本的语法是:<% java代码%>,注意:在这个格式里的代码最后会被解析进_jspService()的方法中,这个方法是该jsp所解析成的java类的方法,请注意,有些是不能在该方法里面声明的:如方法,静态代码块,私有属性等
代码脚本的作用是:可以在jsp页面中,编写我们需要的功能(使用java)
可以由多个代码脚本组合完成一个完整的java语句
代码脚本还可以和表达式脚本一起组合使用,在jsp页面上输出数据
5. jsp内置(inbuild)对象
- JSP内置对象(已经创建好的对象,可以直接使用),是指Tomcat在解析JSP页面成为Servlet后,内部提供的九大对象,叫内置对象。
- 内置对象,可以直接使用,不需要动手定义
- JSP九大内置对象
- out向客户端输出数据,例如out.println("")
- request 客户端的http请求
- response 响应对象
- Session会话对象
- application对应的是ServletContext
- pageContext jsp页面的上下文,是一个域对象,可以setAttribute(),作用范围只是本页面
- exception异常对象对应Exception,获取异常信息getMessage()
- page代表jsp这个实例本身,相当于this
- config对应ServletConfig
- jsp的内置对象来源是Servlet和HttpJspPage
6. jsp四大域对象介绍{作用:存取数据}
pageContext(域对象,存放的数据只能在当前页面使用)
resquest(域对象,存放的数据在一次request请求有效)
session(域对象,存放的数据在一次会话有效)
application(域对象,存放的数据在整个web应用运行期间有效)
7.jsp四大域对象注意事项和细节
- 域对象是可以像Map一样存取数据的对象,四个域对象功能一样。不同的是它们对数据的存储范围不一样
- 从存储范围(作用域范围看)pageContext < reuqest < session <appliaction
二、EL表达式
1.EL表达式的介绍
- EL表达式全称:Expression Language,表达式语言
- EL表达式主要是代替jsp页面的表达式脚本,代替这个<%=request.getAttribute()%>
- EL表达式输出数据的方式比jsp的表达式脚本简洁
- EL表达式基本语法:${ key1}
- EL表达式只能获取域中的数据,如果想要操作数据,就要放进域对象中,然后再用EL表达式来操作
- EL表达式如果你没有指定域对象来获取域对象中的数据默认是从小到大来获取数据
- EL表达式如果输出的数据为空,EL表达式则会输出一个" "
2.EL的empty运算
- empty运算可以判断一个数据是否为空,如果为空返回true,否则返回false
- 以下几种情况为空
- 值为null
- 值为空串的时候
- 值是Object类型数组,长度为零
- List集合,元素个数为零
- Map集合,元素个数为零
3. 获取四大域对象中的数据
EL表达式中的pageContext可以获取jsp中的九大内置对象
<% pageContext.setAttribute("name", "pageContext"); request.setAttribute("name", "request"); session.setAttribute("name", "session"); application.setAttribute("name", "application"); %> 获取pageContext域对象中的数据:${pageScope.name}<br> 获取request域对象中的数据:${requestScope.name}<br> 获取session域对象中的数据:${sessionScope.name}<br> 获取application域对象中的数据:${applicationScope.name}<br>
三、JSTL标签库
1.基本介绍
JSTL标签库是指 JSP Standard Tag Library JSP标准标签库
EL表达式是为了替换jsp中的表达式脚本,JSTL是为了替换JSP代码脚本,这样JSP页面就变得更加简洁
我使用的是Tomcat9的版本,导包遇到了这个问题{org.apache.jasper.JasperException: 无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]}
主要是Tomcat本身没有这个包,需要你把这个几个包导入到Tomcat的lib目录下
你的项目也导入这两个包,以防万一
2.< c:set/ >标签介绍
- 介绍:< c:set scope="request" var="username" value="努力学习">
- < c:set /> set标签可以往域中保存数据
- 等价于 域对象.setAttribute(String key , String name);
- scope属性设置保存到哪个域中
- page表示PageContext域(默认值)
- request表示Request域
- session表示Session域
- application表示ServletContext域
- var属性设置key什么
- value属性设置值
3.< c:if />标签介绍
- 介绍:< c:if test="${10 > 2}" > hello < /c:if >
- if标签用来做if判断,跟java中的if(判断条件){执行体}差不多
- test属性表示判断的条件(用EL表达式输出)
4.< c:choose > < c:when > < c:therwise >标签介绍
可以理解为多路判断,跟switch ...case...default非常接近
test属性是判断条件(EL表达式输出)
注意:可以有多个< c:when >,但是如果满足了其中一个条件,执行完内容后就结束,不会再去判断其他的< c:when >
<c:set scope="request" var="scorce" value="90"></c:set> <c:choose> <c:when test="${scorce >= 90}"> <h1>成绩优秀</h1> </c:when> <c:when test="${scorce >= 80}"> <h1>成绩良</h1> </c:when> <c:when test="${scorce >= 70}"> <h1>成绩合格</h1> </c:when> <c:when test="${scorce >= 60}"> <h1>成绩及格</h1> </c:when> //所有<c:when>不满足就执行这个 <c:otherwise> <h1>成绩太差了</h1> </c:otherwise> </c:choose>
5.< c:forEach >标签介绍
<%
int[] arr = new int[]{1,2,3,8,9,10};
HashMap<String,Object> hashMap = new HashMap<>();
hashMap.put("age",20);
hashMap.put("name","李华");
hashMap.put("sex","女");
ArrayList<Monster> list = new ArrayList<>();
list.add(new Monster("1001","小妖怪","巡山"));
list.add(new Monster("1002","中妖怪","做饭"));
list.add(new Monster("1003","大妖怪","睡觉"));
request.setAttribute("arr",arr);
request.setAttribute("map",hashMap);
request.setAttribute("list",list);
%>
<h1>遍历从1到10的数</h1>
//begin 属性表示开始的数
//end 属性表示结束的数
//var 属性表示接收数据的变量名是什么
//step 属性表示增量是多少
//items 属性表示获取域中的哪个数据
<c:forEach begin="1" end="10" var="i" step="1">
${i}
</c:forEach>
<h1>遍历数组中的数据</h1>
<c:forEach items="${arr}" var="number">
${number}
</c:forEach>
<h1>遍历Map集合</h1>
<c:forEach items="${map}" var="key">
${key.key}-->${key.value}
</c:forEach>
<h1>循环遍历list集合</h1>
<c:forEach items="${list}" var="monster">
妖怪id: ${monster.id}
妖怪name: ${monster.name}
妖怪skill: ${monster.skill}<br>
</c:forEach>