JavaWeb--服务器渲染技术(JSP+EL+JSTL)
JavaWeb--服务器渲染技术(JSP+EL+JSTL)
JSP
基本概念
-
JSP 全称是 Java Server Pages,Java 的服务器页面
-
JSP 这门技术的最大的特点在于,写 JSP 就像在写 HTML
- 相比 html 而言,html 只能为用户提供静态数据,而 JSP 技术允许在页面中嵌套 java 代码,为用户提供动态数据
- 相比 Servlet 而言,Servlet 很难对数据进行排版,而 jsp 除了可以用 java 代码产 生动态数据的同时,也很容易对数据进行排版
-
jsp 技术基于 Servlet, 你可以理解成 JSP 就是对 Servlet 的包装
-
会使用 JSP 的程序员, 再使用 thymeleaf 是非常容易的事情, 几乎是无缝接轨
运行原理
-
jsp 页面本质是一个 Servlet 程序, 其性能是和 java 关联的, 只是长得丑
-
第 1 次访问 jsp 页面的时候。Tomcat 服务器会把 jsp 页面解析成为一个 java 源文件。
并 且 对 它 进 行 编 译 成 为 .class 字 节 码 程 序
-
可以看出本质就是 Servlet
page指令
<%@ page contentType="text/html;charset=utf-8" language="java"%>
- language: 表示jsp翻译后是什么语言文件,目前只支持java
- contentType:表示jsp返回的数据类型,对应源码中 response.setContenttype()参数值
- pageEncoding属性: 表示jsp页面文件本身的字符集
- import 属性:用于导入包、类
三种常用脚本
声明脚本
语法: <%! 声明 java 代码 %>
作用: 定义jsp的需要属性、方法、静态代码块和内部类等
应用:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
jsp声明脚本
jsp声明脚本
<%!
//这里我们可以声明该jsp需要使用的属性,方法,静态代码块, 内部类
//也就是给 statement.jsp 对应的 statement_jsp 类定义成员
//1. 属性
private String name = "jack";
private int age;
private static String company;
//2 方法
public String getName() {
return name;
}
//3. 静态代码块
static {
company = "字节跳动";
}
%>
表达式脚本
语法:<%=表达式%>
作用:在jsp页面上输出数据
注意:其中的表达式不能以分号结束
应用:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
表达式脚本的使用
个人信息
<%
String name = "老韩";
String email = request.getParameter("email");
%>
用户名: <%=name%>
工作是: <%="java工程师"%>
年龄: <%=request.getParameter("age")%>
电邮: <%=email%>
代码脚本
语法: <% java代码 %>
作用: 在JSP页面中,编写我们需要的功能(使用java,就像在servlet doGet等方法中)
注意: 可以由多个代码脚本块组合完成一个完整的java语句,也可以配合表达式脚本一起组合使用,输出数据
应用:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
演示代码脚本
演示代码脚本
<%
//创建ArrayList ,放入两个monster对象
ArrayList monsterList = new ArrayList<>();
monsterList.add(new Monster(1, "牛魔王", "芭蕉扇"));
monsterList.add(new Monster(2, "蜘蛛精", "吐口水"));
%>
id
名字
技能
<%
for (int i = 0; i < monsterList.size(); i++) {
//先取出monster对象
Monster monster = monsterList.get(i);
%>
<%=monster.getId()%>
<%=monster.getName()%>
<%=monster.getSkill()%>
<%
}
%>
注释
<%-- jsp注释 --%>
// java注释
内置对象
JSP内置对象(已经创建好的对象,直接使用inbuild),是指Tomcat在翻译jsp页面成为
Servlet后,内部提供的九大对象,叫内置对象,可以直接使用,不需要手动定义
-
out向客户端输出数据,out.println("");
-
request客户端的http请求
-
response响应对象
-
session会话对象
-
application对应ServletContext
-
pageContextjsp页面的上下文,是一个域对象,可以setAttribue(),作用范围只是本页面
-
exception异常对象,getMessage()
-
page代表jsp这个实例本身
-
config对应ServletConfig
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
jsp内置对象
jsp内置对象
<%
//老韩梳理jsp的内置对象
//out 类型是 JspWriter 父类就是 Writer.
out.println("jsp out");
//request是HttpServletRequest
request.getParameter("age");
//response就是 HttpServletResponse
//response.sendRedirect("http://www.baidu.com");
//session 就是 HttpSession
session.setAttribute("job", "PHP工程师");
//application类型就是ServletContext
application.setAttribute("name", "老韩老师");
//pageContext 可以存放数据(属性), 但是该数据只能在本页面使用
pageContext.setAttribute("age", 100);
//exception 异常对象 使用比较少
//page 内置对象,类似 this
out.println("page=" + page);
//config 内置对象的类型就是ServletConfig
String pwd = config.getInitParameter("pwd");
%>
age: <%=pageContext.getAttribute("age")%>
域对象
作用就是为了存取数据
- pageContext(域对象,存放的数据只能在当前页面使用)
- request(域对象,存放的数据在一次request请求有效)
- session(域对象,存放的数据在一次会话有效)
- application(域对象,存放的数据在整个web应用运行期间有效,范围更大)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
scope文件
<%
//在不同的域对象中,放入数据
//1. 因为四个域对象,是不同的对象,因此name(key) 相同时,并不会冲突
pageContext.setAttribute("k1", "pageContext数据(k1)");
request.setAttribute("k1", "request数据(k1)");
session.setAttribute("k1", "session数据(k1)");
application.setAttribute("k1", "application数据(k1)");
//做一个请求转发的操作
//路径应该怎么写,请不清楚地小伙伴,参考web路径笔记
//request.getRequestDispatcher("/scope2.jsp").forward(request, response);
//做一个重定向
String contextPath = request.getContextPath();//返回的就是 web路径=>/jsp
//response.sendRedirect("/jsp/scope2.jsp");
response.sendRedirect(contextPath + "/scope2.jsp");
%>
四个域对象,在本页面获取数据的情况
pageContext-k1: <%=pageContext.getAttribute("k1")%>
request-k1: <%=request.getAttribute("k1")%>
session-k1: <%=session.getAttribute("k1")%>
application-k1: <%=application.getAttribute("k1")%>
-----
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
scope2.js
在scope2页面获取数据的情况
pageContext-k1: <%=pageContext.getAttribute("k1")%>
request-k1: <%=request.getAttribute("k1")%>
session-k1: <%=session.getAttribute("k1")%>
application-k1: <%=application.getAttribute("k1")%>
注意事项
- 域对象可以像map一样存取数据的对象,四个域对象功能一样,仅仅是它们对数据的存储范围有差别
- 从存储范围(作用域)比较:pageContext < request < session < application
转发标签
它的功能就是请求转发page属性设置请求转发的路径
// 转发请求
EL表达式
EL表达式全称:ExpressionLanguage,是表达式语言
EL表达式主要是代替jsp页面的表达式脚本<%=request.getAttribute("xx")%>
EL表达式输出数据的时,比jsp的表达式脚本简洁
EL表达式基本语法:${key1},你可以理解就是一个语法糖
EL表达式在输出null时,输出的是"",jsp表达式脚本输出null的时,输出的是"null"字符串
EL表达式常用输出Bean的普通属性、数组属性、List集合属性和map集合属性
演示EL常用输出使用
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
el 表达式输出数据演示
el 表达式输出数据演示
<%
//创建Book 对象,放入相关的属性
//private String name;//书名
//private String[] writer;//作者
//private List reader;//读者
//private Map topics;//评讲
Book book = new Book();
book.setName("昆虫总动员");
book.setWriter(new String[]{"jack", "tom"});
ArrayList readers = new ArrayList<>();
readers.add("老韩");
readers.add("老李");
book.setReader(readers);//放入readers
//创建topics
HashMap topics = new HashMap<>();
topics.put("topic1", "这是我看过的最好的动画片");
topics.put("topic2", "不错的电影~~");
book.setTopics(topics);
//把book 放入到request域对象
request.setAttribute("bookkey", book);
%>
book对象: ${bookkey}
book.name= ${bookkey.name}
book.writer= ${bookkey.writer}
book.writer[0]= ${bookkey.writer[0]}
book.readers= ${bookkey.reader}
book.readers第2个= ${bookkey.reader.get(1)}
book.readers第2个= ${bookkey.reader[1]}
book.topics= ${bookkey.topics}
book.topics第一个评论= ${bookkey.topics["topic1"]}
运算
- 关系运算
- 逻辑运算
- 算数运算
-
empty运算
-
可以判断一个数据是否为空,如果为空,返回true,否则返回false
-
以下情况满足为空
- 值为null
- 值为空串的时
- 值是Object类型数组,长度为零
- list集合,元素个数为零
- map集合,元素个数为零
-
应用
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
el empty的运算 el empty的运算
<% request.setAttribute("k1", null); request.setAttribute("k2", ""); request.setAttribute("k3", new Object[]{}); request.setAttribute("k4", new ArrayList<>()); request.setAttribute("k5", new HashMap<>()); request.setAttribute("score", 70); %> k1是否为空= ${empty k1}
k2是否为空= ${empty k2}
k3是否为空= ${empty k3}
k4是否为空= ${empty k4}
k5是否为空= ${empty k5}
是否及格= ${score >= 60 ? "及格": "不及格"}
-
-
三元运算
${布尔条件表达式 ? 真值:假值}
隐含对象
EL四个特定域变量
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
演示el的四个常用的隐藏对象(域对象)
演示el的四个常用的隐藏对象(域对象)
<%
request.setAttribute("k1", "request-k1数据");
pageContext.setAttribute("k1", "pageContext-k1数据");
session.setAttribute("k1", "session-k1数据");
application.setAttribute("k1", "application-k1数据");
%>
jsp脚本方式获取
request域中的k1= <%=request.getAttribute("k1")%>
el方式来获取域对象的数据
request域中的k1= ${requestScope.k1}
pageContext域中的k1= ${pageScope.k1}
session域中的k1= ${sessionScope.k1}
application域中的k1= ${applicationScope.k1}
pageContext对象的使用
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
pageContext 对象的使用
pageContext 对象的使用
<%--
//通过request对象来获取和HTTP协议相关的数据
request.getScheme() 它可以获取请求的协议
request.getServerName() 获取请求的服务器 ip 或域名
request.getServerPort() 获取请求的服务器端口号
getContextPath() 获取当前工程路径
request.getMethod() 获取请求的方式(GET 或 POST)
request.getRemoteHost() 获取客户端的 ip 地址
session.getId() 获取会话的唯一标识
--%>
<%--老韩解读
1.我们可以通过pageContext.request.xx 俩获取和http协议相关的信息
2.相当于替代 request.getMethod()....
--%>
协议: ${ pageContext.request.scheme }
服务器 ip:${ pageContext.request.serverName }
服务器端口:${ pageContext.request.serverPort }
工程路径:${ pageContext.request.contextPath }
请求方法:${ pageContext.request.method }
客户端 ip 地址:${ pageContext.request.remoteHost }
会话id :${ pageContext.session.id }
使用jsp表达式脚本获取如上信息
ip地址: <%=request.getRemoteHost() %>
使用el表达式形式获取信息-简化写法
<%
pageContext.setAttribute("req", request);
%>
ip地址(简化获取): ${req.remoteHost}
获取请求方法(简化获取): ${req.method}
JSTL标签库
JSTL标签库是指JSPStandardTagLibraryJSP标准标签库
EL表达式是为了替换jsp中的表达式脚本,JSTL是为了替换代码脚本。这样jsp页面变得更佳简洁
五个标签库
使用需要导入jar包:taglibs-standard-impl-1.2.1.jar、taglibs-standard-spec-1.2.1.jar
快速入门
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
jstl的快速入门
jstl的快速入门
<%--老韩解读
1. c:if ... 类似
2. if(10>2){
out.println("10 > 2 成立~
")
}
--%>
10 > 2 成立~
注意事项
- taglib引入标签,要放行首
- 导入jstl jar包后,要重新发布web工程,否则不识别jstl
core核心库
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
c:set标签的使用
c:set标签的使用
<%--<%--%>
<%-- //Java代码--%>
<%-- request.setAttribute("email", "hsp@sohu.com");--%>
<%--%>--%>
<%--老韩解读
set 标签可以往域中保存数据
1. 等价 域对象.setAttribute(key,value);
2. scope 属性设置保存到哪个域
page 表示 PageContext 域(默认值)
request 表示 Request 域
session 表示 Session 域
application 表示 ServletContext 域
3. var 属性设置 key 是什么
4. value 属性设置值
--%>
c:set-name的值${requestScope.name}
------
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: 韩顺平
Version: 1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
c:if标签使用
${num1} > ${num2}
------
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: 韩顺平
Version: 1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
c:choose标签的使用
c:choose标签的使用
<%
request.setAttribute("score", 50);
//request.setAttribute("k1", "request-k1的值");
//session.setAttribute("k1", "session-k1的值");
//application.setAttribute("k1", "application-k1的值");
//pageContext.setAttribute("k1", "pageContext-k1的值~");
%>
<%--老师多说一句
1. 如果${requestScope.score} 那么就明确的指定从request域对象取出数据
2. 如果${score}, 这是就按照从小到大的域范围去获取 pageContext->request->session->application
3. 一会老韩给小伙伴验证一把.
--%>
k1=${k1}
${score}-成绩优秀
${score}-成绩一般, 及格了
${score}-没有及格,下次努力~
------
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="com.hspedu.entity.Monster" %>
<%--
Created by IntelliJ IDEA.
User: 韩顺平
Version: 1.0
--%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--
Created by IntelliJ IDEA.
User: 韩顺平
Version: 1.0
Filename: jstl_foreach
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
c:forEach 标签
c:forEach 标签
第1种遍历方式从i到j
<%--
1.遍历 1 到 5,
2. 输出 begin 属性设置开始的索引 end 属性设置结束的索引
3. var 属性表示循环的变量(也是当前正在遍历到的数据)
4. 等价 for (int i = 1; i <= 5; i++) {}
5. 在默认情况下, i 每次会递增1
--%>
- 排名=${i}
第2种遍历方式:遍历数组
<%
request.setAttribute("sports", new String[]{"打篮球", "乒乓球"});
%>
<%--
1. items 遍历的集合/数组
2. var 遍历到的数据
3. 等价 for (Object item: arr) {}
--%>
运动名称= ${sport}
第3种遍历方式:遍历Map
<%
Map map = new HashMap<>();
map.put("key1", "北京");
map.put("key2", "上海");
map.put("key3", "天津");
request.setAttribute("cities", map);
%>
<%--
1. items 遍历的map集合
2. var 遍历到的数据
3. entry.key 取出key
4. entry.value 取出值
--%>
城市信息: ${city.key}--${city.value}
第4种遍历方式:遍历List
<%
List monsters = new ArrayList<>();
monsters.add(new Monster(100, "小妖怪", "巡山的"));
monsters.add(new Monster(200, "大妖怪", "做饭的"));
monsters.add(new Monster(300, "老妖怪", "打扫位置的"));
request.setAttribute("monsters", monsters);
%>
<%--
items 表示遍历的集合
var 表示遍历到的数据
begin 表示遍历的开始索引值 ,从0开始计算
end 表示结束的索引值
step 属性表示遍历的步长值
varStatus 属性表示当前遍历到的数据的状态,可以得到step,begin,end等属性值
//老师提示, 对于jstl标签,能看懂,会使用即可
--%>
妖怪的信息: ${monster.id}-${monster.name}-${monster.skill}