Java Web之JSP技术

   JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术。JSP这门技术的最大的特点在于,写jsp就像在写html,但它相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。

1、JSP运行原理

  当用户第一次访问JSP页面时,该页面会被JSPServlet翻译成一个Servlet源文件,然后将源文件翻译成.class文件。Servlet源文件和.class文件一般放在当前Work Space下的.metadata中,可以在该目录下搜索对应的Servlet源文件和.class文件。以下是一个简单的JSP程序,文件名称为index.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" %>

<html>
<head>
    <title>servlet学习</title>
</head>
<body>
    <% out.println(new java.util.Date().toLocaleString()); %>
</body>
</html>

  搜索对应的Servlet源文件和.class文件,文件结构如下所示:

  可以看出,index.jsp文件被翻译成了index_jsp.java和index_jsp.class,打开index_jsp.java文件,翻译后的Servlet源码如下:

/*
 * Generated by the Jasper component of Apache Tomcat
 * Version: Apache Tomcat/8.0.30
 * Generated at: 2016-05-27 01:49:52 UTC
 * Note: The last modified time of this file was set to
 *       the last modified time of the source file after
 *       generation to assist with modification tracking.
 */
package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent,
                 org.apache.jasper.runtime.JspSourceImports {

  private static final javax.servlet.jsp.JspFactory _jspxFactory =
          javax.servlet.jsp.JspFactory.getDefaultFactory();

  private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;

  private static final java.util.Set<java.lang.String> _jspx_imports_packages;

  private static final java.util.Set<java.lang.String> _jspx_imports_classes;

  static {
    _jspx_imports_packages = new java.util.HashSet<>();
    _jspx_imports_packages.add("javax.servlet");
    _jspx_imports_packages.add("javax.servlet.http");
    _jspx_imports_packages.add("javax.servlet.jsp");
    _jspx_imports_classes = null;
  }

  private volatile javax.el.ExpressionFactory _el_expressionfactory;
  private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;

  public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
    return _jspx_dependants;
  }

  public java.util.Set<java.lang.String> getPackageImports() {
    return _jspx_imports_packages;
  }

  public java.util.Set<java.lang.String> getClassImports() {
    return _jspx_imports_classes;
  }

  public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
    if (_el_expressionfactory == null) {
      synchronized (this) {
        if (_el_expressionfactory == null) {
          _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
        }
      }
    }
    return _el_expressionfactory;
  }

  public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
    if (_jsp_instancemanager == null) {
      synchronized (this) {
        if (_jsp_instancemanager == null) {
          _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
        }
      }
    }
    return _jsp_instancemanager;
  }

  public void _jspInit() {
  }

  public void _jspDestroy() {
  }

  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

final java.lang.String _jspx_method = request.getMethod();
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD");
return;
}

    final javax.servlet.jsp.PageContext pageContext;
    javax.servlet.http.HttpSession session = null;
    final javax.servlet.ServletContext application;
    final javax.servlet.ServletConfig config;
    javax.servlet.jsp.JspWriter out = null;
    final java.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("
");
      out.write("
");
      out.write("<html>
");
      out.write("<head>
");
      out.write("	<title>servlet学习</title>
");
      out.write("</head>
");
      out.write("<body>
");
      out.write("	");
 out.println(new java.util.Date().toLocaleString()); 
      out.write("
");
      out.write("</body>
");
      out.write("</html>");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof 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);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

  从代码中看出,index.jsp翻译后的Servlet类为index_jsp,其并没有实现Servlet接口,但是继承了org.apache.jasper.runtime.HttpJspBase类,在Tomcat源文件中查看HttpJspBase类源码可以得出:HttpJspBase继承了HttpServlet,也就是说index_jsp类也是一个Servlet。HttpJspBase中的service()直接调用了_jspService()方法,也就是调用了index_jsp中的_jspService()方法。

2、JSP基本语法

JSP表达式

  JSP表达式用于将程序数据输出到客户端,它将要输出的变量或者表达式直接封装在以"<%= expression %>"结尾的标记中。

<%= expression %>

JSP脚本片段

  JSP脚本片段是指嵌套在"<%"和"%>"之中的一条或多条Java程序代码,这些Java代码必须遵循Java语法规范,否则编译报错。

<%
    int num = 1;
    out.println(num);
%>

JSP声明

  当JSP页面被翻译成Servlet程序时,JSP包含的脚本片段、表达式、模板元素都将转换为Servlet中_jspService()方法的程序代码,这是,JSP脚本片段中定义的变量都将成为_jspService()中的程序代码,这时,JSP脚本片段中定义的方法都将插入到_jspService()中,这显然会引起语法错误。为了解决这个问题,在JSP提供了声明,以"<%!"开头,"%>"结尾。格式如下:

<%!
    java代码
%>

JSP注释

  JSP有自己的注释方式,语法格式如下:

<%-- 注释信息 --%>

3、JSP指令

   JSP2.0中定义了page、include和taglib三种指令,每种指令都定义了各自的属性。

page指令

<%@ page 属性名="属性值" %>

page指令的主要常用属性 

属性名称 气质范围 功能
language java jsp文件采用的语言,默认Java
import 任何报名、类名 指定导入的包或类
session true或false JSP是否内置session对象,默认session属性为true
buffer none或者数字+kb 指定缓存大小,也就是out缓冲区大小
isErrorPage true或者false 该页面是否是错误处理页面
errorPage 某个JSP页面的路径 制定一个错误处理页 

使用page指令程序示例

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page import="java.util.Date" %>

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>servlet学习</title>
</head>
<body>
    <%= new Date() %>
</body>
</html>

include指令

  有时在JSP页面上需要包含一个HTML文件、文本文件时,可以通过include指令来实现,语法格式如下:

<%@ include file="relativeURL" %>

4、JSP隐式对象

  JSP页面中,有一些对象需要频繁使用,因此,JSP提供了9个隐式对象,他们是JSP默认创建的,可以直接在JSP页面上使用,以下是JSP的9个隐式对象。

隐式对象名称 类型 功能
out javax.servlet.jsp.JspWriter 页面输出
request javax.servlet.http.Request 得到用户请求信息
response javax.servlet.http.Response 服务器响应信息
config javax.servlet.ServletConfig 服务器配置,可获取初始化参数
session javax.servlet.http.HttpSession 保存用户信息
application javax.servlet.ServletContext 所有用户共享的信息
page java.lang.Object 当前页面转换后的Servlet类实例
pageContext javax.servlet.jsp.PageContext JSP页面容器
exception java.lang.Throwable JSP页面发生的异常,只在错误页起作用

out对象

  JSP页面中,需要向客户端发送文本内容时,可以使用out对象来实现,其是javax.servlet.jsp.JspWriter的实例对象,作用和ServletResponse.getWrite()返回的PrintWrite对象类似。不同的是,out对象是一种带缓存功能的PrintWrite,其缓冲区大小可以有page指令来设置。

  注意:out对象通过print写入数据后,知道整个JSP页面结束,out对象输入缓冲区的数据才真正写入到Servlet提供的缓冲区中,而Response.getWrite().print语句是直接把内容写入到Servlet提供的缓冲区中的。

pageContext对象

  JSP页面中要想获取隐式对象,可以使用pageContext对象,它是javax.servlet.jsp.PageContext的实例,代表当前JSP页面的运行环境,并提供了一些列用于获取其他隐式对象的方法。

方法 功能
JspWrite getOut() 获取out隐式对象
Object getPage() 获取page隐式对象
ServletRequest getRequest() 获取request隐式对象
ServletResponse getResponse() 获取response隐式对象
HttpSession getSession() 获取session隐式对象
Exception getException() 获取exception隐式对象
ServletConfig getServletConfig() 获取config隐式对象
ServletContext getServletContext() 获取application隐式对象

参考资料

  1、Java Web之Servlet技术

  2、《Java Web程序开发入门》 第7章节

  3、javaweb学习总结(十四)——JSP原理

原文地址:https://www.cnblogs.com/luoxn28/p/5528280.html