JSP

Take my wine in my own cup, friend.
It loses its wreath of foam when poured into that of others.

在我自己的杯中,饮了我的酒吧,朋友。一倒在别人的杯里,这酒的腾跳的泡沫便要消失了。

Java Server Pages

JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。

JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。

JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。

JSP标签有多种功能,比如访问数据库、记录用户选择信息、访问JavaBeans组件等,还可以在不同的网页中传递控制信息和共享信息。

JSP 处理

以下步骤表明了 Web 服务器是如何使用JSP来创建网页的:

  • 就像其他普通的网页一样,您的浏览器发送一个 HTTP 请求给服务器。
  • Web 服务器识别出这是一个对 JSP 网页的请求,并且将该请求传递给 JSP 引擎。通过使用 URL或者 .jsp 文件来完成。
  • JSP 引擎从磁盘中载入 JSP 文件,然后将它们转化为 Servlet。这种转化只是简单地将所有模板文本改用 println() 语句,并且将所有的 JSP 元素转化成 Java 代码。
  • JSP 引擎将 Servlet 编译成可执行类,并且将原始请求传递给 Servlet 引擎。
  • Web 服务器的某组件将会调用 Servlet 引擎,然后载入并执行 Servlet 类。在执行过程中,Servlet 产生 HTML 格式的输出并将其内嵌于 HTTP response 中上交给 Web 服务器。
  • Web 服务器以静态 HTML 网页的形式将 HTTP response 返回到您的浏览器中。
  • 最终,Web 浏览器处理 HTTP response 中动态产生的HTML网页,就好像在处理静态网页一样。

一般情况下,JSP 引擎会检查 JSP 文件对应的 Servlet 是否已经存在,并且检查 JSP 文件的修改日期是否早于 Servlet。如果 JSP 文件的修改日期早于对应的 Servlet,那么容器就可以确定 JSP 文件没有被修改过并且 Servlet 有效。这使得整个流程与其他脚本语言(比如 PHP)相比要高效快捷一些。

总的来说,JSP 网页就是用另一种方式来编写 Servlet 而不用成为 Java 编程高手。除了解释阶段外,JSP 网页几乎可以被当成一个普通的 Servlet 来对待。

JSP 生命周期

JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。

以下是JSP生命周期中所走过的几个阶段:

  1. 编译阶段:

    servlet容器编译servlet源文件,生成servlet类

  2. 初始化阶段:

    加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法

  3. 执行阶段:

    调用与JSP对应的servlet实例的服务方法

  4. 销毁阶段:

    调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例

JSP编译

当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。

Mac文件地址:~/Library/Caches/JetBrains/IntelliJIdea/tomcat/项目名/work/Catalina/localhost/ROOT/org/apache/jsp/index_jsp.java

编译的过程包括三个步骤:

  • 解析JSP文件。
  • 将JSP文件转为servlet。
  • 编译servlet。
  1. JSP初始化

    1
    2
    3
    public void jspInit(){
    // 初始化代码
    }

    一般来讲程序只初始化一次,servlet也是如此。通常情况下您可以在jspInit()方法中初始化数据库连接、打开文件和创建查询表。

  2. JSP执行

    1
    2
    3
    4
    void _jspService(HttpServletRequest request,HttpServletResponse response)
    {
    // 服务端处理代码
    }

    当JSP网页完成初始化后,JSP引擎将会调用_jspService()方法。

  3. JSP清理

    1
    2
    3
    4
    public void jspDestroy()
    {
    // 清理代码
    }

输出页面前新增的代码:

1
2
3
4
5
6
7
8
9
response.setContentType("text/html"); //设置相应的页面类型
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;

以上这些对象可以在jsp对象中直接使用

JSP 隐式对象(内置)

JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。

1
2
3
4
5
6
7
8
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;
对象 描述
request HttpServletRequest 接口的实例
response HttpServletResponse 接口的实例
out JspWriter类的实例,用于把结果输出至网页上
session HttpSession类的实例
application ServletContext类的实例,与应用上下文有关
config ServletConfig类的实例
pageContext PageContext类的实例,提供对JSP页面所有对象以及命名空间的访问
page 类似于Java类中的this关键字
Exception Exception类的对象,代表发生错误的JSP页面中对应的异常对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<%--内置对象--%>
<%
pageContext.setAttribute("name1","1"); //保存的数据只在一个页面中有效
request.setAttribute("name2","2"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","3"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","4"); //保存的数据只在一次服务器中有效,从打开服务器到关闭服务器
%>

<%
//通过pageContext取出我们保存的值
//通过寻找的方式
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
String name5 = (String) pageContext.findAttribute("name5");
%>

<%--使用EL表达式输出 ${}--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<%--使用EL表达式输出 不存在不会输出--%>
<h3>${name5}</h3>
<%--原始方式输出 不存在会输出null--%>
<h3><%=name5%></h3>

语法

JSPMaven导包

JSP注释

语法 描述
<%– 注释 –%> JSP注释,注释内容不会被发送至浏览器甚至不会被编译
HTML注释,通过浏览器查看网页源代码时可以看见注释内容
<\% 代表静态 <%常量
%> 代表静态 %> 常量
\’ 在属性中使用的单引号
\” 在属性中使用的双引号

脚本程序

1
2
3
4
5
<% 代码片段 %>
<!-- 或 -->
<jsp:scriptlet>
代码片段
</jsp:scriptlet>

中文编码问题

1
2
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>

JSP声明

一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用。在JSP文件中,您必须先声明这些变量和方法然后才能使用它们。

1
2
3
4
5
<%! declaration; [ declaration; ]+ ... %>
<!-- 或 -->
<jsp:expression>
代码片段
</jsp:expression>

JSP表达式

将程序结果输出到客户端

1
2
3
4
5
<%= 表达式 %>
<!-- 或 -->
<jsp:declaration>
代码片段
</jsp:declaration>

JSP指令

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

JSP行为

1
<jsp:action_name attribute="value" />
语法 描述
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 用于封装模板数据
  • <%@ include %>将两个页面合为一整个页面
  • <jsp:include>将页面拼接

JSTL标签

弥补HTML标签的不足

  1. 核心标签

    导入标签库

    1
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

    | 标签 | 描述 |
    | :————-: | :———————————————————-: |
    | <<c:out>> | 用于在JSP中显示数据,就像<%= … > |
    | <<c:set>> | 用于保存数据 |
    | <<c:if>> | <<c:if>>标签判断表达式的值,如果表达式的值为 true 则执行其主体内容。 |
    | <<c:remove>> | 用于删除数据 |
    | <<c:forEach>> | 基础迭代标签,接受多种集合类型 |
    | <<c:url>> | 使用可选的查询参数来创造一个URL |
    | <<c:choose>> | 本身只当做<<c:when>>和<<c:otherwise>>的父标签 |
    | <<c:when>> | <<c:choose>>的子标签,用来判断条件是否成立 |
    | <<c:otherwise>> | <<c:choose>>的子标签,接在<<c:when>>标签后,当<<c:when>>标签判断为false时被执行 |

JSP JavaBean

JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取。众所周知,属性名称符合这种模式,其他Java 类可以通过自省机制(反射机制)发现和操作这些JavaBean 的属性。

  • 提供一个默认的无参构造函数。
  • 需要被序列化并且实现了 Serializable 接口。
  • 可能有一系列可读写属性。
  • 可能有一系列的 gettersetter 方法

JavaBean 属性

一个 JavaBean 对象的属性应该是可访问的。这个属性可以是任意合法的 Java 数据类型,包括自定义 Java 类。

一个 JavaBean 对象的属性可以是可读写,或只读,或只写。JavaBean 对象的属性通过 JavaBean 实现类中提供的两个方法来访问:

方法 描述
getPropertyName() 举例来说,如果属性的名称为 myName,那么这个方法的名字就要写成 getMyName() 来读取这个属性。这个方法也称为访问器。
setPropertyName() 举例来说,如果属性的名称为 myName,那么这个方法的名字就要写成 setMyName()来写入这个属性。这个方法也称为写入器。

一个只读的属性只提供 getPropertyName() 方法,一个只写的属性只提供 setPropertyName() 方法。

访问JavaBean

<jsp:useBean>标签可以在 JSP 中声明一个 JavaBean,然后使用。声明后,JavaBean 对象就成了脚本变量,可以通过脚本元素或其他自定义标签来访问。<jsp:useBean>标签的语法格式如下:

1
<jsp:useBean id="bean 的名字" class="com.bobo.pojo.类名" scope="bean 的作用域" />

scope 的值可以是 page,request,session 或 application。id值可任意只要不和同一 JSP 文件中其它 <jsp:useBean> 中 id 值一样就行了

访问 JavaBean 对象的属性

在 <jsp:useBean> 标签主体中使用 <jsp:getProperty/> 标签来调用 getter 方法,使用 <jsp:setProperty/> 标签来调用 setter 方法,语法格式如下:

1
2
3
4
5
6
<jsp:useBean id="id" class="bean 编译的类" scope="bean 作用域">
<jsp:setProperty name="bean 的 id" property="属性名"
value="value"/>
<jsp:getProperty name="bean 的 id" property="属性名"/>
...........
</jsp:useBean>
查看评论