🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# JSP教程 JSP 与 PHP、ASP、ASP.NET等语言类似,运行在服务端的语言。 JSP(全称Java Server Pages)是由 Sun Microsystems 公司倡导和许多公司参与共同创建的一种使软件开发者可以响应客户端请求,而动态生成 HTML、XML 或其他格式文档的Web网页的技术标准。 JSP 技术是以 Java 语言作为脚本语言的,JSP 网页为整个服务器端的 Java 库单元提供了一个接口来服务于HTTP的应用程序。 JSP文件后缀名为\*.jsp。 JSP开发的WEB应用可以跨平台使用,既可以运行在 Linux 上也能运行在 Windows 上。 * * * ## 第一个 JSP 程序 语言学习入门的第一个程序一般都是输出 "Hello World",JSP输出 "Hello World" 代码如下所示: ~~~ <html> <head> <title>第一个 JSP 程序</title> </head> <body> <% out.println("Hello World!"); %> </body> </html> ~~~ * * * ## 开始学习 JSP 了解了 JSP 的基本概念后,现在让我们开始来学习 JSP吧。 # JSP简介 ## 什么是Java Server Pages? JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以结束。 JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。网页开发者们通过结合HTML代码、XHTML代码、XML元素以及嵌入JSP操作和命令来编写JSP。 JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。 JSP标签有多种功能,比如访问数据库、记录用户选择信息、访问JavaBeans组件等,还可以在不同的网页中传递控制信息和共享信息。 * * * ## 为什么使用JSP? JSP程序与CGI程序有着相似的功能,但和CGI程序相比,JSP程序有如下优势: * 性能更加优越,因为JSP可以直接在HTML网页中动态嵌入元素而不需要单独引用CGI文件。 * 服务器调用的是已经编译好的JSP文件,而不像CGI/Perl那样必须先载入解释器和目标脚本。 * JSP 基于Java Servlet API,因此,JSP拥有各种强大的企业级Java API,包括JDBC,JNDI,EJB,JAXP等等。 * JSP页面可以与处理业务逻辑的 Servlet 一起使用,这种模式被Java servlet 模板引擎所支持。 最后,JSP是Java EE不可或缺的一部分,是一个完整的企业级应用平台。这意味着JSP可以用最简单的方式来实现最复杂的应用。 * * * ## JSP的优势 以下列出了使用JSP带来的其他好处: * 与ASP相比:JSP有两大优势。首先,动态部分用Java编写,而不是VB或其他MS专用语言,所以更加强大与易用。第二点就是JSP易于移植到非MS平台上。 * 与纯 Servlet 相比:JSP可以很方便的编写或者修改HTML网页而不用去面对大量的println语句。 * 与SSI相比:SSI无法使用表单数据、无法进行数据库链接。 * 与JavaScript相比:虽然JavaScript可以在客户端动态生成HTML,但是很难与服务器交互,因此不能提供复杂的服务,比如访问数据库和图像处理等等。 * 与静态HTML相比:静态HTML不包含动态信息。 * * * ## 接下来呢? 我们将会带您一步一步地来搭建JSP运行环境,这需要有一定的Java基础。 # JSP结构 网络服务器需要一个 JSP 引擎,也就是一个容器来处理 JSP 页面。容器负责截获对 JSP 页面的请求。本教程使用内嵌 JSP 容器的 Apache 来支持 JSP 开发。 JSP 容器与 Web 服务器协同合作,为JSP的正常运行提供必要的运行环境和其他服务,并且能够正确识别专属于 JSP 网页的特殊元素。 下图显示了 JSP 容器和 JSP 文件在 Web 应用中所处的位置。 ![](http://h.yiniuedu.com/a64dbc5a8415996c04597466879f6cbb) * * * ## 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网页,就好像在处理静态网页一样。 以上提及到的步骤可以用下图来表示: ![](http://h.yiniuedu.com/210ac7b78c2556c1e68e387a3b94a59c) 一般情况下,JSP 引擎会检查 JSP 文件对应的 Servlet 是否已经存在,并且检查 JSP 文件的修改日期是否早于 Servlet。如果 JSP 文件的修改日期早于对应的 Servlet,那么容器就可以确定 JSP 文件没有被修改过并且 Servlet 有效。这使得整个流程与其他脚本语言(比如 PHP)相比要高效快捷一些。 总的来说,JSP 网页就是用另一种方式来编写 Servlet 而不用成为 Java 编程高手。除了解释阶段外,JSP 网页几乎可以被当成一个普通的 Servlet 来对待。 # JSP生命周期 理解JSP底层功能的关键就是去理解它们所遵守的生命周期。 JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet。 以下是JSP生命周期中所走过的几个阶段: * **编译阶段:** servlet容器编译servlet源文件,生成servlet类 * **初始化阶段:** 加载与JSP对应的servlet类,创建其实例,并调用它的初始化方法 * **执行阶段:** 调用与JSP对应的servlet实例的服务方法 * **销毁阶段:** 调用与JSP对应的servlet实例的销毁方法,然后销毁servlet实例 很明显,JSP生命周期的四个主要阶段和servlet生命周期非常相似,下面给出图示: ![](http://h.yiniuedu.com/a6bf74ccae71a38892647bc9419201fb) * * * ## JSP编译 当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。 编译的过程包括三个步骤: * 解析JSP文件。 * 将JSP文件转为servlet。 * 编译servlet。 * * * ## JSP初始化 容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法。如果您需要执行自定义的JSP初始化任务,复写jspInit()方法就行了,就像下面这样: ~~~ public void jspInit(){ // 初始化代码 } ~~~ 一般来讲程序只初始化一次,servlet也是如此。通常情况下您可以在jspInit()方法中初始化数据库连接、打开文件和创建查询表。 * * * ## JSP执行 这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。 当JSP网页完成初始化后,JSP引擎将会调用\_jspService()方法。 \_jspService()方法需要一个HttpServletRequest对象和一个HttpServletResponse对象作为它的参数,就像下面这样: ~~~ void _jspService(HttpServletRequest request, HttpServletResponse response) { // 服务端处理代码 } ~~~ \_jspService()方法在每个request中被调用一次并且负责产生与之相对应的response,并且它还负责产生所有7个HTTP方法的回应,比如GET、POST、DELETE等等。 * * * ## JSP清理 JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切。 jspDestroy()方法在JSP中等价于servlet中的销毁方法。当您需要执行任何清理工作时复写jspDestroy()方法,比如释放数据库连接或者关闭文件夹等等。 jspDestroy()方法的格式如下: ~~~ public void jspDestroy() { // 清理代码 } ~~~ ### 实例 JSP生命周期代码实例如下所示: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <title>life.jsp</title> </head> <body> <%! private int initVar=0; private int serviceVar=0; private int destroyVar=0; %> <%! public void jspInit(){ initVar++; System.out.println("jspInit(): JSP被初始化了"+initVar+"次"); } public void jspDestroy(){ destroyVar++; System.out.println("jspDestroy(): JSP被销毁了"+destroyVar+"次"); } %> <% serviceVar++; System.out.println("_jspService(): JSP共响应了"+serviceVar+"次请求"); String content1="初始化次数 : "+initVar; String content2="响应客户请求次数 : "+serviceVar; String content3="销毁次数 : "+destroyVar; %> <h1>JSP 测试实例</h1> <p><%=content1 %></p> <p><%=content2 %></p> <p><%=content3 %></p> </body> </html> ~~~ 浏览器打开该页面,输出结果为: **JSP 测试实例** 初始化次数 : 1 响应客户请求次数 :1 销毁次数 :0 # JSP语法 本小节将会简单地介绍一下JSP开发中的基础语法。 * * * ## 脚本程序 脚本程序可以包含任意量的Java语句、变量、方法或表达式,只要它们在脚本语言中是有效的。 脚本程序的语法格式: ~~~ <% 代码片段 %> ~~~ 或者,您也可以编写与其等价的XML语句,就像下面这样: ~~~ <jsp:scriptlet> 代码片段 </jsp:scriptlet> ~~~ 任何文本、HTML标签、JSP元素必须写在脚本程序的外面。 下面给出一个示例,同时也是本教程的第一个JSP示例: ~~~ <html> <head><title>Hello World</title></head> <body> Hello World!<br/> <% out.println("Your IP address is " + request.getRemoteAddr()); %> </body> </html> ~~~ **注意:**请确保Apache Tomcat已经安装在C:\\apache-tomcat-7.0.2目录下并且运行环境已经正确设置。 将以上代码保存在hello.jsp中,然后将它放置在 C:\\apache-tomcat-7.0.2\\webapps\\ROOT目录下,打开浏览器并在地址栏中输入http://localhost:8080/hello.jsp。运行后得到以下结果: ![](http://h.yiniuedu.com/e16713a0bfcc7dc2779eadaf43e29603) ### 中文编码问题 如果我们要在页面正常显示中文,我们需要在 JSP 文件头部添加以下代码: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> ~~~ 接下来我们将以上程序修改为: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSP教程(cms.yiniuedu.com)</title> </head> <body> Hello World!<br/> <% out.println("你的 IP 地址 " + request.getRemoteAddr()); %> </body> </html> ~~~ 这样中文就可以正常显示了。 * * * ## JSP声明 一个声明语句可以声明一个或多个变量、方法,供后面的Java代码使用。在JSP文件中,您必须先声明这些变量和方法然后才能使用它们。 JSP声明的语法格式: ~~~ <%! declaration; [ declaration; ]+ ... %> ~~~ 或者,您也可以编写与其等价的XML语句,就像下面这样: ~~~ <jsp:declaration> 代码片段 </jsp:declaration> ~~~ 程序示例: ~~~ <%! int i = 0; %> <%! int a, b, c; %> <%! Circle a = new Circle(2.0); %> ~~~ * * * ## JSP表达式 一个JSP表达式中包含的脚本语言表达式,先被转化成String,然后插入到表达式出现的地方。 由于表达式的值会被转化成String,所以您可以在一个文本行中使用表达式而不用去管它是否是HTML标签。 表达式元素中可以包含任何符合Java语言规范的表达式,但是不能使用分号来结束表达式。 JSP表达式的语法格式: ~~~ <%= 表达式 %> ~~~ 同样,您也可以编写与之等价的XML语句: ~~~ <jsp:expression> 表达式 </jsp:expression> ~~~ 程序示例: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSP教程(cms.yiniuedu.com)</title> </head> <body> <p> 今天的日期是: <%= (new java.util.Date()).toLocaleString()%> </p> </body> </html> ~~~ 运行后得到以下结果: ~~~ 今天的日期是: 2016-6-25 13:40:07 ~~~ * * * ## JSP注释 JSP注释主要有两个作用:为代码作注释以及将某段代码注释掉。 JSP注释的语法格式: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSP教程(cms.yiniuedu.com)</title> </head> <body> <%-- 该部分注释在网页中不会被显示--%> <p> 今天的日期是: <%= (new java.util.Date()).toLocaleString()%> </p> </body> </html> ~~~ 运行后得到以下结果: ~~~ 今天的日期是: 2016-6-25 13:41:26 ~~~ 不同情况下使用注释的语法规则: | **语法** | 描述 | | --- | --- | | <%--注释--%> | JSP注释,注释内容不会被发送至浏览器甚至不会被编译 | | \<\!--注释--> | HTML注释,通过浏览器查看网页源代码时可以看见注释内容 | | <\% | 代表静态 <%常量 | | %\> | 代表静态 %> 常量 | | \' | 在属性中使用的单引号 | | \" | 在属性中使用的双引号 | * * * ## JSP指令 JSP指令用来设置与整个JSP页面相关的属性。 JSP指令语法格式: ~~~ <%@ directive attribute="value" %> ~~~ 这里有三种指令标签: | **指令** | **描述** | | --- | --- | | <% @ page ...| 定义网页依赖属性,比如脚本语言、error页面、缓存需求等等 | | <% @ include ...%> | 包含其他文件 | | <% @taglib ...%>| 引入标签库的定义 | * * * ## 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 | 用于封装模板数据 | * * * ## JSP隐含对象 JSP支持九个自动定义的变量,江湖人称隐含对象。这九个隐含对象的简介见下表: | **对象** | **描述** | | --- | --- | | request | **HttpServletRequest**类的实例 | | response | **HttpServletResponse**类的实例 | | out | **PrintWriter**类的实例,用于把结果输出至网页上 | | session | **HttpSession**类的实例 | | application | **ServletContext**类的实例,与应用上下文有关 | | config | **ServletConfig**类的实例 | | pageContext | **PageContext**类的实例,提供对JSP页面所有对象以及命名空间的访问 | | page | 类似于Java类中的this关键字 | | exception | **exception**类的对象,代表发生错误的 JSP 页面中对应的异常对象 | * * * ## 控制流语句 JSP提供对Java语言的全面支持。您可以在JSP程序中使用Java API甚至建立Java代码块,包括判断语句和循环语句等等。 ## 判断语句 **if…else**块,请看下面这个例子: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%! int day = 3; %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSP教程(cms.yiniuedu.com)</title> </head> <body> <h3>IF...ELSE 实例</h3> <% if (day == 1 || day == 7) { %> <p>今天是周末</p> <% } else { %> <p>今天不是周末</p> <% } %> </body> </html> ~~~ 运行后得到以下结果: ~~~ IF...ELSE 实例 今天不是周末 ~~~ 现在来看看switch…case块,与if…else块有很大的不同,它使用out.println(),并且整个都装在脚本程序的标签中,就像下面这样: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%! int day = 3; %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSP教程(cms.yiniuedu.com)</title> </head> <body> <h3>SWITCH...CASE 实例</h3> <% switch(day) { case 0: out.println("星期天"); break; case 1: out.println("星期一"); break; case 2: out.println("星期二"); break; case 3: out.println("星期三"); break; case 4: out.println("星期四"); break; case 5: out.println("星期五"); break; default: out.println("星期六"); } %> </body> </html> ~~~ 浏览器访问,运行后得出以下结果: ~~~ SWITCH...CASE 实例 星期三 ~~~ * * * ## 循环语句 在JSP程序中可以使用Java的三个基本循环类型:for,while,和 do…while。 让我们来看看for循环的例子,以下输出的不同字体大小的"菜鸟教程": ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%! int fontSize; %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSP教程(cms.yiniuedu.com)</title> </head> <body> <h3>For 循环实例</h3> <%for ( fontSize = 1; fontSize <= 3; fontSize++){ %> <font color="green" size="<%= fontSize %>"> JSP教程 </font><br /> <%}%> </body> </html> ~~~ 运行后得到以下结果: <h1>For循环示例</h1> <h5>JSP教程</h5> <h3>JSP教程</h3> <h2>JSP教程</h2> 将上例改用 while 循环来写: ~~~ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%! int fontSize=0; %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>JSP教程(cms.yiniuedu.com)</title> </head> <body> <h3>While 循环实例</h3> <%while ( fontSize <= 3){ %> <font color="green" size="<%= fontSize %>"> JSP教程 </font><br /> <%fontSize++;%> <%}%> </body> </html> ~~~ 浏览器访问,输出结果为(fontSize 初始化为0,所以多输出了一行): <h1>While循环示例</h1> <font color="green" size="1">JSP教程</font><br/> <font color="green" size="2">JSP教程</font><br/> <h3>JSP教程</h3> <h2>JSP教程</h2> JSP运算符 JSP支持所有Java逻辑和算术运算符。 下表罗列出了JSP常见运算符,优先级从高到底: | **类别** | **操作符** | **结合性** | | --- | --- | --- | | 后缀 | () \[\] . (点运算符) | 左到右 | | 一元 | ++ - - ! ~ | 右到左 | | 可乘性 | \* / %  | 左到右 | | 可加性 | \+ -  | 左到右 | | 移位 | \>> >>> <<   | 左到右  | | 关系 | \> >= < <=   | 左到右 | | 相等/不等 | \== !=  | 左到右 | | 位与 | &  | 左到右 | | 位异或 | ^  | 左到右 | | 位或 | |  | 左到右 | | 逻辑与 | &&  | 左到右 | | 逻辑或 | ||  | 左到右 | | 条件判断 | ?:  | 右到左 | | 赋值 | \= += -= \*= /= %= >>= <<= &= ^= |=  | 右到左 | | 逗号  | ,  | 左到右  | * * * ## JSP 字面量 JSP语言定义了以下几个字面量: * 布尔值(boolean):true 和 false; * 整型(int):与 Java 中的一样; * 浮点型(float):与 Java 中的一样; * 字符串(string):以单引号或双引号开始和结束; * Null:null。