JSP总结

Author Avatar
stormjie 8月 08, 2018
  • 在其它设备中阅读本文章

感觉自己三分钟热度要过去了,不想更博想偷懒了,以后不知道能不能做到一周二更,果然做个快乐肥宅太舒服了。。。废话不说,今天讲JSP,下面就开始吧。

一、什么是JSP

掌握了编写Servlet程序后,我们有能力让网页“动”起来——根据不同的输入(URL参数、Session等)生成不同的页面内容。但由于Web中大量用到HTML作为展示语言,在Servlet中去拼接HTML代码显然不是一个好办法。Java EE里制定的JSP标准,就是帮助开发者基于HTML/XML来动态生成Web页面内容。

JSP全名为Java Server Pages,中文名叫Java服务器页面,其根本是一个简化的Servlet设计,它是由Sun提出的一种动态网页技术标准。在传统的网页HTML(标准通用标记语言的子集)文件中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件。

本质上来说,JSP是Servlet的一个更高层的抽象。Servlet容器会将JSP在运行时转化为Servlet程序,接下来的处理流程就和Servlet完全一样了。

下面是一个最简单的一段jsp代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">

    <title>First Jsp</title>

  </head>

  <body>
    <%
        out.print("Hello Jsp");
    %>
  </body>
</html>

对应的,Servlet容器将上面的JSP转化为Servlet如下:

package org.apache.jsp;

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

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

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

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

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    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');
      out.write('\n');

String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

      out.write("\r\n");
      out.write("\r\n");
      out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
      out.write("<html>\r\n");
      out.write("  <head>\r\n");
      out.write("    <base href=\"");
      out.print(basePath);
      out.write("\">\r\n");
      out.write("    \r\n");
      out.write("    <title>First Jsp</title>\r\n");
      out.write("\t\r\n");
      out.write("  </head>\r\n");
      out.write("  \r\n");
      out.write("  <body>\r\n");
      out.write("    ");

        out.print("Hello Jsp");

      out.write("\r\n");
      out.write("  </body>\r\n");
      out.write("</html>\r\n");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

二、JSP运行原理

当客户端浏览器向服务器发出访问一个JSP页面的请求时,服务器根据该请求加载相应的JSP页面,并对该页面进行编译,然后执行。JSP页面的执行过程如下图所示:

1.当用户访问一个JSP页面时,会向一个Servlet容器(Tomcat等)发出请求。

2.服务器根据接收到的客户端的请求来加载相应的JSP文件。

3.Web服务器中的JSP引擎会将被加载的JSP文件转化为Servlet(.java文件)。

4.JSP引擎将生成的Servlet代码编译成.class文件。

5.服务器执行这个.class文件, 将执行结果发送给浏览器进行显示。

并不是每次请求都需要重复进行这样的处理。当服务器第一次接收到对某个页面的请求时,JSP引擎就开始按照上述的处理过程来将被请求的JSP文件编译成.class文件。当再次对该页面进行请求时,如果该页面没有任何改动,服务器就会直接调用对应的.class文件来执行,因此当某个JSP页面第一次被请求时,会有一些延迟,而再次访问时会感觉速度快了很多。如果被请求的页面经过了修改,那么服务器会重新编译这个文件,然后再执行。

三、JSP基础语法

1.JSP表达式

JSP表达式用于向页面中输出信息,其语法格式如下:

<%= expression %>

参数说明:

expression:可以是任何Java语言的完整表达式,该表达式的最终运算结果将被转换为字符串。

需要注意 :

(1)JSP 的表达式中没有分号 !

(2)”%=” 间不能有空格

程序示例:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>
<p>
   今天的日期是: <%= (new java.util.Date()).toLocaleString()%>
</p>
</body> 
</html> 
2.JSP脚本片断

JSP脚本片断(scriptlet)用于在JSP页面中编写多行Java代码,其语法格式如下:

<%            
    多行java代码     
%>

需要注意 :

(1)在<% %>中可以定义变量,编写语句,不能定义方法。

(2)JSP脚本片断中只能出现java代码,不能出现其它模板元素,JSP引擎在翻译JSP页面中,会将JSP脚本片断中的Java代码将被原封不动地放到Servlet的_jspService方法中。

(3)在一个JSP页面中可以有多个脚本片断,在两个或多个脚本片断之间可以嵌入文本、HTML标记和其他JSP元素。

(4)JSP脚本片断中的Java代码必须严格遵循Java语法,例如,每执行语句后面必须用分号结束。

程序示例:

<%
    int sum=0; 
    for(int i=1;i<=100;i++) {
        sum+=i;
    }
    out.println("<h1>Sum="+sum+"</h1>");
%>
3.JSP声明

JSP页面中编写的所有代码,默认会翻译到Servlet的service方法中, 而JSP声明中的Java代码被翻译到_jspService方法的外面,其语法格式如下:

<% !           
    Java代码     
%>

需要注意 :

(1)声明以 “<%!” 开头 , 以 “%>” 结尾 , “%!” 必须紧挨。

(2)多个静态代码块,变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象。

程序示例:

<%! int i = 0; %> 
<%! int a, b, c; %> 
<%! Circle a = new Circle(2.0); %>
4.JSP注释

JSP 程序的注释有隐藏注释、HTML 注释、Java 语言注释

(1)隐藏注释是 JSP 的标准注释 , 在编写 JSP 程序中 , 在发布网页时完全被忽略, 不发送至客户端。

语法格式如下 :

<%-- comment --%>

comment 为被注释内容

(2)HTML 注释在发布网页时可以在浏览器文件窗口中看到 HTML 注释 , 在这种注释中 , 也可以使用 JSP 的表达式。

语法格式如下 :

<!-- comment [<%=expression%>]-->  

comment 为被注释内容

(3)Java 注释和隐藏注释相似 , 在浏览器的源文件窗口中也看不到注释内容。

语法格式如下:

<%// 单行注释 %>

<%/* 多行注释 */%>

5.JSP指令

JSP指令用来设置与整个JSP页面相关的属性。

JSP指令语法格式:

<%@ directive attribute="value" %>

这里有三种指令标签:

指令 描述
<%@ page … %> 定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等
<%@ include … %> 包含其他文件
<%@ taglib … %> 引入标签库的定义,可以是自定义标签
6.JSP行为

JSP行为标签使用XML语法结构来控制Servlet引擎。它能够动态插入一个文件,重用JavaBean组件,引导用户去另一个页面,为Java插件产生相关的HTML等等。

行为标签只有一种语法格式,它严格遵守XML标准:

<jsp:action_name attribute="value" />

行为标签基本上是一些预先就定义好的函数,下表罗列出了一些可用的JSP行为标签:

语法 描述
jsp:include 用于在当前页面中包含静态或动态资源
jsp:useBean 寻找和初始化一个JavaBean组件
jsp:setProperty 设置 JavaBean组件的值
jsp:getProperty 将 JavaBean组件的值插入到 output中
jsp:forward 从一个JSP文件向另一个文件传递一个包含用户请求的request对象
jsp:plugin 用于在生成的HTML页面中包含Applet和JavaBean对象
jsp:element 动态创建一个XML元素
jsp:attribute 定义动态创建的XML元素的属性
jsp:body 定义动态创建的XML元素的主体
jsp:text 用于封装模板数据
7.JSP隐含对象

JSP支持九个自动定义的变量,江湖人称隐含对象。这九个隐含对象的简介见下表:

对象 描述
request HttpServletRequest类的实例
response HttpServletResponse类的实例
out PrintWriter类的实例,用于把结果输出至网页上
session HttpSession类的实例
application ServletContext类的实例,与应用上下文有关
config ServletConfig类的实例
pageContext PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问
page 类似于Java类中的this关键字
Exception Exception类的对象,代表发生错误的JSP页面中对应的异常对象

好了,JSP的内容有点多,我就先介绍到这里了,理论知识很多,记不住就多敲多看,有兴趣的可以再去网上看看EL表达式和自定义标签,但是我不建议花太多时间。以后如果想到什么重要的还会添加的,如果有什么疑惑或者错误欢迎联系我。

参考文章:菜鸟教程–JSP语法