zoukankan      html  css  js  c++  java
  • JSP

    JSP

    JSP 的全换是 Java Server Pages ,Java 的服务器页面。
    是由 Sun 公司专门为了解决动态生成 HTML 文档的技术。
    JSP 的主要作用是代替 Servlet 程序回传 HTML 页面的数据。
    因为 Servlet 程序回传 HTML 页面数据是一件非常繁锁的事情。开发成本和维护成本都极高。

    JSP 的本质

    JSP 页面本质上是一个 Servlet 程序。
    当我们第一次访问 jsp 页面的时候。Tomcat 服务器会帮我们把 jsp 页面翻译成为一个 java 源文件。并且对它进行编译成为 .class 字节码程序。我们打开 java 源文件不难发现其里面的内容是:

    Jw7WE6.png

    我们跟踪原代码发现,HttpJspBase 类。它直接地继承了 HttpServlet 类。也就是说。jsp 翻译出来的 java 类,它间接了继承了 HttpServlet 类。也就是说,翻译出来的是一个 Servlet 程序

    JwHQq1.png

    总结:通过翻译的 java 源代码我们就可以得到结果:jsp 就是 Servlet 程序。

    可以去观察翻译出来的 Servlet 程序的源代码,不难发现。其底层实现,也是通过输出流。把 html 页面数据回传给客户端。

    JwbFQH.png

    JSP 的三种语法

    JSP 头部的 page 指令

    jsp 的 page 指令可以修改 jsp 页面中一些重要的属性,或者行为。

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    • language 属性
      表示 jsp 翻译后是什么语言文件。暂时只支持 java。
    • contentType 属性
      表示 jsp 返回的数据类型是什么;也是源码中 response.setContentType() 参数值
    • import 属性
      跟java源代码中一样。用于导包,导类。
    • autoFlush 属性
      设置当 out 输出流缓冲区满了之后,是否自动刷新冲级区。默认值是 true。
    • buffer 属性
      设置 out 缓冲区的大小。默认是 8kb
    • errorPage 属性
      设置当 jsp 页面运行时出错,自动跳转去的错误页面路径
      这个路径一般都是以斜杠打头,它表示请求地址为 http://ip:port/工程路径/
    • isErrorPage 属性
      设置当前 jsp 页面是否是错误信息页面。默认是 false 如果是 true 可以获取异常信息
    • session 属性
      置访问当前jsp页面,是否会创建 HttpSession 对象。默认是 true
    • extends 属性
      设置jsp翻译出来的java类默认继承谁

    JSP 脚本

    声明脚本

    格式:<%! Java 声明代码 %>
    可以给 jsp 翻译出来的 Java 类增加属性、方法、静态代码块、内部类等。

    JDYMo8.png

    当第一次访问此 JSP 页面时,生成的 Java 类程序中:

    JDYDW4.png

    表达式脚本

    格式:<%= 表达式 %>
    在 jsp 页面上输出数据

    1. 所有的表达式脚本都会被翻译到 _jspService() 方法中
    2. 表达式脚本都会被翻译成为 out.print() 输出到页面上
    3. 由于表达式脚本翻译的内容都在 _jspService() 方法中,所以 _jspService() 方法中的对象都可以直接使用
    4. 表达式脚本中的表达式不能以分号结束

    JDURwq.png

    表达式脚本的内容翻译到 Java 类中的 _jspService() 方法中:

    JDap1e.png

    代码脚本

    格式:<% Java 语句 %>
    可以在 jsp 页面中,编写我们自己需要的功能(写的是 java 语句)

    1. 代码脚本翻译之后都在 _jspService() 方法中
    2. 代码脚本由于翻译到 _jspService() 方法中,所以在 _jspService() 方法中的现有对象都可以直接使用
    3. 可以由多个代码脚本块组合完成一个完整的 java 语句
    4. 代码脚本还可以和表达式脚本一起组合使用,在 jsp 页面上输出数据

    JDdHd1.png

    页面生成效果:

    JDw9eA.png

    翻译出的 Java 类中的代码(实际上是原封不动的放到 _jspService() 方法中):

    JD0Vtx.png

    JSP 注释

    HTM 注释

    格式:<!-- html 注释 -->
    html 注释会被翻译到 java 源代码中;在 _jspService() 方法里,以 out.writer 输出到客户端

    Java 注释

    格式:// 单行注释``/* 多行注释 */
    java 注释会被翻译到 java 源代码中

    JSP 注释

    格式:<%-- jsp 注释 --%>
    jsp 注释可以注释掉一切,包括 html 注释、Java 注释、jsp 脚本等;不会翻译到 Java 源代码中

    JDDDf0.png

    翻译到 Java 代码中(除 jsp 注释外都会在源代码中看到):

    JDDhkR.png

    JSP 九大内置对象

    JDrp1f.png

    JSP 四大域对象

    1. PageContextImpl pageContext:当前 jsp 页面范围内有效
    2. HttpServletRequest request:一次请求内有效
    3. HttpSession session:一个会话范围内有效
    4. ServletContext application:整个 web 工程范围内都有效

    如下两个 jsp 文件:

    <h1>JSP域对象1.jsp</h1>
    <%
        pageContext.setAttribute("key", "pageContext");
        request.setAttribute("key", "request");
        session.setAttribute("key", "session");
        application.setAttribute("key", "application");
    %>
    <%="pageContext 域:" + pageContext.getAttribute("key")%> <br>
    <%="request 域:" + request.getAttribute("key")%> <br>
    <%="session 域:" + session.getAttribute("key")%> <br>
    <%="application 域:" + application.getAttribute("key")%> <br>
    <%request.getRequestDispatcher("/JSP域对象2.jsp").forward(request, response);%>
    
    <h1>JSP域对象2.jsp</h1>
    <%="pageContext 域:" + pageContext.getAttribute("key")%> <br>
    <%="request 域:" + request.getAttribute("key")%> <br>
    <%="session 域:" + session.getAttribute("key")%> <br>
    <%="application 域:" + application.getAttribute("key")%> <br>
    

    第一次访问第一个 jsp 页面,4 个域对象都能得到数据:

    JD62gx.png

    打开第一个 jsp 页面的请求转发的注释,跳转到第二个 jsp 页面后,仅在 jsp 当前页面范围内有效的 pageContext 对象获取不到数据:

    JDcSaQ.png

    修改浏览器地址栏中的地址,直接访问第二个 jsp 页面(不关闭浏览器,此时还是一次会话),request 域就无法读取到数据:

    JDcMGR.png

    关闭浏览器,再次访问第二个 jsp 页面,新的会话,所以 session 也无法访问到数据:

    JDccdg.png

    重启下 web 工程,再次访问第二个 jsp 对象,此时发现最后一个域对象也无法读取到数据:

    JDgSOK.png

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

    JD2Rvq.png

    由于 jsp 翻译之后,底层源代码都是使用 out 来进行输出,所以一般情况下。我们在 jsp 页面中统一使用 out 来进行输出。避免打乱页面输出内容的顺序。

    out.write() 输出字符串没有问题
    out.print() 输出任意数据都没有问题(都转换成为字符串后调用的 write 输出)

    常用标签

    静态包含

    格式:<%@ include file="/xxx"%>
    file 属性指定要包含的 jsp 页面

    1. 静态包含不会翻译被包含的 jsp 页面
    2. 静态包含其实是把被包含的 jsp 页面的代码拷贝到包含的位置输出

    JrF0y9.png

    JrFre1.png

    JrFTTP.png

    动态包含

    格式:<jsp:include page="/xxx">
    page 属性指定要包含的 jsp 页面的路径
    同静态包含,讲被包含的内容执行输出到包含位置

    1. 动态包含会把包含的 jsp 页面也翻译成 Java 代码
    2. 动态包含底层代码:
      org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/include/footer.jsp", out, false);
    3. 动态包含还可以传递参数

    现在有两个 jsp 页面,一个首页,一个页脚:

    JrEyoq.png

    JrEIm9.png

    在首页页面动态包含 jsp 页面时,可以设置请求参数,在页脚页面的 jsp 页面中可以使用 request 对象获取请求参数,在浏览器显示效果:

    JrVpTI.png

    请求转发标签

    格式:<jsp:forward page="/xxx"></jsp:forward>
    效果等同于<% request.getDispatcher("/xxx").forward(request, response); %>

    请求转发的使用

    JrDBP1.png

    Listener 监听器

    Listener 监听器它是 JavaWeb 的三大组件之一
    JavaWeb 的三大组件分别是:Servlet 程序、Filter 过滤器、Listener 监听器
    Listener 它是 JavaEE 的规范,就是接口
    监听器的作用是,监听某种事物的变化。然后通过回调函数,反馈给客户(程序)去做一些相应的处理

    ServletContextListener 接口

    ServletContextListener 它可以监听 ServletContext 对象的创建和销毁
    ServletContext 对象在 web 工程启动的时候创建,在 web 工程停止的时候销毁
    监听到创建和销毁之后都会分别调用 ServletContextListener 监听器的方法反馈

    public interface ServletContextListener extends EventListener {
    
        // 在 ServletContext 对象创建之后马上调用,做初始化
        public void contextInitialized(ServletContextEvent sce);
    
        // 在 ServletContext 对象销毁之后调用
        public void contextDestroyed(ServletContextEvent sce);
    }
    

    使用步骤:

    1. 创建一个类实现 ServletContextListener 接口
    2. 实现回调方法
    3. 在 web.xml 配置
    public class MyFirstListener implements ServletContextListener {
        @Override
        public void contextInitialized(ServletContextEvent sce) {
            System.out.println("ServletContext 对象被创建了,执行初始化...(此处省略一万行代码)");
        }
    
        @Override
        public void contextDestroyed(ServletContextEvent sce) {
            System.out.println("ServletContext 对象被销毁了,正在善后...(此处省略一万行代码)");
        }
    }
    
    <listener>
        <listener-class>work.jkfx.listener.MyFirstListener</listener-class>
    </listener>
    

    Jrs1XT.png

    不一定每天 code well 但要每天 live well
  • 相关阅读:
    Codeforces Round #455 (Div. 2) A. Generate Login【贪心】
    Codeforces Round #315 (Div. 2)【贪心/重排去掉大于n的元素和替换重复的元素】
    CSU-ACM2018寒假集训选拔-入门题
    Codeforces Round #454 C. Shockers【模拟/hash】
    Nowcoder Girl 参考题解【待写】
    2017吉首大学新生赛
    P1450 包裹快递 RP+14【二分】
    NewCode
    2017年浙江工业大学大学生程序设计迎新赛决赛题解
    Codeforces Round #451 (Div. 2) B. Proper Nutrition【枚举/扩展欧几里得/给你n问有没有两个非负整数x,y满足x·a + y·b = n】
  • 原文地址:https://www.cnblogs.com/geekfx/p/12773967.html
Copyright © 2011-2022 走看看