zoukankan      html  css  js  c++  java
  • javaEE(6)_JSP

    一、什么是JSP

    1、JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术,只用JSP就可以开发动态web资源.

    2、为什么JSP技术也是一种动态web资源的开发技术?

    答:因为JSP技术允许在页面中嵌套java代码,以产生动态数据,并且web服务器在执行jsp时,web服务器会传递web开发相关的对象给jsp,jsp通过这些对象,可以与浏览器进行交互,所以jsp当然也是一种动态web资源开发技术.

    3、强调一个概念:对现在的用户而言,认为通过浏览器看到的东西都是网页.但我们程序员心里要清楚,开一个浏览器访问网页,这些网页有可能是一个html页面(即静态web资源),也有可能是一个动态web资源(即servlet或jsp程序输出的).

    4、JSP这门技术的最大的特点在于,写jsp就像在写html,但:
    •它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据.
    •相比servlet而言,servlet很难对数据进行排版,而jsp除了可以用java代码产生动态数据的同时,也很容易对数据进行排版.
    5、Jsp快速入门:在jsp页面中输出当前时间.观察jsp编译后的class文件,发现其实jsp就是servlet,jsp中嵌套的java代码会原封不动的放到JSP的service方法中.打印日期的jsp页面和编译后class源码:
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.Date"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <%
            Date date = new Date();
        %>
        <%= date %>
    </body>
    </html>
    package org.apache.jsp.jsp;
    
    import java.io.IOException;
    import java.util.Date;
    import java.util.Map;
    import javax.el.ExpressionFactory;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.jsp.JspApplicationContext;
    import javax.servlet.jsp.JspFactory;
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.PageContext;
    import javax.servlet.jsp.SkipPageException;
    import org.apache.jasper.runtime.HttpJspBase;
    import org.apache.jasper.runtime.InstanceManagerFactory;
    import org.apache.jasper.runtime.JspSourceDependent;
    import org.apache.tomcat.InstanceManager;
    
    public final class NewFile_jsp extends HttpJspBase
      implements JspSourceDependent
    {
      private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();
      private static Map<String, Long> _jspx_dependants;
      private ExpressionFactory _el_expressionfactory;
      private InstanceManager _jsp_instancemanager;
    
      public Map<String, Long> getDependants()
      {
        return _jspx_dependants;
      }
    
      public void _jspInit() {
        this._el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        this._jsp_instancemanager = InstanceManagerFactory.getInstanceManager(getServletConfig());
      }
    
      public void _jspDestroy()
      {
      }
    
      public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException
      {
        JspWriter out = null;
    
        JspWriter _jspx_out = null;
        PageContext _jspx_page_context = null;
        try
        {
          response.setContentType("text/html; charset=UTF-8");
          PageContext pageContext = _jspxFactory.getPageContext(this, request, response, 
            null, true, 8192, true);
          _jspx_page_context = pageContext;
          pageContext.getServletContext();
          pageContext.getServletConfig();
          pageContext.getSession();
          out = pageContext.getOut();
          _jspx_out = out;
    
          out.write("
    ");
          out.write("<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    ");
          out.write("<html>
    ");
          out.write("<head>
    ");
          out.write("<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    ");
          out.write("<title>Insert title here</title>
    ");
          out.write("</head>
    ");
          out.write("<body>
    ");
          out.write("	");
    
          Date date = new Date();
    
          out.write(13);
          out.write(10);
          out.write(9);
          out.print(date);
          out.write("
    ");
          out.write("</body>
    ");
          out.write("</html>");
        } catch (Throwable t) {
          if (!(t instanceof SkipPageException)) {
            out = _jspx_out;
            if ((out != null) && (out.getBufferSize() != 0)) try {
                out.clearBuffer(); } catch (IOException localIOException) {
              } if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); else
              throw new ServletException(t);
          }
        } finally {
          _jspxFactory.releasePageContext(_jspx_page_context);
        }
      }
    }
    View Code

    二、JSP技术在开发中该怎么去用

    1、不管是JSP还是Servlet,虽然都可以用于开发动态web资源.但由于这2门技术各自的特点,在长期的软件实践中,人们逐渐把servlet作为web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用.
    2、其原因为,程序的数据通常要美化后再输出:
    •让jsp既用java代码产生动态数据,又做美化会导致页面难以维护.
    •让servlet既产生数据,又在里面嵌套html代码美化数据,同样也会导致程序可读性差,难以维护.
    •因此最好的办法就是根据这两门技术的特点,让它们各自负责各的,servlet只负责响应请求产生数据,并把数据通过转发技术带给jsp,数据的显示jsp来做.其实就是一个servlet转发给另外一个servlet.

    三、JSP语法

    1、JSP模版元素

    JSP页面中的HTML内容称之为JSP模版元素,JSP模版元素定义了网页的基本骨架,即定义了页面的结构和外观.
    2、JSP脚本表达式
    JSP脚本表达式(expression)用于将程序数据输出到客户端
    语法:<%= 变量或表达式 %>
    
    举例:当前时间:<%= new java.util.Date() %>
    JSP引擎(把jsp翻译为servlet的程序,也就是tomcat)在翻译脚本表达式时,会将程序数据转成字符串,然后在相应位置用out.print(…) 将数据输给客户端.
    JSP脚本表达式中的变量或表达式后面不能有分号(;).
    3、JSP脚本片断
    1>JSP脚本片断(scriptlet)用于在JSP页面中编写多行Java代码.语法:
    <%
      多行java代码
    %>
    注意:JSP脚本片断中只能出现java代码,不能出现其它模板元素, JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中.JSP脚本片断中的Java代码必须严格遵循Java语法.
    2>在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素.例:
    <%
      int x = 10;
      out.println(x);
    %>
    <p>这是JSP页面文本</p>
    <%
      int y = 20;
      out.println(y);
    %>

    多个脚本片断中的代码可以相互访问,犹如将所有的代码放在一对<%%>之中的情况.如:out.println(x);

    3>单个脚本片断中的Java语句可以是不完整的,但是,多个脚本片断组合后的结果必须是完整的Java语句,例:

    <%
        for (int i=1; i<5; i++) {
    %>
    <H1>www.it315.org</H1>
    <%
        }
    %> 

    4、JSP声明,一般很少使用

    JSP页面中编写的所有代码,默认会翻译到servlet的service方法中, 而Jsp声明中的java代码被翻译到_jspService方法的外面.语法:
    <%!
      java代码
    %>
    所以,JSP声明可用于定义JSP页面转换成的Servlet程序的静态代码块、成员变量和方法 .多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中.JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象,java脚本片段中是不能加方法,静态代码块等的,因为这些代码会被放到jsp的service方法中.
    5、JSP注释
    1>JSP注释的格式:<%-- 注释信息 --%>
    2>JSP引擎在将JSP页面翻译成Servlet程序时,忽略JSP页面中被注释的内容.注意和HTML注释区别.
    <%-- date --%> //jsp注释
    <!-- date-->      //html注释,jsp中采用这个会增加网络流量,这个是打回浏览器后浏览器不显示.
    6、JSP指令
    1.JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分.在JSP 2.0规范中共定义了三个指令:•page指令•Include指令•taglib指令.
    2.JSP指令的基本语法格式:
      <%@ 指令 属性名="" %>
      举例:<%@ page contentType="text/html;charset=gb2312"%>
    如果一个指令有多个属性,这多个属性可以写在一个指令中,也可以分开写.例:
    <%@ page contentType="text/html;charset=gb2312"%>
    <%@ page import="java.util.Date"%><%@ page contentType="text/html;charset=gb2312" import="java.util.Date"%>

    Page指令

    page指令用于定义JSP页面的各种属性,无论page指令出现在JSP页面中的什么地方,它作用的都是整个JSP页面,为了保持程序的可读性和遵循良好的编程习惯,page指令最好是放在整个JSP页面的起始位置.
    *JSP 2.0规范中定义的page指令的完整语法:
    <%@ page 
    [ language="java" ]  //页面嵌套的语言
    [ extends="package.class" ]  //jsp servlet继承的包,一般不要修改
    [ import="{package.class | package.*}, ..." ]  //jsp Servlet引入的包
    [ session="true | false" ]   //是否引入session,ture的话,jsp引擎会传给jsp Session 对象
    [ buffer="none | 8kb | sizekb" ]  //关于缓存
    [ autoFlush="true | false" ]      //关于缓存
    [ isThreadSafe="true | false" ]  //ture的话JSP servlet 会继承SingleThreadModel
    [ info="text" ]      
    [ errorPage="relative_url" ]  //JSP出错的错误页面(必须采用相对路径),web.xml也可设置
    [ isErrorPage="true | false" ]  //true的话,JSP引擎会传给jsp错误的Excepiotn 对象
    [ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=utf-8" ]//页面类型
    [ pageEncoding="characterSet | ISO-8859-1" ] //页面采用的编码,只写这句就可解决JSP乱码问题
    [ isELIgnored="true | false" ]  //是否支持使用el表达式
    %>

    include指令

    include指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet.所以include指令引入通常也称之为静态引入.
    语法:

    <%@ include file="relativeURL"%>

    其中的file属性用于指定被引入文件的相对路径.  file属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前WEB应用程序的根目录(注意不是站点根目录),否则,表示相对于当前文件.
    细节:
    被引入的文件必须遵循JSP语法.(被引入的jsp文件不要有架构性的标签,可以有指令)
    被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名.
    由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外).

    taglib指令

    用于引入标签库。

    四、JSP运行原理和九大隐式对象

    1、每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet) ,然后按照servlet的调用方式进行调用.

    2、由于JSP第一次访问时会翻译成servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响.

    3、JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用.JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用.

    4、JSP九大隐式对象与servlet的对应关系

    request   HttpServletRequest
    response  HttpServletResponse
    session   HttpSession
    application servletContext
    config    servletConfig
    out       JspWriter  ----->   PrintWriter
    exception
    page      this
    pageContext

    out隐式对象
    1、out隐式对象用于向客户端发送文本数据.
    2、out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似.
    3、JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存.
    4、只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
    1>设置page指令的buffer属性关闭了out对象的缓存功能,2>out对象的缓冲区已满,3>整个JSP页面结束

    5、out工作原理图,底层其实是调用response的writer回写给客户端的.


    *开发的时候不用同时使用servlet中的Writer和Jsp中的out,否则可能打印到页面的内容会有先后问题,因为缓冲的原因.
    pageContext对象

    pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据.并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等.
    1、通过pageContext可以获得其它八大对象,它存在的意义是什么呢,因为我们可以直接在jsp中获得九大对象.它的意义在于统一管理入口,比如用在自定义标签中,我们只要传递这一个对象给标签解析器,标签就可获得其它所有对象而不需要传递所有的对象给标签,这应该是一种思想,很多地方有体现.

    2、pageContext作为域对象(page域)

    public void setAttribute(java.lang.String name,java.lang.Object value)
    public java.lang.Object getAttribute(java.lang.String name)
    public void removeAttribute(java.lang.String name)

    3、pageContext对象中还封装了访问其它域的方法,同样的问题,我们可以直接获得相应域,为什么还要间接通过pageContext?同样的答案.

    public java.lang.Object getAttribute(java.lang.String name,int scope)
    public void setAttribute(java.lang.String name, java.lang.Object value,int scope)
    public void removeAttribute(java.lang.String name,int scope)

    上面方法会用到下面代表各个域的常量:

    PageContext.APPLICATION_SCOPE
    PageContext.SESSION_SCOPE
    PageContext.REQUEST_SCOPE
    PageContext.PAGE_SCOPE

    4、findAttribute方法    (*重点,查找各个域中的属性),其实el表达式就是在各个域中查找.
    5、web开发的四个域对象,重点,1>域的含义;2>生命周期;3>什么时候使用什么域

    pageContext(称之为page域) 
    request(称之为request域)
    session(称之为session域)
    servletContext(称之为application域)

    6、PageContext类中定义了一个forward方法和两个include方法来分别简化和替代RequestDispatcher.forward方法和include方法,传递给这些方法的资源路径都只能是相对路径,如果路径以“/”开头,表示相对于当前WEB应用程序的根目录,否则,表示相对于当前JSP所映射到的访问路径.这写方法基本不用,动态包含,用的少.而且后面有专门的标签来使用动态包含.

    五、JSP标签

    1、虽然我们希望JSP页面仅用作数据显示模块,不要嵌套任何java代码引入任何业务逻辑,但在实际开发中不引入一点业务逻辑是不可能的,但引入业务逻辑会导致页面出现难看java代码,怎么办?Sun公司允许用户开发自定义标签封装页面的java代码,以便jsp页面不出现一行java代码.当然sun公司在jsp页面中也内置了一些标签(这些标签叫做jsp标签),开发人员使用这些标签可以完成页面的一些常用业务逻辑.JSP标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能.
    2、JSP常用标签:<jsp:include>标签、<jsp:forward>标签 、<jsp:param>标签
    3、<jsp:include>标签

    <jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入.
    语法:
    <jsp:include page="relativeURL | <%=expression%>" flush="true|false" />
    page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得.
    flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端.

    4、<jsp:include>与include指令的比较
    1><jsp:include>标签是动态引入, <jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并.
    2>而include指令是静态引入,涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并.
    3>不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档
    4、<jsp:forward>标签

    <jsp:forward>标签用于把请求转发给另外一个资源.
    语法:

    <jsp:forward page="relativeURL | <%=expression%>" /> 

    page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得.
    使用场景:比如在首页中,在tomcat,web.xml中<welcome-file-list>标签中可以指定jsp页面,但是不能指定servlet,这时可以使用<jsp:forward>转发给一个servlet.<welcome-file-list>的作用:只要输域名,就可调到首页.

    5、<jsp:param>标签,了解即可

    当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数.

    6、映射JSP,例:其实和servlet一样,感觉用的不多,一般是通过servlet跳转到jsp,而不会直接访问jsp.

    <servlet>
        <servlet-name>SimpleJspServlet</servlet-name>
        <jsp-file>/jsp/simple.jsp</jsp-file>
        <load-on-startup>1</load-on-startup >
    </servlet>
        ……
    <servlet-mapping>
        <servlet-name>SimpleJspServlet</servlet-name>
        <url-pattern>/xxx/yyy.html</url-pattern>
    </servlet-mapping>
  • 相关阅读:
    DB-MySQL:MySQL 函数
    DB-MySQL:目录
    文学-人物:王阳明
    院校:伦敦大学学院
    文学-人物:曹操
    文学-人物:诸葛亮
    x2go
    PHP+jQuery 注册模块开发
    java中Runtime类详细介绍
    java中Runtime类详细介绍
  • 原文地址:https://www.cnblogs.com/wangweiNB/p/4955941.html
Copyright © 2011-2022 走看看