您现在的位置是:首页 >技术交流 >服务器端渲染技术网站首页技术交流
服务器端渲染技术
简介服务器端渲染技术
文章目录
1. JSP基本介绍
- JSP全称是Java Server Pages, 即Java的服务器页面, 就是服务器端渲染技术
- JSP这门技术的最大的特点是, 写JSP就像在写HTML
- 相比html而言, html只能为用户提供静态数据, 而JSP(Java Server Pages)技术允许在页面中嵌套java代码, 为用户提供动态数据
- 相比Servlet而言, Servlet很难对数据进行排版, 而JSP(Java Server Pages)除了可以用java代码产生动态数据的同时, 也很容易对数据进行排版
- JSP技术基于Servlet, 可以理解成就是Servlet
1.1 JSP快速入门
- 新建java项目
- 引入web框架
- 新建lib目录->导入servlet-api.jar, jsp-api.jar
- 在web工程路径下新建jsp
- 配置Tomcat
- 运行结果
- 注意事项和细节
jsp->(java server pages) 页面不能像HTML页面, 直接用浏览器运行, 只能是浏览器通过Tomcat来访问jsp页面- 如何设置jsp模板
1.2 JSP(Java Server Pages)运行原理
- jsp(java server pages)页面本质是一个Servlet程序(本质就是java程序).
- 第1次访问jsp(java server pages)页面的时候, Tomcat服务器会把jsp页面解析成一个java源文件, 并且对它编译为.class字节码程序. 参考sum.jsp对应的sum_jsp.java和sum_jsp.class文件
- sum_jsp.java是sum.jsp对应的servlet
- sum_jsp.class是对应的字节码文件
- 这两个文件在tomcat启动时的Using CATALINA_BASE: 目录下
比如:C:Users97896AppDataLocalJetBrainsIntelliJIdea2022.3 omcat934373ca-74e2-42fa-87e8-55ee0332e30cworkCatalinalocalhostjsporgapachejsp
要想查看HttpJspBase的类图关系, 要引入jasper.jar包
总结:
3. sum.jsp->sum_jsp.java
4. sum_jsp 继承 HttpJspBase
5. HttpJspBase 继承了 HttpServlet
6. 结论: sum.jsp本质就是servlet
7. 因为sum_jsp 类还继承了 HttpJspBase, 所以就有更强的功能
1.3 page指令介绍
<%@ page contentType=“text/html; charset=utf-8” languange=“java” %>
- language表示jsp翻译后是什么语言文件, 但是只支持java, 其它的不支持
- contentType表示jsp返回的数据类型, 对应源码中response.setContentType()的参数值
- pageEncoding属性 表示当前jsp页面文件本身的字符集
- import属性跟java源码中的一样, 用于导包, 导类
1.4 JSP脚本
1.4.1 声明脚本
- 声明脚本的格式: <%! 声明java代码 %>
- 作用: 定义jsp需要的属性, 方法, 静态代码块和内部类…
对应的statement_jsp 类
1.4.2 表达式脚本
- 表达式脚本的格式是: <%=表达式%>
- 表达式脚本的作用是: 在jsp(java server pages)页面上输出数据
- 脚本中的表达式不能以分号结束
1.4.3 java代码脚本
- 代码脚本的语法是: <% java代码 %>
- 代码脚本的作用是: 可以在jsp页面中(用java)编写我们需要的功能
- 可以由多个代码脚本块组合完成一个完整的java语句
- 代码脚本还可以和表达式脚本一起组合使用, 在jsp(java server pages)页面上输出数据
<%@ page import="java.util.ArrayList" %>
<%@ page import="com.zzw.entity.Monster" %><%--
Created by IntelliJ IDEA.
User: 赵志伟
Version: 1.0
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>代码脚本</title>
</head>
<body>
<h1>演示代码脚本</h1>
<%
//创建ArrayList, 存放Monster对象
ArrayList<Monster> monsters = new ArrayList<>();
monsters.add(new Monster("铁扇公主", 3000, "芭蕉扇"));
monsters.add(new Monster("白骨精", 2000, "魅惑"));
%>
<table border="1px">
<tr>
<th>编号</th>
<th>名字</th>
<th>年龄</th>
<th>技能</th>
</tr>
<%
for (int i = 0; i < monsters.size(); i++) {
Monster monster = monsters.get(i);
%>
<tr>
<td><%=i+1%></td>
<td><%=monster.getName()%></td>
<td><%=monster.getAge()%></td>
<td><%=monster.getKill()%></td>
</tr>
<%
}
%>
</table>
</body>
</html>
对应的javacode_jsp 类
1.5 jsp注释
1.6 jsp内置对象
- JSP内置对象(即已经创建好的对象, 直接使用 英文名-inbuild), 是指Tomcat在翻译jsp页面成为Servlet后, 内部提供的九大对象, 叫内置对象
- 内置对象, 可以直接使用, 不需要手动定义
- out 向客户端输出数据 out.println(“”);
- request 客户端的http请求
- response 响应对象
- session 会话对象
- application 对应ServletContext
- pageContext (jsp独有) jsp页面的上下文, 是一个域对象, 可以setAttribute(), 作用范围只是本页面
- exception异常对象, 使用比较少(jsp独有) getMessage()
- page对象(jsp独有) 代表jsp这个实例本身
- config 对应ServletConfig
1.7 JSP四大域对象
- pageContext(域对象, 存放的数据只能在当前页面使用)
- request(域对象, 存放的数据在一次request请求中有效, 数据和request对象绑定)
- session(域对象, 存放的数据在一次会话中有效)
- application(域对象, 存放的数据在整个web应用运行期间有效, 范围更大)
1.7.1 域对象实例
- 请求转发
- 重定向
- 打开一个新的浏览器定位scope2.jsp
1.7.2 注意事项
- 域对象是可以向Map一样存取数据的对象. 四个域对象功能一样, 不同的是它们对数据的存储范围
- 从存储范围(作用域范围看) pageContext < request < session < application
1.8 JSP请求转发标签
1.9 作业布置
calServlet
tips:
- Java中, 整数运算除数为0会抛异常;
- 浮点类型的除法运算除数为0会得到Infinity, 表示无限大, 运算并不会抛异常, 判断一个数是否是无限大, 用Double.isInfinite();
- 如果在浮点类型的除法运算中, 被除数和除数都为0, 会得到NaN, 即非数字, NaN不等于任何值, 要判断是否是NaN, 用Double.isNaN()
public class CalServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String num1 = request.getParameter("num1");
String num2 = request.getParameter("num2");
String oper = request.getParameter("oper");
String regStr = "^[+-]?([1-9]\d*|0)$";
if (Pattern.matches(regStr, num1) && Pattern.matches(regStr, num2)) {
double num_1 = WebUtils.parseDouble(num1, 0);
double num_2 = WebUtils.parseDouble(num2, 0);
double result = 0;
request.setAttribute("oper", oper);
if ("+".equals(oper)) {
result = num_1 + num_2;
} else if ("-".equals(oper)) {
result = num_1 - num_2;
} else if ("*".equals(oper)) {
result = num_1 * num_2;
} else if ("/".equals(oper)) {
result = num_1 / num_2;
if (Double.isInfinite(result)) {
request.setAttribute("num2Error", "除数不能为零");
request.getRequestDispatcher("/cal/cal.jsp").forward(request, response);
} else if (Double.isNaN(result)) {
request.setAttribute("num1Error", "被除数不能为零");
request.setAttribute("num2Error", "除数不能为零");
request.getRequestDispatcher("/cal/cal.jsp").forward(request, response);
}
}
//String.format:格式化字符串
String format = String.format("%s %s %s = %s", num1, oper, num2, result);
request.setAttribute("result", format);
System.out.println(format);
request.getRequestDispatcher("/cal/result.jsp").forward(request, response);
} else {
request.setAttribute("error", "数据格式不正确");
request.getRequestDispatcher("/cal/cal.jsp").forward(request, response);
}
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
}
cal.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%String path = application.getContextPath();%>
<html>
<head>
<title>计算页面</title>
<script type="text/javascript">
function register() {
var num1 = document.getElementById("num1").value;
var num2 = document.getElementById("num2").value;
var regStr = /^[+-]?([1-9]d*|0)$/;
if (!regStr.test(num1)) {
var span_1 = document.getElementById("span_1");
span_1.hidden = false;
return false;
}
if (!regStr.test(num2)) {
alert("num2数字错误");
return false;
}
return true;
};
if (<%=request.getAttribute("error") != null%>) {
alert("<%=request.getAttribute("error")%>");
}
window.onload = function () {
if (<%=request.getAttribute("num2Error") != null%>) {
var span_2 = document.getElementById("span_2");
span_2.hidden = false;
}
if (<%=request.getAttribute("num1Error") != null%>) {
var span_1 = document.getElementById("span_1");
span_1.hidden = false;
}
}
</script>
</head>
<body>
<form action="<%=path%>/calServlet" onsubmit="return register()">
num1: <input type="text" id="num1" name="num1"><span id="span_1" hidden>num1错误:<%=request.getAttribute("num1Error")%></span><br/>
num2: <input type="text" id="num2" name="num2"><span id="span_2" hidden>num2错误:<%=request.getAttribute("num2Error")%></span><br/>
运算符号: <select name="oper">
<option value="+">+</option>
<option value="-">-</option>
<option value="*">*</option>
<option value="/">/</option>
</select><br/>
<input type="submit" value="提交计算"/>
</form>
</body>
</html>
result.jsp
2. EL表达式
2.1 EL表达式快速入门
- EL表达式全称: Expression Language, 是表达式语言
- EL表达式主要是代替jsp页面的表达式脚本
- EL表达式输出数据时, 比jsp的表达式脚本简洁
- EL表达式基本语法: ${key1}
- EL表达式在输出null时, 输出的是""
- jsp表达式脚本输出null时, 输出的是"null"字符串
2.2 EL表达式输出形式
public class Book {
private String name;//书名
private String[] writer;//作者
private List<String> reader;//读者
private Map<String, Object> topics;//评讲
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getWriter() {
return writer;
}
public void setWriter(String[] writer) {
this.writer = writer;
}
public List<String> getReader() {
return reader;
}
public void setReader(List<String> reader) {
this.reader = reader;
}
public Map<String, Object> getTopics() {
return topics;
}
public void setTopics(Map<String, Object> topics) {
this.topics = topics;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + ''' +
", writer=" + Arrays.toString(writer) +
", reader=" + reader +
", topics=" + topics +
'}';
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>el 表达式输出数据演示</title>
</head>
<body>
<h1>el 表达式输出数据演示</h1>
<%
// private String name;//书名
//private String[] writer;//作者
//private List<String> reader;//读者
//private Map<String, Object> topics;//评讲
//创建Book, 放入相关属性
Book book = new Book();
book.setName("雪国");
book.setWriter(new String[]{"川端康成","2"});
ArrayList<String> list = new ArrayList<>();
list.add("赵志伟");
list.add("赵培竹");
book.setReader(list);
Map<String, Object> hashMap = new HashMap<>();
hashMap.put("赵志伟", "讲的不错❤");
hashMap.put("赵培竹", "Love❤");
book.setTopics(hashMap);
//把book对象 放入request域对象
request.setAttribute("bookkey", book);
%>
book对象: ${bookkey}<br/>
book.name: ${bookkey.name}<br/>
book.writer: ${bookkey.writer}<br/>
book.writer[0]: ${bookkey.writer[0]}<br/>
book.readers: ${bookkey.reader}<br/>
book.readere.get(1): ${bookkey.reader.get(1)}<br/>
book.readere[0]: ${bookkey.reader[0]}<br/>
book.topics["赵志伟"]: ${bookkey.topics["赵志伟"]}<br/>
book.topics.get("赵培竹"): ${bookkey.topics.get("赵培竹")}<br/>
</body>
</html>
输出结果
2.3 el运算符
关系运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
== 或 eq | 等于 | ${5 == 5} 或 ${5 eq 5} | true |
!= 或 ne | 不等于 | ${5 != 5} 或 ${5 ne 5} | false |
< 或 lt | 小于 | ${3 < 5} 或 ${3 lt 5} | true |
> 或 gt | 大于 | ${3 > 5} 或 ${3 gt 5} | false |
<= 或 le | 小于等于 | ${3 <= 5} 或 ${3 le 5} | true |
>= 或 ge | 大于等于 | ${3 >= 5} 或 ${3 ge 5} | false |
- 逻辑运算
逻辑运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
&& 或 and | 与运算 | ${12 == 12 && 12 < 11} | false |
或 or | 或运算 | ${12 == 12 | |
! 或 not | 取反运算 | ${ !true } 或 ${not true} | false |
- 算术运算
算数运算符 | 说明 | 范例 | 结果 |
---|---|---|---|
+ | 加法 | ${12 + 12} | 30 |
- | 减法 | ${24 - 12} | 12 |
/ 或 div | 除法 | ${ 144 / 12 } 或 ${ 144 div 12 } | 12 |
% 或 mod | 取模 | ${ 144 % 10 } 或 ${ 144 mod 10 } | 4 |
2.4 empty运算
- empty运算可以判断一个数据是否为空, 如果为空, 返回true, 否则返回false
- 以下几种情况为空
- 值为null
- 值为空串
- 值是Object类型数组, 长度为零
- list集合, 元素个数为零
- map集合, 元素个数为零
- 三元运算
2.5 EL获取四个域数据
变量 | 类型 | 说明 |
---|---|---|
pageContext | PageContextImpl | 获取jsp中的九大内置对象 |
pageScope | Map<String, Object> | 获取pageContext域中的数据 |
requestScope | Map<String, Object> | 获取Request域中的数据 |
sessionScope | Map<String, Object> | 获取Session域中的数据 |
applicationScope | Map<String, Object> | 获取ServletContext域中的数据 |
2.6 EL获取HTTP相关信息
3. JSTL标签库
3.1 jstl 快速入门
- JSTL标签库是指 JSP Standard Tag Library(JSP标准标签库)
- EL表达式是为了替换jsp中的表达式脚本, JSTL是为了替换代码脚本. 这样jsp页面变得更加简洁
- JSTL由五个标签库组成
功能范围 | URI | 前缀 |
---|---|---|
核心标签库 | http://java.sun.com/jsp/jstl/core | c |
格式化 | http://java.sun.com/jsp/jstl/fmt | fmt |
函数 | http://java.sun.com/jsp/jstl/functions | fn |
数据库 | http://java.sun.com/jsp/jstl/sql | sql |
XML | http://java.sun.com/jsp/jstl/xml | x |
- 使用JSTL, 需要导入相关的jar包, 即taglibs-standard-impl-1.2.1.jar, taglibs-standard-spec-1.2.1.jar
3.2 <c:set/>标签
- 介绍: <c:set scope=“request” var=“username” value=“赵志伟”/>
<c:set />标签可以往域中存放数据
- 等价于 域对象.setAttribute(key, value);
- scope属性 设置保存到哪个域
page表示PageContext域 (如果不写, 默认值)
request表示Request域
session表示Session域
application表示ServletContext域- var属性 设置key值
- value属性 设置值
3.3 <c:if/>标签
- 介绍: <c:if test=“${10 > 2}”>hello</c:if>
<c:if />
- if标签用来做if判断
- test属性表示判断的条件(用EL表达式输出)
3.4 <c:choose/>标签
- 介绍: 多路判断, 跟switch…case…default非常接近
- 取值问题
- c:choose标签使用
3.5 <c:forEach/>标签
- 介绍: c:forEach标签, 用来遍历输出, 主要有4种形式
- 普通遍历输出 i 到 j
- 遍历数组
- 遍历Map
- 遍历List
3.6 作业布置
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。