阶段四-JavaEE-Day05

一、JSP的使用

1. JSP的引入

有一种特殊的文件,我们可以在它内部编写HTML代码、CSS代码、js代码还有Java代码。编写完之后,再有一个工具,将这个特殊的文件转换成Servlet,在转换好的Servlet中,之前写的Java代码还在,而HTML、css、js代码都使用writer的方式给写好。

那这个特殊的文件就是jsp文件。这个工具就是Tomcat服务器中的jsp引擎。

2. JSP展示数据实例

<%@ page import="java.util.List" %>
<%@ page import="com.sh.pojo.Emp" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>

    <style>
        table{
            width: 550px;
            margin: 0 auto;
            border: 1px solid red;
            border-collapse:collapse;
            text-align: center;
        }
        td,th{
            border: 1px solid red;
        }
    </style>
</head>
<body>

<%
    //从数据库中查询
    List<Emp> list = new ArrayList<>();
    list.add(new Emp(1, "张无忌", "经理", new Date(), 5000.0));
    list.add(new Emp(2, "赵敏", "主管", new Date(), 3000.0));
    list.add(new Emp(3, "金毛狮王", "职员", new Date(), 2000.0));
    list.add(new Emp(4, "灭绝师太", "职员", new Date(), 2000.0));
    list.add(new Emp(5, "周芷若", "总监", new Date(), 8000.0));
%>

<table>
    <tr>
        <th>编号</th>
        <th>姓名</th>
        <th>职位</th>
        <th>生日</th>
        <th>工资</th>
    </tr>

    <% SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); %>
    <% for (Emp emp : list) {%>

    <tr>
        <td><%out.write(emp.getId()+"");%></td>
        <td><%out.write(emp.getName());%></td>
        <td><%out.write(emp.getPosition());%></td>
        <td><%out.write(sdf.format(emp.getBirthday()));%></td>
        <td><%out.write(emp.getSalary()+"");%></td>
    </tr>

    <% }%>
</table>
</body>
</html>

4. JSP执行原理及流程

  • JSP看似是HTML代码,看似是页面,但其实是一种后端技术。

  • 当我们第一发送请求访问jsp资源时,Tomcat服务器中的JSP加载引擎会将该JSP资源转换成一个 .java 文件(Servlet)

  • 这个 .java文件其实就是一个Servlet,在这个Servlet中已经将写在JSP中的HTML代码以writer.print()的方式编写好了,然后将数据响应给浏览器的。

  • JSP本质上就是一个Servlet,JSP中的HTML代码就相当于我们之前在Servlet中写的writer.write()代码。

4.1 JSP执行过程

JSP的执行过程大致可以分为三个时期:转换、编译、执行。

转换/翻译(translation):Tomcat中的JSP引擎将JSP网页转换成Servlet,得到一个.java文件

编译(compile)通过javac命令将.java文件编译成 .class文件

.

运行运行.class字节码文件,处理请求。 具体运行过程:

  1. 浏览器发起请求访问jsp。

  2. Tomcat服务器接收到请求后调用对应的Servlet处理请求,调用JspServlet。

  3. JspServlet将请求的jsp文件转换成对应的Java文件并完成编译。

  4. 将编译后的class文件加载到内存并执行,其实就是运行一个Servlet。

  5. 最后得到结果数据响应浏览器。

jsp页面上所有的HTML相关代码全部被转化成了字符串,并在_jspService方法中,通过流的形式响应给了浏览器。 当JSP页面在执行时,JSP 引擎会做检查工作,如果发现JSP页面中有更新修改时,JSP引擎会再次转换JSP为Servlet,如果没有更新,就直接执行之前转换好的Servlet。

4.2 JSP的性能问题

JSP与Servlet执行性能上的差别只在第一次的执行上。因为在第一次执行jsp时,jsp要经过转换、编译、执行三个过程。而之后再次访问jsp页面时,就直接执行第一次所产生的Servlet即可,不需要每次都转换、编译。

JSP本质上是Servlet,在请求jsp时,要经过执行,其内部是通过大量的IO流形式将内容发送给页面的,IO流就是一种比较耗费资源的操作。而HTML本身资源是已经存在的,不需要服务器执行什么操作。

但JSP是动态资源,可以动态的展示数据。

4.3 JSP加载引擎

查看Tomcat conf/web.xml文件发现,这里默认配置了一个JSP的加载引擎-JspServlet。

<servlet>
    <servlet-name>jsp</servlet-name>
    <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
    <init-param>
        <param-name>fork</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <param-name>xpoweredBy</param-name>
        <param-value>false</param-value>
    </init-param>
    <load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>jsp</servlet-name>
    <url-pattern>*.jsp</url-pattern>
    <url-pattern>*.jspx</url-pattern>
</servlet-mapping>

JSP加载引擎的作用:

转换JSP页面:将JSP页面转换成一个Servlet。

编译JSP对应的Java文件:JSP引擎调用Java编译器对这个Servlet进行编译,得到可执行文件class。

请求处理:JSP引擎调用java虚拟机来解释执行class文件,得到结果响应浏览器。

5. JSP的继承结构

  • HttpJSPBase重写了init,service和destory方法。

  • 并且自定义了 jspInit, jspService, jspDestory。

  • 然后在重写的init方法中调用了 JSPInit,在重写的service方法中调用了 jspService,在重写的destory方法中调用了 jspDestory。

  • 我们JSP的文件编译成JAVA代码后,继承HttpJspBase重写的方法是 jspInit, jspService, jspService。

6. JSP中的java代码问题

在jsp中可以通过 <%%> 和 <%!%>两种方式来书写代码,这两种方式中写的Java代码在转换后生成的代码在Servlet中位置是不一样的,前者在_jspService方法中,后者在Servlet中作为类的成员。

<%%>中定义的变量是局部变量

<%!%>中定义的变量是成员变量

JSP本质上是Servlet,在Servlet中我们是不推荐定义一些成员变量的。

7. JSP中的注释

JSP中可以写HTML、Java、CSS、JS代码,那么也就可以写这些语言的注释,并且JSP也有自己的注释方式。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>

    <style>
        /*我是css注释*/
    </style>

    <script>
        //我是JS注释
        /*我是JS注释*/
    </script>
</head>
<body>
    <!--我是HTML注释-->

    <%--我是jsp注释--%>
</body>
</html>

推荐在jsp中使用jsp自己的注释:<%--注释内容--%>

8. JSP的使用建议

  • JSP和Servlet本质上是相同的。所以说,JSP页面功能和Servlet中功能完全可以互换。

  • JSP的编码风格是在HTML中嵌入少量的Java代码,它用于展示数据比较方便。

  • Servlet适合编写Java代码。

  • 所以在MVC分层上,我们往往将Servlet作为控制层(C),将JSP作为视图层(V)。M(model)模型层

  • 以后通过Servlet去处理请求,得到结果,然后通过JSP来进行结果展示。

二、JSP中的常用指令标签

1. 概述

指令标签是JSP页面上的一种特殊标签,JSP指令可以用来设置整个JSP页面相关的属性,如网页的编码方式、网页使用的脚本语言、导包等。

指令标签的语法:

<%@ directive attribute="value" %>

JSP中的三种指令标签:

指令描述
<%@ page %>定义网页依赖属性,如脚本语言、error页面、缓存需求等等
<%@ include %>包含其他文件
<%@ taglib %>引入标签库的定义

2. page指令标签

属性描述
buffer指定out对象使用缓冲区的大小
autoFlush控制out对象的 缓存区
contentType指定当前JSP页面的MIME类型和字符编码
errorPage指定当JSP页面发生异常时需要转向的错误处理页面
isErrorPage指定当前页面是否可以作为另一个JSP页面的错误处理页
extends指定servlet从哪一个类继承
import导入要使用的Java类
info定义JSP页面的描述信息
isThreadSafe指定对JSP页面的访问是否为线程安全
language定义JSP页面所用的脚本语言,默认是Java
session指定JSP页面是否使用session,默认是使用
isELIgnored指定是否执行EL表达式
isScriptingEnabled确定脚本元素能否被使用

常用的:

contentType:告诉浏览器响应的数据类型及编码格式

contentType="text/html;charset=UTF-8"

errorPage:指定错误页,当前页面发生错误时,显示错误页面的信息

errorPage="error500.jsp

 import:导包

import="com.sh.pojo.Emp"

3. include指令标签

  • JSP可以通过include指令来包含其他文件。被包含的文件可以是jsp文件、HTML文件或文本文件。

  • 包含的文件就像是jsp文件的一部分,会被同时编译执行。

  • 除了使用include指令标签可以实现引入外,使用jsp:include动作也可以实现引入。

静态引入: @include 被引入的网页和当前页生成代码后形成了一个java文件。

动态引入: jsp:include 被引入的JSP页面会生成独立的java代码。

​​​​​​

        静态引入,被引入的jsp页面不会单独生成java代码文件,当前页和被引入页会生成一个java文件

    <%@ include file="hello2.jsp"%>


        动态引入:被引入的页面会生成独立的java代码,在当前页生成的java代码中使用
        org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "hello3.jsp", out, false);
        引入其他页面

4. taglib指令标签

可以在jsp页面中引入其他的标签库

<%@ taglib uri="uri" prefix="prefixOfTag" %>

三、JSP内置对象

1. 什么是内置对象

JSP的本质是Servlet,在JSP文件经过转译之后,生成JAVA代码,在运行时,JSP给我们准备好了九个可以直接使用的对象,这九个对象我们称之为内置对象。

2. 九大内置对象

四个域对象

pageContext page域 当前页面内可用。

request reqeust域 一次请求。

session session域 一次会话, 多次请求。

application application域 整个项目运行, 多次请求, 多次会话。

响应对象

response 响应对象。

输出流对象

out 打印流对象。

其他三个对象

servletConfig 由于JSP本身也是一个Servlet,所以容器也会给我们准备一个ServletConfig。

page 就是JSP转换的Servlet的对象,也就是当前JSP对象本身 。

exception 异常对象,在错误提示页上使用,当isErrorpage=true 才具有该对象。

注意事项:

response对象 当服务器创建request对象时会同时创建用于响应客户端的response对象。

out对象 是 JspWriter 类的实例,不是PrinterWriter的实例;用来在response对象中写入内容。JspWriter类包含了大部分java.io.PrintWriter类中的方法。不过,JspWriter增了一些专为处理缓存而设计的方法。另外JspWriter类会抛出IOExceptions异常。 最初的JspWriter类对象根据页面是否有缓存来进行不同的实例化操作。可以在page指令中使用。buffered='false'属性来轻松关闭缓存。

pageContext对象 PageContext类的实例,用来代表整个JSP页面;提供对JSP页面所有对象以及命名空间的访问。

3. JSP的使用总结

  1. 创建Jsp文件,在项目的web目录下创建。

  2. 使用page指令设置Jsp的转译细节(一般自动生成的就够用)。

  3. 使用tablib指令引入第三方的自定义标签来使用(JSTL标签)。

  4. 使用HTML,CSS,JQuery完成页面的开发。

  5. 使用<%%>声明java脚本片段完成数据的动态拼接。

    1. <%%>:生成在_jspService()方法中

    2. <%! %>:生成在类中

    3. <%= %>:生成在_jspService()方法中,输出

  6. 获取request或者session中的数据拼接到当前页面中(内置对象)。

四、EL表达式学习

1. 概念

在jsp页面中可以使用EL表达式来获取域对象中的数据

2. 特点

  1. 可以获取作用域对象中的数据。

  2. 底层使用的是反射,在使用的时候可以通过键名即可获取对应的

  3. 简化了在jsp页面中使用<%%>获取域对象数据的方式。

3. 使用

基本语法

  1. ${键名},键名是域对象中存储的数据的键。

  2. ${键名.属性名.属性名…},可以获取域对象中级联属性的值。

  3. ${键名[角标]},获取域对象中存储的list集合或者数组中指定角标的数据。

  4. 注意:${}不仅可获取域对象中的数据,而且会将该数据打印到浏览器中。如果获取不到数据,也不会报错,只是不显示而已。

作用域数据查找顺序

使用EL表达式获取域数据的时候,如果没有指明作用域,那会按照作用域由小到大的顺序去找,直到找到为止: ​ pageContext ---> request ---> session ---> application

指定获取某个作用域中的数据

  • ${pageScope.键名} 获取page域对象中的数据

  • ${requestScope.键名} 获取request域对象中的数据

  • ${sessionScope.键名} 获取session域对象中的数据

  • ${applicationScope.键名} 获取application域对象中的数据

获取request对象中的请求数据

${param.键名},可以获取request中携带的请求参数的数据

获取request对象中Cookie的key value

${cookie.JSESSIONID.name}

${cookie.JSESSIONID.value}

EL表达式可以使用比较运算和算术运算

${键名 逻辑运算符 键名} ​ ${键名 算术运算符 键名}

注意: + 表示的是算术运算,而不是字符串拼接。

 <h2>使用脚本方式获取数据</h2>
    <ul>
        <li>获取简单数据:<%out.write(request.getAttribute("name").toString());%></li>
        <li>获取对象数据:<%out.write(((Emp)request.getAttribute("emp")).getName());%></li>
        <li>获取list集合数据:<%out.write(((List)request.getAttribute("list")).get(0).toString());%></li>
        <li>获取map集合数据:<%out.write(((Map)request.getAttribute("map")).get("key1").toString());%></li>
    </ul>
    <h2>使用EL表达式方式获取数据</h2>
    <ul>
        <li>获取简单数据:${name}</li>
        <li>获取对象数据:${emp}</li>
        <li>获取list集合数据:${list[0]}</li>
        <li>获取map集合数据:${map.key1}</li>
    </ul>

    <h2>指明域对象获取数据</h2>
    <ul>
        <li>获取request域数据:${requestScope.requestParam}</li>
        <li>获取session域数据:${sessionScope.sessionParam}</li>
        <li>获取application域数据:${applicationScope.applicationParam}</li>
    </ul>

    <h2>使用逻辑表达式</h2>
    ${3 > 4}<br>
    ${5 + 8}

五、JSTL标签库学习

1. 作用

可以使用JSTL标签来完成一些例如循环、判断等情况的与数据输出。

JSTL的作用就是:替换在Jsp中声明的Java逻辑代码。

2. 介绍

JSTL标签库是第三方发明的自定义的标签,每个标签都有自己特定的含义表示一个具体的java逻辑。我们要在JSP中使用JSTL必须使用taglib标签引入第三方的标签库资源。 ​标签库的内容有:

  1. 核心标签库

  2. SQL标签库

  3. 函数标签库

  4. 格式化标签库

  5. XML标签库

3. 使用

使用步骤:

  1. 在项目中导入JSTL的jar包。

  2. 在jsp页面中通过taglib指令引入jstl标签库。

  3. 使用jstl标签完成开发。

if判断

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%
    request.setAttribute("gender", "0");
%>
<%--
    c:if 标签的作用就相当于Java中的if判断
    格式是: <c:if test="${EL 比较运算符 值}">条件成立输出的内容</c:if>
--%>
<c:if test="${gender == '0'}">
    性别是男。
</c:if>
</body>
</html>

循环

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <c:forEach items="${list}" var="emp">
        ${emp.id}---${emp.name}---${emp.position} <br>
    </c:forEach>

    <c:forEach begin="0" end="10" var="i" step="1" varStatus="status">
        ${i} --- ${status.index}
    </c:forEach>
</body>
</html>

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值