jsp服务器端页面技术

1.1.1   JSP概述

1.1.1.1 什么是JSP

JSP全名是Java Server Pages,它是建立在Servlet规范之上的动态网页开发技术。在JSP文件中,HTML代码与Java代码共同存在,其中,HTML代码用来实现网页中静态内容的显示,Java代码用来实现网页中动态内容的显示。为了与传统HTML有所区别,JSP文件的扩展名为.jsp。

JSP技术所开发的Web应用程序是基于Java的,它可以用一种简捷而快速的方法从Java程序生成Web页面,其使用上具有如下几点特征:

跨平台:由于JSP是基于Java语言的,它可以使用Java API,所以它也是跨平台的,可以应用于不同的系统中,如Windows、Linux等。当从一个平台移植到另一个平台时,JSP和JavaBean的代码并不需要重新编译,这是因为Java的字节码是与平台无关的,这也应验了Java语言“一次编译,到处运行”的特点。

业务代码相分离:在使用JSP技术开发Web应用时,可以将界面的开发与应用程序的开发分离开。开发人员使用HTML来设计界面,使用JSP标签和脚本来动态生成页面上的内容。在服务器端,JSP引擎(或容器,本书中指Tomcat)负责解析JSP标签和脚本程序,生成所请求的内容,并将执行结果以HTML页面的形式返回到浏览器。

组件重用:JSP中可以使用JavaBean编写业务组件,也就是使用一个JavaBean类封装业务处理代码或者作为一个数据存储模型,在JSP页面中,甚至在整个项目中,都可以重复使用这个JavaBean,同时,JavaBean也可以应用到其他Java应用程序中。

预编译:预编译就是在用户第一次通过浏览器访问JSP页面时,服务器将对JSP页面代码进行编译,并且仅执行一次编译。编译好的代码将被保存,在用户下一次访问时,会直接执行编译好的代码。这样不仅节约了服务器的CPU资源,还大大的提升了客户端的访问速度。

1.1.1.2 编写第一个JSP文件

在Eclipse中,创建一个名称为day17的Web项目,然后右击WebContent目录à【new】à【Other】,在弹出的窗口中找到JSP文件,如图1-1所示。

填写完图1-2中JSP文件名称后,点击【Next】按钮,进入选择模板窗口,此处采用默认设置,如图1-3所示。

以被JSP容器所解析。实际上,JSP只是在原有的HTML文件中加入了一些具有Java特点的代码,这些代码具有其独有的特点,称为JSP的语法元素。

1.1.1.1 JSP运行原理

JSP的工作模式是请求/响应模式,客户端首先发出HTTP请求,JSP程序收到请求后进行处理并返回处理结果。在一个JSP文件第一次被请求时,JSP引擎(容器)把该JSP文件转换成为一个Servlet,而这个引擎本身也是一个Servlet。JSP的运行过程如图1-6所示。

JSP的运行过程具体如下:

(1)客户端发出请求,请求访问JSP文件。

(2)JSP容器先将JSP文件转换成一个Java源文件(Java Servlet源程序),在转换过程中,如果发现JSP文件中存在任何语法错误,则中断转换过程,并向服务端和客户端返回出错信息。

(3)如果转换成功,则JSP容器将生成的Java源文件编译成相应的字节码文件*.class。该class文件就是一个Servlet,Servlet容器会像处理其他Servlet一样来处理它。

为了使同学们更容易理解JSP的运行原理,接下来简单介绍分析一下JSP所生成的Servlet代码。

以HelloWorld.jsp为例,当用户第一次访问HelloWorld.jsp页面时,该页面会先被JSP容器转换为一个名称为HelloWorld_jsp.java的源文件,然后将源文件编译为一个名称为HelloWorld_jsp.class字节码文件。如果项目发布在Tomcat的webapps目录中,源文件和.class文件可以在“Tomcat安装目录/work/Catalina/localhost/项目名/org/apache/jsp”下找到,如图1-7所示。

图1-1    JSP文件编译后的文件

在图1-7中,地址栏中的路径多出了org\apache\jsp,这是由于JSP文件转换成类文件时会带有包名,该包名为org.apache.jsp。从图中还可以看出,HelloWorld.jsp已被转换为源文件和.class文件。打开HelloWorld_jsp.java文件,可查看转换后的源代码,其主要代码如下所示。(以下代码可以快速浏览,确定父类和方法名即可)

package org.apache.jsp;

...

public final class HelloWorld_jsp

extends org.apache.jasper.runtime.HttpJspBase

                  implementsorg.apache.jasper.runtime.JspSourceDependent {

...

  public void_jspInit() {

   _el_expressionfactory = _jspxFactory.getJspApplicationContext(

getServletConfig().getServletContext()).getExpressionFactory();

   _jsp_instancemanager = org.apache.jasper.runtime

.InstanceManagerFactory.getInstanceManager(getServletConfig());

  }

  public void_jspDestroy() {

  }

public void _jspService(final javax.servlet.http.HttpServletRequestrequest,

                    final javax.servlet.http.HttpServletResponse response)

       throws java.io.IOException, javax.servlet.ServletException {

    finaljavax.servlet.jsp.PageContext pageContext;

   javax.servlet.http.HttpSession session = null;

    finaljavax.servlet.ServletContext application;

    finaljavax.servlet.ServletConfig config;

   javax.servlet.jsp.JspWriter out = null;

    finaljava.lang.Object page = this;

   javax.servlet.jsp.JspWriter _jspx_out = null;

   javax.servlet.jsp.PageContext _jspx_page_context = null;

    try {

     response.setContentType("text/html; charset=UTF-8");

     pageContext = _jspxFactory.getPageContext(this, request, response,

                 null, true, 8192, true);

     _jspx_page_context = pageContext;

     application = pageContext.getServletContext();

      config= pageContext.getServletConfig();

      session= pageContext.getSession();

      out =pageContext.getOut();

     _jspx_out = out;

     out.write("\r\n");

     out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01Transitional//EN\"\"http://www.w3.org/TR/html4/loose.dtd\">\r\n");

     out.write("<html>\r\n");

     out.write("<head>\r\n");

     out.write("<meta http-equiv=\"Content-Type\"content=\"text/html; charset=UTF-8\">\r\n");

     out.write("<title>Insert title here</title>\r\n");

     out.write("</head>\r\n");

     out.write("<body>\r\n");

      out.write("     My First JSP\r\n");

     out.write("</body>\r\n");

     out.write("</html>");

    } catch(java.lang.Throwable t) {

      if (!(tinstanceof javax.servlet.jsp.SkipPageException)){

        out =_jspx_out;

        if(out != null && out.getBufferSize() != 0)

          try{

           if (response.isCommitted()) {

             out.flush();

            }else {

             out.clearBuffer();

            }

          }catch (java.io.IOException e) {}

if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);

        elsethrow new ServletException(t);

      }

    } finally{

     _jspxFactory.releasePageContext(_jspx_page_context);

    }

  }

}

从上面的代码可以看出,HelloWorld.jsp文件转换后的源文件没有实现Servlet接口,但继承了org.apache.jasper.runtime.HttpJspBase类。在Tomcat源文件中查看HttpJspBase类的源代码,具体如下所示:(以下代码可以快速阅读,确定父类即可)

package org.apache.jasper.runtime;

...

public abstract class HttpJspBase extendsHttpServlet implements HttpJspPage {  

    privatestatic final long serialVersionUID = 1L;

    protectedHttpJspBase() {

    }

    @Override

    publicfinal void init(ServletConfig config)

       throws ServletException

    {

       super.init(config);

       jspInit();

        _jspInit();

    }  

    @Override

    publicString getServletInfo() {

       return Localizer.getMessage("jsp.engine.info");

    }

    @Override

    publicfinal void destroy() {

       jspDestroy();

       _jspDestroy();

    }

    @Override

    publicfinal void service(HttpServletRequest request,

HttpServletResponse response)

       throws ServletException, IOException

    {

       _jspService(request, response);

    }

    @Override

    publicvoid jspInit() {

    }

    publicvoid _jspInit() {

    }

    @Override

    publicvoid jspDestroy() {

    }

    protectedvoid _jspDestroy() {

    }

    @Override

    publicabstract void _jspService(HttpServletRequest request,

                                    HttpServletResponse response)

        throws ServletException, IOException;

}

从HttpJspBase源代码中可以看出,HttpJspBase类是HttpServlet的一个子类,由此可见,HelloWorld_jsp类就是一个Servlet。 结论:JSP就是Servlet


猜你喜欢

转载自blog.csdn.net/shitianhang123/article/details/79284178
今日推荐