JSP入门
基本概述
JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它是由Sun公司倡导、许多公司参与一起建立的一种动态网页技术标准。JSP技术有点类似ASP技术,它是在传统的网页HTML(标准通用标记语言的子集)文件(*.htm,*.html)中插入Java程序段(Scriptlet)和JSP标记(tag),从而形成JSP文件,后缀名为(*.jsp)。 用JSP开发的Web应用是跨平台的,既能在Linux下运行,也能在其他操作系统上运行。
它实现了Html语法中的java扩展(以 <%, %>形式)。JSP与Servlet一样,是在服务器端执行的。通常返回给客户端的就是一个HTML文本,因此客户端只要有浏览器就能浏览。
JSP技术使用Java编程语言编写类XML的tags和scriptlets,来封装产生动态网页的处理逻辑。网页还能通过tags和scriptlets访问存在于服务端的资源的应用逻辑。JSP将网页逻辑与网页设计的显示分离,支持可重用的基于组件的设计,使基于Web的应用程序的开发变得迅速和容易。 JSP(Java Server Pages)是一种动态页面技术,它的主要目的是将表示逻辑从Servlet中分离出来。
Java Servlet是JSP的技术基础,而且大型的Web应用程序的开发需要Java Servlet和JSP配合才能完成。JSP具备了Java技术的简单易用,完全的面向对象,具有平台无关性且安全可靠,主要面向因特网的所有特点。
JSP技术所开发的Web应用程序是基于Java的,它可以用一种简捷而快速的方法从Java程序生成Web页面,其使用上具有如下几点特征:
l 跨平台:由于JSP是基于Java语言的,它可以使用Java API,所以它也是跨平台的,可以应用于不同的系统中,如Windows、Linux等。当从一个平台移植到另一个平台时,JSP和JavaBean的代码并不需要重新编译,这是因为Java的字节码是与平台无关的,这也应验了Java语言“一次编译,到处运行”的特点。
l 业务代码相分离:在使用JSP技术开发Web应用时,可以将界面的开发与应用程序的开发分离开。开发人员使用HTML来设计界面,使用JSP标签和脚本来动态生成页面上的内容。在服务器端,JSP引擎(或容器)负责解析JSP标签和脚本程序,生成所请求的内容,并将执行结果以HTML页面的形式返回到浏览器。
l 组件重用:JSP中可以使用JavaBean编写业务组件,也就是使用一个JavaBean类封装业务处理代码或者作为一个数据存储模型,在JSP页面中,甚至在整个项目中,都可以重复使用这个JavaBean,同时,JavaBean也可以应用到其他Java应用程序中。
l 预编译:预编译就是在用户第一次通过浏览器访问JSP页面时,服务器将对JSP页面代码进行编译,并且仅执行一次编译。编译好的代码将被保存,在用户下一次访问时,会直接执行编译好的代码。这样不仅节约了服务器的CPU资源,还大大的提升了客户端的访问速度。
PS:其实就是JSP是用来处理界面,Servlet用来处理业务逻辑,Java用来处理数据访问,这样来实现MVC分层,至于具体实现可以参考我的另一篇博客《Web MVC模式实现》。
参考文档:http://tomcat.apache.org/tomcat-7.0-doc/jspapi/index.html?index-all.html
参考文档:http://www.runoob.com/jsp/jsp-tutorial.html
运行原理图
JSP的运行过程具体如下:
(1)客户端发出请求,请求访问JSP文件。
(2)JSP容器先将JSP文件转换成一个Java源文件(Java Servlet源程序),在转换过程中,如果发现JSP文件中存在任何语法错误,则中断转换过程,并向服务端和客户端返回出错信息。
(3)如果转换成功,则JSP容器将生成的Java源文件编译成相应的字节码文件*.class。该class文件就是一个Servlet,Servlet容器会像处理其他Servlet一样来处理它,所以第二次访问,直接使用生成的字节码文件。
PS:JSP运行之后会在Tomcat服务器主目录下的work目录中生成相应的.java和.class文件
其格式为tomcat主目录名\work\Catalina\主机名\应用名\org\apache\jsp\文件名
注意:.java文件和.class文件是在一起的
JSP页面如何被翻译成Servlet
html->servlet
<body>
This is my JSP page. <br>
</body>
out.write(" <body>\r\n");
out.write(" This is my JSP page. <br>\r\n");
out.write(" </body>\r\n");
jsp标签内代码->servlet
<%
int i=90;
int j=i+90;
%>
<%
out.println("j="+j);
%>
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
// 隐式对象创建
int i=90;
int j=i+90;
// 代码块
// out.write(“j=” + j + “\r\n”);
// 代码块
}
jsp指令
为了设置JSP页面中的一些信息,Sun公司提供了JSP指令。 JSP 2.0中共定义了page、include和taglib三种指令,每种指令都定义了各自的属性。接下来,本节将针对page和include指令进行详细的讲解。
在JSP页面中,经常需要对页面的某些特性进行描述,例如,页面的编码方式,JSP页面采用的语言等,这时,可以通过page指令来实现。page指令的具体语法格式如下所示:
<%@ page 属性名1= "属性值1" 属性名2= "属性值2" ...%>
在上面的语法格式中,page用于声明指令名称,属性用来指定JSP页面的某些特性。page指令提供了一系列与JSP页面相关的属性,如表所示。
属性名称 | 取值or范围 | 描述 |
pageEncoding | 当前页面 | 指定页面编码格式 |
contentType | 有效的文档类型 | 客户端浏览器根据该属性判断文档类型,例如: HTML格式为text/html 纯文本格式为text/plain JPG图像为image/jpeg GIF图像为image/gif Word文档为application/msword |
|
|
|
buffer | 8kb | jsp缓存大小 |
autoFlush | true / false | 是否自动刷新 |
|
|
|
errorPage | 某个JSP页面的相对路径 | 指定一个错误页面,如果该JSP程序抛出一个未捕捉的异常,则转到errorPage指定的页面。errorPage指定页面的isErrorPage属性为true,且内置的exception对象为未捕捉的异常 |
isErrorPage | true / false | 指定该页面是否为错误处理页面,如果为true,则该JSP内置有一个Exception对象的exception,可直接使用。默认情况下,isErrorPage的值为false |
|
|
|
import | 任何包名、类名 | 指定在JSP页面翻译成的Servlet源文件中导入的包或类。import是唯一可以声明多次的page指令属性。一个import属性可以引用多个类,中间用英文逗号隔开。 |
language | java | 指明解释该JSP文件时采用的语言,默认为Java |
session | true、false | 指明该JSP内是否内置Session对象,如果为true,则说明内置Session对象,可以直接使用,否则没有内置Session对象。默认情况下,session属性的值为true。需要注意的是,JSP 引擎自动导入以下4个包: java.lang.* javax.servlet.* javax.servlet.jsp.* javax.servlet.http.* |
表1-1中列举了page指令的常见属性,其中,除了import属性外,其他的属性都只能出现一次,否则会编译失败。需要注意的是,page指令的属性名称都是区分大小写的。
下面列举两个使用page指令的示例:
<%@ page language="java" contentType="text/html;charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.awt.*" %>
<%@ page import="java.util.*","java.awt.*"%>
上面代码中使用了page指令的language、contentType、pageEncoding和import属性。
需要注意的是,page指令对整个页面都有效,而与其书写的位置无关,但是习惯上把page指令写在JSP页面的最前面。
pageEncoding指定当前JSP页面的编码!这个编码是给服务器看的,服务器需要知道当前JSP使用的编码,不然服务器无法正确把JSP编译成java文件。所以这个编码只需要与真实的页面编码一致即可!
contentType属性与response.setContentType()方法的作用相同!它会完成两项工作,一是设置响应字符流的编码,二是设置content-type响应头。例如:<%@contentType=”text/html;charset=utf-8”%>,它会使“真身”中出现response.setContentType(“text/html;charset=utf-8”)。
无论是page指令的pageEncoding还是contentType,它们的默认值都是ISO-8859-1,我们知道ISO-8859-1是无法显示中文的,所以JSP页面中存在中文的话,一定要设置这两个属性。
其实pageEncoding和contentType这两个属性的关系很“暧昧”:
当设置了pageEncoding,而没设置contentType时: contentType的默认值为pageEncoding;
当设置了contentType,而没设置pageEncoding时: pageEncoding的默认值为contentType;
也就是说,当pageEncoding和contentType只出现一个时,那么另一个的值与出现的值相同。如果两个都不出现,那么两个属性的值都是ISO-8859-1。所以通过我们至少设置它们两个其中一个!
include指令
在实际开发时,有时需要在JSP页面静态包含一个文件,例如HTML文件,文本文件等,这时,可以通过include指令来实现,include指令的具体语法格式如下所示:
<%@ include file="被包含的文件地址"%>
include指令只有一个file属性,该属性用来指定插入到JSP页面目标位置的文件资源。
关于include指令的具体应用,有很多问题需要注意,接下来,将这些问题进行列举,具体如下:
(1) 被引入的文件必须遵循JSP语法,其中的内容可以包含静态HTML、JSP脚本元素和JSP指令等普通JSP页面所具有的一切内容。
(2) 除了指令元素之外,被引入的文件中的其他元素都被转换成相应的Java源代码,然后插入进当前JSP页面所翻译成的Servlet源文件中,插入位置与include指令在当前JSP页面中的位置保持一致。
PS:路径是相对路径,通过该方式引入的JSP文件不能包含唯一HTML标签,比如<head><body>等,并且该方式并不会将引入的JSP文件翻译成Servlet然后编译,也就是说只会产生一个servlet文件,因此这种引入方式也叫作静态引入。
taglib指令
用于页面中引入标签库的,这个指令会在后面介绍JSTL的时候讲解.
在JSP页面中使用第三方的标签库时,需要使用taglib指令来“导包”。例如:
<%@ taglib prefix="c"uri="http://java.sun.com/jsp/jstl/core" %>
其中prefix表示标签的前缀,这个名称可以随便起。uri是由第三方标签库定义的,所以你需要知道第三方定义的uri。
参考博客:http://www.biaodianfu.com/jsp-taglib.html
脚本元素
JSP脚本元素是指嵌套在<%和%>之中的一条或多条Java程序代码。通过JSP脚本元素可以将Java代码嵌入HTML页面中,所有可执行的Java代码,都可以通过JSP脚本来执行。(不建议在jsp页面中嵌入java代码)
JSP脚本元素主要包含如下三种类型:
l JSPScriptlets <%...%>在这个里面书写内容等同于在方法中书写代码
Java语句;方法中能放什么,它就能放什么。如果在这个元素里面定义了一个变量,那么此时他就是一个局部变量!
l JSP声明语句 <%!...%> 在这个里面书写内容等同于在类中书写代码
Java定义类成员;没人会用它!有人会考它!定义类的成员!类能包含什么,它就可以包含什么。声明中没有9大内置对象!
l JSP表达式 <%=…%> 里面的代码会被输出!
Java表达式;等同与resopnse.getWriter().print()。写到这里的东西,都是用来输出的!
1. JSP Scriptlets
JSPScriptlets 是一段代码段。当需要使用Java实现一些复杂操作或控制时,可以使用它。JSP Scriptlets的语法格式如下所示:
<%java 代码(变量、方法、语句等)%>
在JSP Scriptlets中声明的变量是JSP页面的局部变量,调用JSP Scriptlets时,会为局部变量分配内存空间,调用结束后,释放局部变量占有的内存空间。
2. JSP 声明语句
JSP的声明语句用于声明变量和方法,它以“<%!”开始,以“%>”结束,其语法格式如下所示:
<%!
定义的变量或方法等
%>
在上述语法格式中,被声明的Java代码将 被编译到 Servlet 的 _jspService() 方法之外,即 在 JSP 声明语句中定义的都是成员方法、成员变量、静态方法、静态变量、静态代码块等。 在 JSP 声明语句中声明的方法在整个 JSP 页面内有效。
在一个JSP页面中可以有多个JSP声明语句,单个声明中的Java语句可以是不完整的,但是多个声明组合后的结果必须是完整的Java语句。
3. JSP表达式
JSP表达式(expression)用于将程序数据输出到客户端,它将要输出的变量或者表达式直接封装在以“<%=” 开头和以“%>”结尾的标记中,其基本的语法格式如下所示:
<%=expression %>
在上述语法格式中,JSP表达式中的将“expression”表达式结果输出到浏览器。
l “<%=”和“%>”标记之间插入的是表达式,不能插入语句。
l “<%=”是一个完整的符号,“<%”和“=”之间不能有空格。
l JSP表达式中的变量或表达式后面不能有分号(;)。
动作元素
该文档写的非常详细:http://www.runoob.com/jsp/jsp-actions.html
PS:
<%@include file=”文件路径”> 静态引入
<jsp:include page=”文件路径”></jsp:include> 动态引入
两者的区别是前者把两个jsp翻译成一个Servlet,所以被引入的文件不能包含<html><body>之类的唯一HTML标记,后者是将两个jsp分别翻译,然后将一个页面的结果引入到另一个页面,所以被引入的jsp包含有<html><body>也可以。
<jsp:forward page=”文件路径”>也是常用的动作元素,用于把请求转发到另外的页面。
JSP注释
JSP注释有两种方式,一种是<%-- 要注释的内容 --%>,另一种是<!-- 要注释的内容 -->
PS:前者是不会在HTML源码中看到并且不会被编译,叫做JSP注释,后者能在HTML源码中看到,但是不会显示在HTML页面中,叫做HTML注释。建议统一用JSP注释,这样既节省内存也安全。
JSP注释、Java注释、HTML注释对比:
<%-- jsp注释--%>
<% //java注释 %>
<!-- html注释-->
| jsp源码 | java源码 | html源码 |
jsp注释 | 有 | 无 | 无 |
java注释 | 有 | 有 | 无 |
html注释 | 有 | 有 | 有 |
JSP内置对象
JSP隐式对象是JSP容器为每个页面提供的Java对象,开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。JSP一共支持九大隐式对象。
对象名 | 类型 | 作用域 | 描述 |
request请求对象 | javax.servlet.ServletRequest | Request | 得到用户请求信息 |
response响应对象 | javax.servlet.ServletResponse | Page | 服务器向客户端的回应信息 |
pageContext页面上下文对象 | javax.servlet.jsp.PageContext | Page | JSP的页面容器 |
session会话对象 | javax.servlet.http.HttpSession | Session | 用来保存用户的信息 |
out输出对象 | javax.servlet.jsp.JspWriter | Page | 用于页面输出 |
config配置对象 | javax.servlet.ServletConfig | Page | 服务器配置,可以取得初始化参数 |
page页面对象 | java.lang.Object 相当于this | Page | 指当前页面转换后的Servlet类的实例 |
exception异常对象 | java.lang.Throwable | Page | 表示JSP页面所发生的异常,在错误页中才起作用 |
application应用程序对象 | javax.servlet.ServletContext | Application | 所有用户的共享信息 |
out对象
在JSP页面中,经常需要向客户端发送文本内容,这时,可以使用out对象来实现。out对象是javax.servlet.jsp.JspWriter类的实例对象,它的作用与ServletResponse.getWriter()方法返回的PrintWriter对象非常相似,都是用来向客户端发送文本形式的实体内容。不同的是,out对象的类型为JspWriter,它相当于一种带缓存功能的PrintWriter。接下来,通过一张图来描述JSP页面的out对象与Servlet引擎提供的缓冲区之间的工作关系,具体如图所示。
out对象通过print语句写入数据后,直到整个JSP页面结束,out对象中输入缓冲区的数据才真正写入到Serlvet引擎提供的缓冲区中,而response.getWriter().println语句则是直接把内容写入Servlet引擎提供的缓冲区中,Servlet引擎按照缓冲区中的数据存放顺序输出内容。
pageContext对象
在JSP页面中,使用pageContext对象可以获取JSP的其他8个隐式对象。pageContext对象是javax.servlet.jsp.PageContext类的实例对象,它代表当前JSP页面的运行环境,并提供了一系列用于获取其他隐式对象的方法。pageContext对象获取隐式对象的方法如表所示。
方法名 | 功能描述 |
JspWriter getOut() | 用于获取out隐式对象 |
Object getPage() | 用于获取page隐式对象 |
ServletRequest getRequest() | 用于获取request隐式对象 |
ServletResponse getResponse() | 用于获取response隐式对象 |
HttpSession getSession() | 用于获取session隐式对象 |
Exception getException() | 用于获取exception隐式对象 |
ServletConfig getServletConfig() | 用于获取config隐式对象 |
ServletContext getServletContext() | 用于获取application隐式对象 |
表中列举了pageContext获取其他隐式对象的方法,这样,当传递一个pageContext对象后,就可以通过这些方法轻松地获取到其他8个隐式对象了。
pageContext对象不仅提供了获取隐式对象的方法,还提供了存储数据的功能。pageContext对象存储数据是通过操作属性来实现的,表中列举了pageContext操作属性的一系列方法,具体如下:
方法名称 | 功能描述 |
void setAttribute(String name,Object value,int scope) | 用于设置pageContext对象的属性 |
Object getAttribute(String name,int scope) | 用于获取pageContext对象的属性 |
void removeAttribute(String name,int scope) | 删除指定范围内名称为name的属性 |
void removeAttribute(String name) | 删除所有范围内名称为name的属性 |
Object findAttribute(String name) | 从4个域对象中查找名称为name的属性 |
表中列举了pageContext对象操作属性的相关方法,其中,参数name指定的是属性名称,参数scope指定的是属性的作用范围。pageContext对象的作用范围有4个值,具体如下:
PageContext.PAGE_SCOPE:表示页面范围
PageContext.REQUEST_SCOPE:表示请求范围
PageContext.SESSION_SCOPE:表示会话范围
PageContext.APPLICATION_SCOPE:表示Web应用程序范围
需要注意的是,当使用findAttribute()方法查找名称为name的属性时,会按照page、request、session和application的顺序依次进行查找,如果找到,则返回属性的名称,否则返回null。
JSP的四个域范围
PageContext常量名 | 描述 | 作用域名称 | 域对象类型 |
PageScope | 当前页面中有效 | pageContext | PageContext |
RequestScope | 一次请求范围 | request | HttpServletRequest |
SessionScope | 一次会话范围 | session | HttpSession |
ApplicationScope | 应用范围 | application | ServletContext |
page:表示当前页,通常没用。jsp标签底层使用。
request:表示一次请求。通常一次请求就一个页面,但如果使用请求转发,可以涉及多个页面。
session:表示一次会话。可以在多次请求之间共享数据。
application:表示一个web应用(项目)。可以整个web项目共享,多次会话共享数据。
小结
1、jsp运行在服务器
2、jsp(java server page)
3、jsp的基础是servlet(相当于对servlet进行一个包装)
4、jsp是综合技术 jsp=html+css+javascript+java代码+jsp标签(servlet)
5、jsp无需配置.直接使用,如果修改了jsp文件,不需要重新reload web应用.
6、jsp如何方法 http://ip:8080/web应用名/jsp路径
7、jsp是一种动态网页技术
8、为了防止直接访问JSP文件,可以将JSP文件放入WEB-INF目录下,然后通过<jsp:forward>从WebRoot目录下跳转当访问文件。
PS:上述只是JSP语法和使用的一部分知识,其他内容可以参考API文档和教程,已在基本概述中给出。
----------参考《韩顺平.细说JSP》