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" %>
<html>
<head>
    <title>jsp声明脚本</title>
</head>
<body>
<h1>jsp声明脚本</h1>
<%!
    //这里我们可以声明该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 = "字节跳动";
    }
%>
</body>
</html>

表达式脚本

语法:<%=表达式%>
作用:在jsp页面上输出数据
注意:其中的表达式不能以分号结束
应用:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>表达式脚本的使用</title>
</head>
<body>
<h1>个人信息</h1>
<%
    String name = "老韩";
    String email = request.getParameter("email");
%>
用户名: <%=name%><br/>
工作是: <%="java工程师"%><br/>
年龄: <%=request.getParameter("age")%><br/>
电邮: <%=email%>
</body>
</html>

代码脚本

语法: <% java代码 %>
作用: 在JSP页面中,编写我们需要的功能(使用java,就像在servlet doGet等方法中)
注意: 可以由多个代码脚本块组合完成一个完整的java语句,也可以配合表达式脚本一起组合使用,输出数据
应用:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>演示代码脚本</title>
</head>
<body>
<h1>演示代码脚本</h1>
<%
    //创建ArrayList ,放入两个monster对象
    ArrayList<Monster> monsterList = new ArrayList<>();
    monsterList.add(new Monster(1, "牛魔王", "芭蕉扇"));
    monsterList.add(new Monster(2, "蜘蛛精", "吐口水"));
%>
<table bgcolor="#f0f8ff" border="1px" width="300px">
    <tr>
        <th>id</th>
        <th>名字</th>
        <th>技能</th>
    </tr>
    <%
        for (int i = 0; i < monsterList.size(); i++) {
            //先取出monster对象
            Monster monster = monsterList.get(i);
    %>
            <tr>
                <td><%=monster.getId()%></td>
                <td><%=monster.getName()%></td>
                <td><%=monster.getSkill()%></td>
            </tr>
            <%
        }
    %>

</table>
</body>
</html>

注释

<%-- jsp注释 --%>
<!-- html注释 -->
// java注释

内置对象

JSP内置对象(已经创建好的对象,直接使用inbuild),是指Tomcat在翻译jsp页面成为

Servlet后,内部提供的九大对象,叫内置对象,可以直接使用,不需要手动定义

  1. out向客户端输出数据,out.println("");
  2. request客户端的http请求
  3. response响应对象
  4. session会话对象
  5. application对应ServletContext
  6. pageContextjsp页面的上下文,是一个域对象,可以setAttribue(),作用范围只是本页面
  7. exception异常对象,getMessage()
  8. page代表jsp这个实例本身
  9. config对应ServletConfig
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp内置对象</title>
</head>
<body>
<h1>jsp内置对象</h1>
<%
    //老韩梳理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");
%>
</body>
age: <%=pageContext.getAttribute("age")%>
</html>

域对象

作用就是为了存取数据

  1. pageContext(域对象,存放的数据只能在当前页面使用)
  2. request(域对象,存放的数据在一次request请求有效)
  3. session(域对象,存放的数据在一次会话有效)
  4. application(域对象,存放的数据在整个web应用运行期间有效,范围更大)
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>scope文件</title>
</head>
<body>
<%
    //在不同的域对象中,放入数据
    //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");
%>
<h1>四个域对象,在本页面获取数据的情况</h1>
pageContext-k1: <%=pageContext.getAttribute("k1")%><br/>
request-k1: <%=request.getAttribute("k1")%><br/>
session-k1: <%=session.getAttribute("k1")%><br/>
application-k1: <%=application.getAttribute("k1")%><br/>
</body>
</html>

-----
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>scope2.js</title>
</head>
<body>
<h1>在scope2页面获取数据的情况</h1>
pageContext-k1: <%=pageContext.getAttribute("k1")%><br/>
request-k1: <%=request.getAttribute("k1")%><br/>
session-k1: <%=session.getAttribute("k1")%><br/>
application-k1: <%=application.getAttribute("k1")%><br/>
</body>
</html>

注意事项

  • 域对象可以像map一样存取数据的对象,四个域对象功能一样,仅仅是它们对数据的存储范围有差别
  • 从存储范围(作用域)比较:pageContext < request < session < application

转发标签

它的功能就是请求转发page属性设置请求转发的路径

// 转发请求
<jsp:forwardpage="/bb.jsp"></jsp:forward>

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" %>
<html>
<head>
    <title>el 表达式输出数据演示</title>
</head>
<body>
<h1>el 表达式输出数据演示</h1>
<%
    //创建Book 对象,放入相关的属性
    //private String name;//书名
    //private String[] writer;//作者
    //private List<String> reader;//读者
    //private Map<String, Object> topics;//评讲
    Book book = new Book();
    book.setName("昆虫总动员");
    book.setWriter(new String[]{"jack", "tom"});
    ArrayList<String> readers = new ArrayList<>();
    readers.add("老韩");
    readers.add("老李");
    book.setReader(readers);//放入readers

    //创建topics
    HashMap<String, String> topics = new HashMap<>();
    topics.put("topic1", "这是我看过的最好的动画片");
    topics.put("topic2", "不错的电影~~");
    book.setTopics(topics);

    //把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.readers第2个= ${bookkey.reader.get(1)}<br/>
book.readers第2个= ${bookkey.reader[1]}<br/>

book.topics= ${bookkey.topics}<br/>
book.topics第一个评论= ${bookkey.topics["topic1"]}<br/>

</body>
</html>

运算

  • 关系运算

html渲染引擎 java java渲染页面_html

  • 逻辑运算

html渲染引擎 java java渲染页面_html渲染引擎 java_02

  • 算数运算

html渲染引擎 java java渲染页面_html渲染引擎 java_03

  • empty运算
  • 可以判断一个数据是否为空,如果为空,返回true,否则返回false
  • 以下情况满足为空
  • 值为null
  • 值为空串的时
  • 值是Object类型数组,长度为零
  • list集合,元素个数为零
  • map集合,元素个数为零
  • 应用
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>el empty的运算</title>
</head>
<body>
<h1>el empty的运算</h1>
<%
    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}<br/>
k2是否为空= ${empty k2}<br/>
k3是否为空= ${empty k3}<br/>
k4是否为空= ${empty k4}<br/>
k5是否为空= ${empty k5}<br/>
是否及格= ${score >= 60 ? "及格": "不及格"}
</body>
</html>
  • 三元运算
${布尔条件表达式 ? 真值:假值}

隐含对象

html渲染引擎 java java渲染页面_html_04

EL四个特定域变量

html渲染引擎 java java渲染页面_html_05

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>演示el的四个常用的隐藏对象(域对象)</title>
</head>
<body>
<h1>演示el的四个常用的隐藏对象(域对象)</h1>
<%
    request.setAttribute("k1", "request-k1数据");
    pageContext.setAttribute("k1", "pageContext-k1数据");
    session.setAttribute("k1", "session-k1数据");
    application.setAttribute("k1", "application-k1数据");
%>
<h1>jsp脚本方式获取</h1>
request域中的k1= <%=request.getAttribute("k1")%><br/>
<h1>el方式来获取域对象的数据</h1>
request域中的k1= ${requestScope.k1}<br/>
pageContext域中的k1= ${pageScope.k1}<br/>
session域中的k1= ${sessionScope.k1}<br/>
application域中的k1= ${applicationScope.k1}<br/>
</body>
</html>

pageContext对象的使用

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>pageContext 对象的使用</title>
</head>
<body>
<h1>pageContext 对象的使用</h1>
<%--
    //通过request对象来获取和HTTP协议相关的数据
    request.getScheme() 它可以获取请求的协议
    request.getServerName() 获取请求的服务器 ip 或域名
    request.getServerPort() 获取请求的服务器端口号
    getContextPath() 获取当前工程路径
    request.getMethod() 获取请求的方式(GET 或 POST)
    request.getRemoteHost() 获取客户端的 ip 地址
    session.getId() 获取会话的唯一标识
--%>
<hr/>
<%--老韩解读
    1.我们可以通过pageContext.request.xx 俩获取和http协议相关的信息
    2.相当于替代 request.getMethod()....
--%>
协议: ${ pageContext.request.scheme }<br>
服务器 ip:${ pageContext.request.serverName }<br>
服务器端口:${ pageContext.request.serverPort }<br>
工程路径:${ pageContext.request.contextPath }<br>
请求方法:${ pageContext.request.method }<br>
客户端 ip 地址:${ pageContext.request.remoteHost }<br>
会话id :${ pageContext.session.id }<br>
<h1>使用jsp表达式脚本获取如上信息</h1>
ip地址: <%=request.getRemoteHost() %> <br>
<h1>使用el表达式形式获取信息-简化写法</h1>
<%
    pageContext.setAttribute("req", request);
%>
ip地址(简化获取): ${req.remoteHost} <br>
获取请求方法(简化获取): ${req.method} <br>
</body>
</html>

html渲染引擎 java java渲染页面_html渲染引擎 java_06

JSTL标签库

JSTL标签库是指JSPStandardTagLibraryJSP标准标签库

EL表达式是为了替换jsp中的表达式脚本,JSTL是为了替换代码脚本。这样jsp页面变得更佳简洁

五个标签库

html渲染引擎 java java渲染页面_语言_07

使用需要导入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" %>
<html>
<head>
    <title>jstl的快速入门</title>
</head>
<body>
<h1>jstl的快速入门</h1>
<%--老韩解读
    1. c:if ... 类似
    2. if(10>2){
       out.println("<h1>10 > 2 成立~</h1>")
    }
--%>
<c:if test="${10 < 2}">
    <h1>10 > 2 成立~</h1>
</c:if>
</body>
</html>

注意事项

  1. taglib引入标签,要放行首
  2. 导入jstl jar包后,要重新发布web工程,否则不识别jstl

core核心库

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>c:set标签的使用</title>
</head>
<body>
<h1>c:set标签的使用</h1>
<%--<%--%>
<%--    //Java代码--%>
<%--    request.setAttribute("email", "hsp@sohu.com");--%>
<%--%>--%>
<%--老韩解读
    <c:set /> set 标签可以往域中保存数据
    1. 等价 域对象.setAttribute(key,value);
    2. scope 属性设置保存到哪个域
            page 表示 PageContext 域(默认值)
            request 表示 Request 域
            session 表示 Session 域
            application 表示 ServletContext 域
    3. var 属性设置 key 是什么
    4. value 属性设置值
--%>
<c:set scope="request" var="name" value="韩顺平教育~"></c:set>
c:set-name的值${requestScope.name}
</body>
</html>

------

<%@ 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" %>
<html>
<head>
    <title>c:if标签使用</title>
</head>
<body>
<c:set scope="request" var="num1" value="20"></c:set>
<c:set scope="request" var="num2" value="10"></c:set>
<c:if test="${num1 > num2}">
    <h1>${num1} > ${num2}</h1>
</c:if>
</body>
</html>

------

<%@ 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" %>
<html>
<head>
    <title>c:choose标签的使用</title>
</head>
<body>
<h1>c:choose标签的使用</h1>
<%
    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}
<c:choose>
    <c:when test="${requestScope.score > 80}">
        <h1>${score}-成绩优秀</h1>
    </c:when>
    <c:when test="${requestScope.score >= 60}">
        <h1>${score}-成绩一般, 及格了</h1>
    </c:when>
    <c:otherwise>
        <h1>${score}-没有及格,下次努力~</h1>
    </c:otherwise>
</c:choose>
</body>
</html>

------

<%@ 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" %>
<html>
<head>
    <title>c:forEach 标签</title>
</head>
<body>
<h1>c:forEach 标签</h1>
<hr/>
<h1>第1种遍历方式从i到j</h1>
<ul>
    <%--
    1.遍历 1 到 5,
    2. 输出 begin 属性设置开始的索引 end 属性设置结束的索引
    3. var 属性表示循环的变量(也是当前正在遍历到的数据)
    4. 等价 for (int i = 1; i <= 5; i++) {}
    5. 在默认情况下, i 每次会递增1
    --%>
    <c:forEach begin="1" end="5" var="i">
        <li>排名=${i}</li>
    </c:forEach>
</ul>
<hr/>
<h1>第2种遍历方式:遍历数组</h1>
<%
    request.setAttribute("sports", new String[]{"打篮球", "乒乓球"});
%>
<%--
    <c:forEach items="${ requestScope.sports }" var="item"/>
    1. items 遍历的集合/数组
    2. var 遍历到的数据
    3. 等价 for (Object item: arr) {}
--%>
<c:forEach items="${requestScope.sports}" var="sport">
    运动名称= ${sport}<br/>
</c:forEach>
<hr/>
<h1>第3种遍历方式:遍历Map</h1>
<%
    Map<String, Object> 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 取出值
--%>
<c:forEach items="${requestScope.cities}" var="city">
    城市信息: ${city.key}--${city.value}<br/>
</c:forEach>
<hr/>
<h1>第4种遍历方式:遍历List</h1>
<%
    List<Monster> 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标签,能看懂,会使用即可
--%>
<c:forEach items="${requestScope.monsters}" var="monster">
    妖怪的信息: ${monster.id}-${monster.name}-${monster.skill}<br/>
</c:forEach>
</body>
</html>