JSP

JavaServer Pages
    基于java语言实现的服务器端页面
    JSP是JavaEE规范之一

JSP文件后缀默认是.jsp,但是jsp文件的后缀也可以修改的,通过修改CATALINA_HOME/conf/web.xml文件

JS : JavaScript,运行在浏览器中,和服务器没有关系,和java也没有关系
JSP : JavaServer Pages,运行在服务器中,JSP底层就是java程序,运行在JVM中。

JSP的执行原理:
      - 浏览器上访问的路径虽然是以.jsp结尾,访问的是某个jsp文件,其实底层执行的是jsp对应的java程序
      - Tomcat服务器负责将.jsp文件翻译生成.java源文件,并且将java源文件编译生成.class字节码文件
      - 访问jsp,其实底层还是执行了.class文件中的程序。
      - Tomcat服务器内置了一个JSP翻译引擎,专门负责翻译JSP文件,编译java源文件
      - index.jsp会被翻译生成index_jsp.java,编译生成index_jsp.class
      - index_jsp这个类继承了HttpJspBase,而HttpJspBase继承了HttpServlet
      - jsp就是Servlet,只不过职责不同,JSP的强项做页面展示。

在JSP文件中编写的所有的HTML、CSS、JavaScript,对于JSP来说,只是普通的字符串。被翻译到:out.write("翻译到这里");

JSP文件修改之后,不需要重新部署,也不需要重新启动Tomcat服务器。

JSP文件第一次访问的时候为什么非常慢?
    - 启动JSP翻译引擎
    - 需要一个翻译的过程
    - 需要一个编译的过程
    - 需要Servlet对象的创建过程
    - init方法调用
    - service方法调用.....
    
    为什么第2+次访问JSP的时候非常快?
        - 不需要重新翻译
        - 不需要重新编译
        - 不需要创建Servlet对象
        - 直接调用Servlet对象的service方法
    
    JSP也是单实例多线程环境下运行的一个Servlet对象。

JSP文件在被修改之后会被重新翻译,Tomcat服务器会记录JSP文件的最后修改时间。

关于JSP的小脚本scriptlet:
    <%----%>    JSP的专业注释,使用这种注释方式,不会被翻译到java源文件中
    <%
        java语句;
        java语句;
        java语句;
    %>
    小脚本中的java语句被翻译到Servlet的service方法中,所以小脚本中必须编写“java语句”,java语句以分号结尾。
JSP的声明语法格式:
    <%!
        实例变量;
        静态变量;
        方法;
        静态语句块;
        构造函数;
        .....
    %>
  注:
      声明块中的java程序会被JSP翻译引擎翻译到service方法之外
      声明块中不能直接编写java语句,除非是变量的声明

<% out.print(); %> 等同于 <%= %>
<%=i %>        表达式语法,具有输出功能,输出到浏览器上

关于JSP的九大内置对象:
    1、内置对象可以直接在JSP文件中拿来使用。
    2、九大内置对象
        内置对象                                完整类名
        ----------------------------------------------------------------------------
        pageContext                    javax.servlet.jsp.PageContext                            页面范围【页面上下文】
        request                            javax.servlet.http.HttpServletRequest                 请求范围
        session                            javax.servlet.http.HttpSession                             会话范围
        application                       javax.servlet.ServletContext                                应用范围
        
        response                         javax.servlet.http.HttpServletResponse               响应对象
        out                                   javax.servlet.jsp.JspWriter                                   标准输出流
        
        config                              javax.servlet.ServletConfig                                  Servlet配置信息对象
        
        exception                        java.lang.Throwable                                             异常引用(isErrorPage="true")
        
        page                               javax.servlet.http.HttpServlet  (page = this)          很少用

      
    3、以上内置对象只能在service方法中“直接”使用,在其它方法中无法“直接”使用,可以间接使用。

    从小到大依次为:
    pageContext < request < session < application
    
    pageContext : 在同一个JSP页面中共享数据,不能跨JSP页面
    request : 在同一个请求中共享数据  【使用较多】
    session : 在同一个会话中共享数据  【使用较多】
    application : 所有用户共享的数据可以放到应用范围中

    pageContext只能在同一个JSP页面中共享数据。范围是最小的。
    通过pageContext这个页面上下文对象,可以获取当前页面中的其它对象。
           <%=pageContext.getRequest() %>
           <%=pageContext.getSession() %>
           <%=pageContext.getServletContext() %>
           <%=pageContext.getServletConfig() %>
        
    pageContext对象传递数据:
            pageContext.setAttribute(“username”,jack); //存
            pageContext.getAttribute(“username”); //取
           只能存储一个页面中的数据,无法跨页面。可以获取include指令包含的jsp页面中存储的数据,但是不能获取include动作包含的jsp页面中存储的数据。
            使用pageContext对象往request,session,application对象中存储数据。
                向request范围存储数据:
                    pageContext.setAttribute(“username”,”jack”,PageContext.REQUEST_SCOPE);
                向session范围存储数据:
                    pageContext.setAttribute(“username”,”jack”,PageContext.SESSION_SCOPE);
                向application范围存储数据:
                    pageContext.setAttribute(“username”,”jack”,PageContext.APPLICATION_SCOPE);


关于JSP的指令:
    1、指令的作用,是指导JSP的翻译引擎如何翻译JSP代码。
    2、JSP中共三个指令:
           * page          页面指令
           * include      包含指令
           * taglib         标签库指令
    3、指令的使用语法格式:
            <%@指令名  属性名=属性值  属性名=属性值.....%>
    4、关于JSP的page指令,page指令中常用的属性:
            * contentType        设置JSP的响应内容类型,同时在响应的内容类型后面也可以指定响应的字符编码方式
            * pageEncoding        设置JSP响应时的字符编码方式
        
            * import            组织导入
        
            * session            设置当前JSP页面中是否可以直接使用session内置对象
        
            * errorPage            错误页面
            * isErrorPage        是否是错误页面
        
            * isELIgnored        是否忽略EL表达式

关于page指令中的session属性:
       - session="true"
           * 表示在当前JSP中可以直接使用内置对象session
           * 程序执行的时候获取当前的session会话对象,若获取不到则新建session对象
        
       - session="false"
           * 表示在当前JSP中不能直接使用内置对象session
           * 但是有一些业务可能要求在当前JSP页面中获取当前的session对象,没有获取到则不新建session对象,此时需要编写                  以下程序
           * <%@page contentType="text/html; charset=UTF-8" session="false"%>
           * <%
           *     HttpSession session = request.getSession(false);
           * %>
        
       - 若session这个属性没有指定,默认值就是session="true"

关于page指令的errorPage属性:
    当前JSP页面出错之后,要跳转的页面路径,需要使用该属性指定。

关于page指令中的isErrorPage属性:
    - 用于错误页面
    - isErrorPage = "false" 表示内置对象exception无法使用【缺省情况下是false】
    - isErrorPage = "true"  表示内置对象exception可以使用

    * <%-- 使用内置对象exception打印异常堆栈追踪信息 --%>
    * <%-- exception引用指向了抛出的异常 --%>
    * <%
    *     exception.printStackTrace();
    * %>

    例:<%@page contentType="text/html; charset=UTF-8" session="true" errorPage="/error.jsp"%>
           <%@page contentType="text/html" %>
           <%@page pageEncoding="UTF-8" %>
           <%@page import="java.util.Date" %>(光标至于类名末尾,alt+/快捷导入)


关于include指令:
    1、a.jsp可以将b.jsp包含进来,当然被包含的资源不一定是jsp,也可能是其它的网络资源
    2、include作用:
           在网页中有一些主体框架,例如:网页头、网页脚,这些都是固定不变的,
           我们可以将网页头、网页脚等固定不变的单独编写到某个JSP文件中,
           在需要页面使用include指令包含进来。
           优点:
               代码量少了
               便于维护【修改一个文件就可以作用于所有的页面】
    3、在一个jsp中可以使用多个include指令
    4、include实现原理:
        4.1 编译期包含
        4.2 a.jsp包含b.jsp,底层共生成一个java源文件,一个class字节码文件,翻译期包含/编译期包含/静态联编
    
    5、静态联编的时候,多个jsp中可以共享同一个局部变量。
    因为最终翻译之后service方法只有一个。
    
    例:<%@include file="/index2.jsp" %>


关于JSP中的动作:
     语法格式:<jsp:动作名  属性名=属性值   属性名=属性值....></jsp:动作名>

关于JSP中的forward动作:
     <jsp:forward page="/index2.jsp"></jsp:forward>

关于JSP中的include动作:
     1、a.jsp包含b.jsp,底层会分别生成两个java源文件,两个class字节码文件
     2、编译阶段并没有包含,编译阶段是两个独立的class字节码文件,生成两个Servlet,两个独立的service方法
     3、使用include动作属于运行阶段包含, 实际上是在运行阶段a中的service方法调用了b中的service方法,达到了包含效果
     4、a.jsp包含b.jsp,若两个jsp文件中有重名的变量,只能使用动态包含。其余都可以使用静态包含。
     5、include动作完成的动态包含,被称为动态联编。

     例:<jsp:include page="/b.jsp"></jsp:include>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章