您现在的位置是:首页 >技术交流 >服务器端渲染技术网站首页技术交流

服务器端渲染技术

吉冈秀隆(赵志伟) 2023-05-23 06:48:29
简介服务器端渲染技术

1. JSP基本介绍

e

  1. JSP全称是Java Server Pages, 即Java的服务器页面, 就是服务器端渲染技术
  2. JSP这门技术的最大的特点是, 写JSP就像在写HTML
  3. 相比html而言, html只能为用户提供静态数据, 而JSP(Java Server Pages)技术允许在页面中嵌套java代码, 为用户提供动态数据
  4. 相比Servlet而言, Servlet很难对数据进行排版, 而JSP(Java Server Pages)除了可以用java代码产生动态数据的同时, 也很容易对数据进行排版
  5. JSP技术基于Servlet, 可以理解成就是Servlet

1.1 JSP快速入门

  1. 新建java项目
    在这里插入图片描述
  2. 引入web框架
    在这里插入图片描述
    在这里插入图片描述
  3. 新建lib目录->导入servlet-api.jar, jsp-api.jar
    在这里插入图片描述
  4. 在web工程路径下新建jsp
    在这里插入图片描述
  5. 配置Tomcat
    在这里插入图片描述
  6. 运行结果
    在这里插入图片描述
    在这里插入图片描述
  7. 注意事项和细节
    jsp->(java server pages) 页面不能像HTML页面, 直接用浏览器运行, 只能是浏览器通过Tomcat来访问jsp页面
  8. 如何设置jsp模板
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.2 JSP(Java Server Pages)运行原理

  1. jsp(java server pages)页面本质是一个Servlet程序(本质就是java程序).
  2. 第1次访问jsp(java server pages)页面的时候, Tomcat服务器会把jsp页面解析成一个java源文件, 并且对它编译为.class字节码程序. 参考sum.jsp对应的sum_jsp.java和sum_jsp.class文件
  1. sum_jsp.java是sum.jsp对应的servlet
  2. sum_jsp.class是对应的字节码文件
  3. 这两个文件在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” %>

  1. language表示jsp翻译后是什么语言文件, 但是只支持java, 其它的不支持
  2. contentType表示jsp返回的数据类型, 对应源码中response.setContentType()的参数值
  3. pageEncoding属性 表示当前jsp页面文件本身的字符集
  4. import属性跟java源码中的一样, 用于导包, 导类

1.4 JSP脚本

1.4.1 声明脚本

  1. 声明脚本的格式: <%! 声明java代码 %>
  2. 作用: 定义jsp需要的属性, 方法, 静态代码块和内部类…
    在这里插入图片描述
    对应的statement_jsp 类
    在这里插入图片描述

1.4.2 表达式脚本

  1. 表达式脚本的格式是: <%=表达式%>
  2. 表达式脚本的作用是: 在jsp(java server pages)页面上输出数据
  3. 脚本中的表达式不能以分号结束
    在这里插入图片描述
    在这里插入图片描述

1.4.3 java代码脚本

  1. 代码脚本的语法是: <% java代码 %>
  2. 代码脚本的作用是: 可以在jsp页面中(用java)编写我们需要的功能
  3. 可以由多个代码脚本块组合完成一个完整的java语句
  4. 代码脚本还可以和表达式脚本一起组合使用, 在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内置对象

  1. JSP内置对象(即已经创建好的对象, 直接使用 英文名-inbuild), 是指Tomcat在翻译jsp页面成为Servlet后, 内部提供的九大对象, 叫内置对象
  2. 内置对象, 可以直接使用, 不需要手动定义
  1. out 向客户端输出数据 out.println(“”);
    在这里插入图片描述
    在这里插入图片描述
  2. request 客户端的http请求
    在这里插入图片描述
    在这里插入图片描述
  1. response 响应对象
    在这里插入图片描述
    在这里插入图片描述
  2. session 会话对象
    在这里插入图片描述
    在这里插入图片描述
  3. application 对应ServletContext
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  4. pageContext (jsp独有) jsp页面的上下文, 是一个域对象, 可以setAttribute(), 作用范围只是本页面
    在这里插入图片描述
    在这里插入图片描述
  5. exception异常对象, 使用比较少(jsp独有) getMessage()
  6. page对象(jsp独有) 代表jsp这个实例本身在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  7. config 对应ServletConfig在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

1.7 JSP四大域对象

  1. pageContext(域对象, 存放的数据只能在当前页面使用)
    在这里插入图片描述
  2. request(域对象, 存放的数据在一次request请求中有效, 数据和request对象绑定)
    在这里插入图片描述
  3. session(域对象, 存放的数据在一次会话中有效)
    在这里插入图片描述
  4. application(域对象, 存放的数据在整个web应用运行期间有效, 范围更大)
    在这里插入图片描述

1.7.1 域对象实例

  1. 请求转发
    在这里插入图片描述
    在这里插入图片描述
  2. 重定向
    在这里插入图片描述
    在这里插入图片描述
  3. 打开一个新的浏览器定位scope2.jsp
    在这里插入图片描述

1.7.2 注意事项

  1. 域对象是可以向Map一样存取数据的对象. 四个域对象功能一样, 不同的是它们对数据的存储范围
  2. 从存储范围(作用域范围看) pageContext < request < session < application

1.8 JSP请求转发标签

在这里插入图片描述

1.9 作业布置

calServlet

tips:

  1. Java中, 整数运算除数为0会抛异常;
  2. 浮点类型的除法运算除数为0会得到Infinity, 表示无限大, 运算并不会抛异常, 判断一个数是否是无限大, 用Double.isInfinite();
  3. 如果在浮点类型的除法运算中, 被除数和除数都为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表达式快速入门

  1. EL表达式全称: Expression Language, 是表达式语言
  2. EL表达式主要是代替jsp页面的表达式脚本
  3. EL表达式输出数据时, 比jsp的表达式脚本简洁
  4. EL表达式基本语法: ${key1}
  5. EL表达式在输出null时, 输出的是""
  6. 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运算

  1. empty运算可以判断一个数据是否为空, 如果为空, 返回true, 否则返回false
  2. 以下几种情况为空
  • 值为null
  • 值为空串
  • 值是Object类型数组, 长度为零
  • list集合, 元素个数为零
  • map集合, 元素个数为零
    在这里插入图片描述
    在这里插入图片描述
  • 三元运算
    在这里插入图片描述

2.5 EL获取四个域数据

变量类型说明
pageContextPageContextImpl获取jsp中的九大内置对象
pageScopeMap<String, Object>获取pageContext域中的数据
requestScopeMap<String, Object>获取Request域中的数据
sessionScopeMap<String, Object>获取Session域中的数据
applicationScopeMap<String, Object>获取ServletContext域中的数据

在这里插入图片描述
在这里插入图片描述

2.6 EL获取HTTP相关信息

在这里插入图片描述
在这里插入图片描述

3. JSTL标签库

3.1 jstl 快速入门

  1. JSTL标签库是指 JSP Standard Tag Library(JSP标准标签库)
  2. EL表达式是为了替换jsp中的表达式脚本, JSTL是为了替换代码脚本. 这样jsp页面变得更加简洁
  3. JSTL由五个标签库组成
功能范围URI前缀
核心标签库http://java.sun.com/jsp/jstl/corec
格式化http://java.sun.com/jsp/jstl/fmtfmt
函数http://java.sun.com/jsp/jstl/functionsfn
数据库http://java.sun.com/jsp/jstl/sqlsql
XMLhttp://java.sun.com/jsp/jstl/xmlx
  1. 使用JSTL, 需要导入相关的jar包, 即taglibs-standard-impl-1.2.1.jar, taglibs-standard-spec-1.2.1.jar
    在这里插入图片描述

3.2 <c:set/>标签

  1. 介绍: <c:set scope=“request” var=“username” value=“赵志伟”/>

<c:set />标签可以往域中存放数据

  1. 等价于 域对象.setAttribute(key, value);
  2. scope属性 设置保存到哪个域
    page表示PageContext域 (如果不写, 默认值)
    request表示Request域
    session表示Session域
    application表示ServletContext域
  3. var属性 设置key值
  4. value属性 设置值
    在这里插入图片描述

3.3 <c:if/>标签

  1. 介绍: <c:if test=“${10 > 2}”>hello</c:if>

<c:if />

  1. if标签用来做if判断
  2. test属性表示判断的条件(用EL表达式输出)
    在这里插入图片描述

3.4 <c:choose/>标签

  1. 介绍: 多路判断, 跟switch…case…default非常接近
  1. 取值问题
    在这里插入图片描述
    在这里插入图片描述
  2. c:choose标签使用在这里插入图片描述

3.5 <c:forEach/>标签

  1. 介绍: c:forEach标签, 用来遍历输出, 主要有4种形式
  • 普通遍历输出 i 到 j
    在这里插入图片描述
  • 遍历数组
    在这里插入图片描述
  • 遍历Map
    在这里插入图片描述
  • 遍历List
    在这里插入图片描述

3.6 作业布置

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。