Jsp内容复习大纲

目录

一、jsp是什么?有什么用?

二、jsp 怎么创建放在什么位置?        

三、jsp 本质

四、jsp 头部的 page 标签

五、jsp 脚本

六、jsp 中的三种注释

七、jsp 中的九大内置对象

八、jsp 四大域对象 

九、jsp 中 out.print 输出 和 response.getWriter().print 输出 的区别

十、jsp 中 包含

十一、请求转发的应用

十二、Listener 监听器 

十三、EL表达式

十四、EL表达式的运算符

十五、EL表达式中隐含的 11 个对象 

十六、JSTL 标签库



一、jsp是什么?有什么用?

  • jsp 全称:java serverpages ,java的服务器页面
  • jsp的主要作用是代替 Servlet 程序回传 html 页面的数据。
  • 这是因为在 Servlet 中响应 html 页面是非常麻烦的事情,开发成本较高。

二、jsp 怎么创建放在什么位置?        

  • 和创建 html 页面一样,放在 web目录下。

三、jsp 本质

jsp 本质就是一个 Servlet 程序,。为什么说是一个 Servlet 程序呢?

找到 CATALINA_BASE 目录:

Using CATALINA_BASE:   "C:\Users\杨照光\.IntelliJIdea2019.1\system\tomcat\Unnamed_jsp_01"

在 Tomcat 服务器未启动时,我们看 jsp 目录下是空的。

当服务器启动时,并且访问jsp页面,在 jsp 目录下 jsp 页面 会被 Tomcat 编译成 源文件和.class 字节码文件。

 打开源文件可以看看 这个 jsp 类是继承 org.apache.jasper.runtime.HttpJspBase,而这个类继承了HttpServlet 。所以简单来说 一个 jsp 就是一个 Servlet 

public final class jsp_005f01_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports,
                 org.apache.jasper.runtime.JspSourceDirectives {
}

四、jsp 头部的 page 标签

page 标签可更改一些重要属性:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  •  language: 表示 jsp 翻译过后是什么语言文件,目前只支持 java 语言
  • contentType:表示 jsp 返回的数据类型是什么,也是源码中 response.setContendType() 的参数值
  • pageEncoding:表示当前 jsp 页面文件本身的字符集。默认是 UTF-8 ,不用更改
  • import:用于导包
  • errorPage: 当jsp 页面出错后,跳转到哪个页面。"页面路径"

 设置错误页面之后: 

  • isErrorPage:设置当前 jsp 页面是否是错误信息页面。默认是false。
  • session:设置访问当前 jsp 页面,是否会创建 HttpSession 对象,默认 true
  • extends:设置 jsp 翻译出来的 java类 默认继承谁。

以下俩个属性是给 out 输出流使用:

  • autoFlush:设置 out 输出流缓冲区满了之后,是否自动刷新冲级区,默认值是:true
  • buffer:设置 out 缓冲区的大小,默认是 8kb

当缓冲区设置比较小,内容较多,并且不自动更新时,会报:缓冲区溢出错误。一般默认是自动更新的,不用改。

五、jsp 脚本

  • 声明脚本(很少用)

格式:<%!    java代码   %>

作用:

  • 可以给 jsp 翻译出来的 java类定义属性和方法,内部类等
  • 在 Tomcat 编辑的源文件中会和 jsp 中的代码对应~

  •  表达式脚本(常用)

 格式: <%= 表达式 %>

作用:往 jsp 页面上输出数据

  • 字符串
  • 对象
  • 基本数据类型

表达式的特点:

  • 所有表达式脚本都会被翻译到源文件中的 _jspService 方法中,所以 _jspService 中的对象以及方法都能使用
  • 表达式脚本都会被翻译称为 out.print() 翻译
  • 表达式脚本不要加分号结尾

  •  代码脚本

 代码格式: <% java语句  %>

作用:在 jsp 页面中实现功能。(编写的是java语句,方法需使用声明脚本)

  • if 语句
  • while语句
  • for 循环

特点:

  • 代码脚本翻译之后都在 _jspService 方法中,可以用  _jspService 中的对象。
  • 可以由多个代码块共同完成一个java语句
  •  代码脚本还可以和表达式脚本配合使用,输出到 jsp 页面中。

 表达式脚本配合代码脚本::

 六、jsp 中的三种注释

  • html
    • <!--html注释-->
    • 不能写在代码脚本和表达式脚本中
  • java
    • // 单行注释
    • /*多行注释*/
    • 出现在代码脚本和表达式脚本中
  • jsp
    • <%--jsp注释--%>
    • 可以出现在任意位置

 七、jsp 中的九大内置对象

  • request                请求对象
  • response             响应对象
  • pageContext        jsp 上下文对象
  • session                会话对象
  • application           ServletContext 对象
  • config                  ServletConfig对象
  • out                       jsp 输出流对象
  • page                    指向当前 jsp 页面的对象,代表当前 jsp 页面
  • exception             jsp 异常对象【需要开启: isErrorPage=true】

八、jsp 四大域对象 

  • pageContext       jsp 页面范围内有效
  • request               请求域对象【一次请求内有效】
  • session              会话域对象【一个会话内有效:浏览器访问服务器 ----> 浏览器关闭】
  • application        应用域对象【服务器启动到关闭内有效】

使用顺序,优先从最小的域选择:pageContext < request < session < application

  • 在当前 jsp 页面范围内: 
    • pageContext 肯定能取出来,因为存数据,取数据在同一个 jsp 页面内
    • request 也能取出来,因为浏览器只发送了一次请求:http://localhost:8080/jsp_01/jsp_05.jsp
    • session 能取出数据,因为浏览器没有关闭
    • application能取出数据,服务器没有关闭

  •  不在当前 jsp 页面范围内
    • pageContext 无法取出数据,这是因为在 jsp_05 页面存数据,jsp_06页面取数据,是俩个页面,不在范围内。
    • request能出来,是因为转发是一次请求。

  •  不在同一 jsp 页面范围内,并且是俩次请求。
    • pageContext 和 request 对象都不能取出数据。

  • 当我们打开浏览器,直接访问 http://localhost:8080/jsp_01/jsp_06.jsp 
    • session 域中也取不出数据,因为 在 jsp_05 页面 存数据,而这个页面并没有被打开,所以超过会话范围。

  •  当我们重新部署 Tomcat 服务器时,application 也会取不到数据。

 九、jsp 中 out.print 输出 和 response.getWriter().print 输出 的区别

  • out.print 和 response.getWriter().print 都是向浏览器输出的。
    • 但是我们发现以下,应该是 out.print 先执行,输出到浏览器中,为什么response.getWriter().print 会先输出呢?

  •  out 输出 会直接写到out缓冲区里,response 输出 会直接写到 response 缓冲区里

  • 当 jsp 页面所有代码都执行完会执行俩个操作:
    • 执行 out.flush() 操作,会把out缓冲区中的数据追加到 response 缓冲区里
    • 执行 response.flush() 操作,将response 缓冲区的数据输出到浏览器中

十、jsp 中 包含

  •  静态包含:会将指定的页面输出到包含位置上。
    • path:被包含的页面路径
    • 特点:
      • 不会把被包含的 jsp 页面翻译成源文件
      • 原理:会将被包含的 jsp 页面的代码 拷贝到源代码中。
    <%@include file="path" %>

 他会将 jsp_07 页面的 jsp 代码 拷贝到 jsp_08 的源码当中。

  •  动态包含:也会将指定的页面输出到包含位置上

格式:

<%--动态包含--%>
    <jsp:include page="path"></jsp:include>

特点:

会将被包含的 jsp 页面翻译成源文件。并生成.class字节码文件

底层其实会调用这样一串代码来实现动态包含。

  org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "jsp_07.jsp", out, false);
  • 请求转发
<%--请求转发--%>
    <jsp:forward page="jsp_06.jsp"></jsp:forward>

十一、请求转发的应用

        客户端访问流程: 

 举例说明:Servlet + jsp 输出十个学生的信息【不需要查询数据库】

学生属性:

public class Student {
   private  String name ;
    private int id ;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }
}

Servlet程序:

/*Servlet程序*/
public class StudentServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        /*1、获取请求信息参数*/
        /*2、执行sql语句*/
        /*3、数据库查询数据*/


        /*以后这些数据都是从数据库中取*/
        List<Student> students = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            int temp = i + 1;
            Student student = new Student("name" + temp, ++temp);
            students.add(student);
        }
        /*存数据*/
        request.setAttribute("students", students);
        /*转发*/
        request.getRequestDispatcher("/jsp_09.jsp").forward(request, response);
    }
}

WEB.xml文件:

    <servlet>
        <servlet-name>Student</servlet-name>
        <servlet-class>yangzhaoguang.StudentServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Student</servlet-name>
        <url-pattern>/list</url-pattern>
    </servlet-mapping>

jsp页面:

<html>
<head>
    <title>Title</title>
    <style type="text/css">
        table, th, tr, td {
            border: rebeccapurple 1px solid;
            border-collapse: collapse;
        }

    </style>
</head>
<body>

<%
    /*从请求域中取出数据*/
    List<Student> students = (List<Student>) request.getAttribute("students");
    int i = 0 ;
%>

<table>
    <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>年龄</th>
    </tr>
    <%--以上都是固定的,静态的--%>


    <%--以下数据都应该是从数据库中取--%>
    <%for (Student student : students) { %>
    <tr>
        <%--获取学生信息--%>
        <td><%out.print(++i);%></td>
        <td><%= student.getName()%></td>
        <td><%= student.getId()%></td>
    </tr>
    <%}%>

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

从浏览器上访问:要先访问 Servlet 程序。通过转发跳转到 jsp 页面。

十二、Listener 监听器 

  • 什么是监听器? 
    • Listener 监听器 是 JavaWeb 三大组件之一,JavaWeb三大组件:Servlet 程序,Filter 过滤器,Listener 监听器
    • Listener 是 javaEE规范之一,也是个接口
          <listener>
              <listener-class>yangzhaoguang.StudentServlet</listener-class>
          </listener>

    • 作用:监听某种事务的变化,然后通过回调函数,返回给客户端去做一些相应的操作
  • ServletContextListener 监听器
    • ServletContextListener 监听器可以监听 ServletContext 对象的创建和销毁
    • ServletContext对象从服务器开始时创建,关闭时销毁
    • 在ServletContext对象创建和销毁时都会调用回调函数:
    // 初始化执行的   
    void contextInitialized(ServletContextEvent var1);

    // 销毁时执行的
    void contextDestroyed(ServletContextEvent var1);
  • 配置监听器步骤:
    • 创建类 ServletContextListener 接口,并重写以上俩个
public class ServletContextListenerImpl implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //编写 ServletContext对象 创建时准备 执行的代码。。。。

    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        //编写 ServletContext对象 销毁时准备 执行的代码。。。。
    }
}
  • 在 web.xml 文件配置监听器
    <listener>
        <listener-class>yangzhaoguang.ServletContextListenerImpl </listener-class>
    </listener>

十三、EL表达式

 什么是 EL表达式?EL 表达式的作用?

  • EL表达式的全称:Expression Language,是表达式语言,
  • EL表达式的作用:代替 jsp 页面中表达式脚本在 jsp 页面进行数据的输出。因为 EL表达式在输出数据的时候,要比 jsp 的表达式脚本简洁的多。 

 当我们向页面中输出一个域中不存在的值,会发现俩种输出方式不同:

EL表达式比表达式脚本更加的方便。

 演示用 EL表达式输出数组,list集合,map集合

<body>
    <%
        ELTest el = new ELTest();
        el.setId(12);

        /*增加String数组*/
        el.setAdd(new String[]{"河北省唐山市","河北省承德市","河北省石家庄市"});
        /*增加map集合*/
        Map<String,String> map = new HashMap<>();
        map.put("key1","张三");
        map.put("key2","李四");
        map.put("key3","王五");
        map.put("key4","木头刘");
        el.setMap(map);
        /*增加list集合*/
        List<Object> list = new ArrayList<>();
        list.add("130281199909194444");
        list.add("130281199909195555");
        list.add("130281199909194092");
        el.setList(list);

        /*放到 request 域中*/
        request.setAttribute("info",el);
    %>

    <%--输出info--%>
    输出 info:${info}<br>
    <%--通过在向域中存放数据时取得名字来获取域中的数据--%>
    输出ELTest中的id属性:${info.id}<br>
    输出ELTest中list集合:${info.list}<br>
    <%--如果指向访问集合中的某个数据:
        使用 get 方法可以
        也可以使用下标,底层使用的也是 get 方法。
    --%>
    通过get方法输出list集合中某个数据:${info.list.get(2)}<br>
    通过下标获取list集合中的数据:${info.list[2]}<br>
    输出ELTest中的map集合:${info.map}<br>
    <%--想问 map 集合中的某个数据
        可以直接 .key, key就是map集合中的键值,但是底层也是调用的 get 方法。
        也可以用 get 方法
    --%>
    通过key输出map集合中的某个数据:${info.map.key3}<br>
    通过get方法输出map集合中的某个数据:${info.map.get("key3")}<br>

    <%--输出String数组--%>
    <%--访问某个元素,也可通过下标的方法--%>
    通过下标输出String数组中的某个元素:${info.add[1]}<br>
</body>

 使用 EL 表达式获取属性的时候,底层也是调用 get 的方法。

 十四、EL表达式的运算符

. 和 [] 运算符:当域中的 key 中有特殊符号的时候,需要加将 .key 变成 [ 'key' ] 或者 [ "key" ] 

十五、EL表达式中隐含的 11 个对象 

变量类型作用
pageContextpageContextImpl可以获取jsp中九大内置对象 
pageScopeMap<String,Object>

  获取 pageContext 域中的数据

【域中的数据通常由键值对形式存储】

requestScopeMap<String,Object>获取request域中的数据
sessionScopeMap<String,Object>获取session域中的数据
applicationScopeMap<String,Object>获取ServletContext域中的数据
param       Map<String,Object>获取请求参数的信息
paramValuesMap<String,String[]>

获取请求参数的信息

可以获取多个值

headerMap<String,Object>获取请求头的信息
headerValuesMap<S        tring,Object>

获取请求头的信息

可以获取多个值

cookieMap<String,Object>获取当前请求的 cookie信息
initParamMap<String,Object>获取web.xml中配置的<context-param> 上下文参数
    <%

        request.setAttribute("key","requestValue");

    %>
    <%--俩种方式都可以--%>
    request域中的数据:${requestScope.key}<br>
    request域中的数据:${key}

既然俩种方式都可以,况且 直接用 key 获取value,不是更简洁吗?为什么还有使用 requestScope 呢?

如果我们多个域中有相同的key,那么直接用 key 的方式,获取value ,他会自动从最小的域中开始搜索。

 从四大域中获取数据的方法:

 pageContext的使用方法:可以获取九大内置对象。

常用的方法:

 通常的用法可以将 request 对象放到 request 域中,比较简洁:

param 和 paramValue 的区别:

 请求参数:

http://localhost:8080/jsp_01/jsp_14.jsp?userName=zhangsan&password=123&hobby=smoke&hobby=drink

当请求参数有多个时,建议使用 paramvalues 

请求参数只有一个,使用 param 

 header 和 headerValues 的用法:

 与浏览器中的一致:

十六、JSTL 标签库

 JSTL 标签库,全称是指 JSP Standard Tag  Library ,JSP 标准标签库,是一个不断完善的开放源代码的 JSP 标签库。

EL表达式 主要是为了 替换 jsp 中的表达式脚本,而标签库则是为了替换代码脚本,这样式的整个 jsp 页面边的更加简洁

JSTL 由5个不同功能的标签库组成:

功能范围URI前缀
核心标签库http://java.sun.com/jsp/jstl/corec
格式化http://java/sum/com/jsp/jstl/fmtfmt
函数http://java/sum/com/jsp/jstl/functionsfn
数据库http://java/sum/com/jsp/jstl/sqlsql
XMLhttp://java/sum/com/jsp/jstl/xmlx

使用步骤:

  •    先将下载好 jar 包 导进去

  • 导入标签库 
    //核心标签库  prefix:前缀
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    //格式化标签库
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    //函数标签库
    <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
    //数据库标签库
    <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
    //XML标签库
    <%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>

核心标签库中常用的标签的使用:

标签作用属性
<c:set  />往域中增加数据

scope属性:指明往哪个域中增加数据

        page:PageContext域

        request:Request 域

        session:Session 域

        application:ServletContext域

var 属性:key 值

value属性:value 值

<c:if></c:if>if判断

test 属性:判断条件,使用EL表达式

<c:if>条件为true执行的语句</c:if>

<c:choose><c:when>

<c:otherwise>

多路判断

和 switch....case...default

差不多

<c:choose>:开始判断,相当于switch

<c:when>:判断每一种结果,相当于case

<c:otherwise>:剩下的结果,相当于 default

注意:标签里不能使用 html 注释。可以使用jsp标签

<c:forEach></c:forEach>循环

begin 属性:设置开始的索引

end 属性:设置结束的索引

var属性:设置循环变量

item属性:表示遍历的数据源(集合,数组.....)

演示:

<body>
    <%--
     <c:set /> :往 域中保存数据
         scope属性:保存到哪个域中
            page“:PageContext域
            request:Request域
            session:Session域
            application:ServletContext 域
         var 属性:key值
         value 属性:value值
    >--%>

    <c:set scope="session" var="key" value="sessionValue" />
    <%--取数据--%>
    ${sessionScope.key}


    <%--
        <c:if /> 标签
            test 属性:判断条件,使用EL表达式

    --%>
    <c:if  test="${12 == 12}" >
        <h3>条件为true才会执行</h3>
    </c:if>

    <%--
        <c:choose> <c:when >  <c:otherwise>标签
            注意:<c:choose></c:choose> 标签里不能使用 html 注释,使用 jsp 注释
                 在<c:otherwise> <c:when>  里面在对条件进行判断,需要在加<c:choose></c:choose>标签

    --%>
    <%
        request.setAttribute("weight",222);
    %>
    <c:choose>
        <c:when  test="${ requestScope.weight > 100}">
            <h3>体重超过100公斤</h3>
        </c:when>
        <c:when  test="${ requestScope.weight > 80}">
            <h3>体重超过80公斤</h3>
        </c:when>
        <c:otherwise>
            <h3>体重小于80公斤</h3>
        </c:otherwise>
    </c:choose>

    <%--
        <c:forEach>标签
            begin属性:设置开始的索引
            end属性:设置结束的索引
            var属性:表示循环的变量
    --%>
    <c:forEach begin="1" end="10" var="i">
        ${i} <br>
    </c:forEach>
    <br>
    <%--
        遍历数组
        for(String item:arr){}
    --%>
    <%
        request.setAttribute("arr",new String[]{"1302811111","15066668888","13522222222"});
    %>
    <c:forEach items="${ requestScope.arr }" var="item">
        ${item}<br>
    </c:forEach>

    <%--遍历map集合--%>
    <%
        Map<String,String> map = new HashMap<>();
        map.put("key1","value1");
        map.put("key2","value2");
        map.put("key3","value3");
        map.put("key4","value4");
        request.setAttribute("map",map);
        // for (Map.Entry<String,String> entry:map.entrySet()) {
        //    java 输出
        // }
    %>
    <c:forEach items="${ requestScope.map}" var="entry">
        <%--获取所有的 key,会调用Map.Entry中的 getKey()方法。--%>
        <%--获取所有的 value,会调用Map.Entry中的 getValue()方法。--%>
        <h3> ${entry.key} = ${entry.value} </h3>
    </c:forEach>
</body>

演示结果: 

使用:<c:forEach> + Servlet 程序+表格的方式 遍历学生的信息【不用mysql】

<html>
<head>
    <title>Title</title>
    <style type="text/css">
        table,tr,th,td {
            border: rebeccapurple solid 1px;
           border-collapse: collapse;
        }
    </style>
</head>

<body>
    <h1>学生信息</h1>
    <table >
        <tr>
            <th>姓名</th>
            <th>ID</th>
            <th>操作</th>
        </tr>
    <c:forEach items="${ requestScope.students }" var="student">
        <tr>
            <td> ${student.name} </td>
            <td> ${student.id} </td>
            <td>增加  修改  删除</td>

        </tr>
    </c:forEach>
    </table>

</body>
</html>

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鲨瓜2号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值