JSP概述
什么是JSP
JSP(Java Server Page)是由sun 公司倡导、许多公司参与而建立的动态网页技术标准。它在HTML代码中嵌入Java代码片段(Scriptlet)和JSP标签,构成了JSP网页。在接收到用户请求时,服务器会处理Java代码片段,然后生成处理结果的HTML页面返回给客户端,客户端的浏览器将呈现最终效果。工作原理如下图:
此处显示客户端 网页效果 |
Web服务器 JSP/HTML |
HTTP请求 |
处理结果 |
Web客户端 |
服务器 |
JSP技术特征:
JSP所开发的Web应用程序是基于Java的,它拥有Java语言跨平台的特性,以及业务代码分离、组建重用、继承Java Servlet功能和预编译等特性。
1. 跨平台(一次编写,到处运行):JSP是基于Java语言的,那么它就可以只用Java API,所以它也是跨平台的,可以应用在不同的系统中。这同时也拓宽了JSP可以使用的Web服务器的范围。另外,应用于不同操作系统的数据库也可以为JSP服务,JSP使用JDBC技术操作数据库,从而避免了代码移植导致更换数据库时的代码修改问题。
2. 业务代码分离:采用JSP技术开发的项目,通常使用HTML语言来设计和格式化静态页面的内容,而使用JSP标签和Java代码片段来实现动态部分。程序开发人员可以将业务处理代码全部放到JavaBean中,或者把业务处理代码交给Servlet、Strust等其他业务控制层来处理,从而实现业务代码从视图层分离。这样JSP页面只负责显示数据即可,当需要修改业务代码时,不会影响JSP页面的代码。
3. 组件重用:JSP中可以使用JavaBean编写业务组件,也就是使用一个JavaBean类封装业务处理代码或者作为一个数据存储模型,在JSP页面甚至整个项目中都可以重复使用这个JavaBean。
4. 继承JavaServlet功能:Servlet是JSP出现之前主要的Java Web处理技术。它接受用户请求,在Servlet类中编写所有Java和HTML代码,然后通过输出流把结果页面返回给浏览器。其缺点是:在类中编写HTML代码非常不便,也不利于阅读。使用JSP技术之后,开发Web应用便变得相对简单快捷多了,并且JSP最终要编译成Servlet才能处理用户请求,因此我们说JSP拥有Servlet的所有功能和特性。
5. 预编译:就是在用户第一次通过浏览器访问JSP页面时,服务器将对JSP页面代码进行编译,并且仅执行一次编译。编译好的代码将被保存,在用户下一次访问时,直接执行编译好的代码。这样不仅节约了服务器的CPU资源,还大大提升了客户端的访问速度。
Web服务器
Web服务器是运行及发布Web应用的容器,只有将开发的Web项目放置到该容器中,才能使网络中的所有用户通过浏览器进行访问。开发Java Web所采用的服务器主要是与JSP/Servlet兼容的Web服务器,比较常用的有:Tomcat、Resin、JBoss、WebSphere、和WebLogic等。
目前最为流行的Tomcat服务器是Apache-Jarkarta开源项目中的一个子项目,是一个小型、轻量级的支持JSP和Servlet技术的Web服务器。
JSP的基本构成
JSP页面主要由指令标签、HTML标记语言、注释、嵌入Java代码、JSP动作标签等5个元素组成。
指令标签
指令标签不会产生任何内容输出到网页中,主要用于定义整个JSP页面的相关信息。例如使用的语言、导入的类包、指定错误处理页面等。语法格式如下:
<%@ directive attribute =”value” attributeN=”valueN” …%>
JSP指令有三种,分别是page、include和taglib.
- 1. page指令
语法格式如下:
<%@ page attr1=”value1” attr2=”value2” …%>
page指令包含的属性有15个,一下是比较常见的:
language 属性:设置JSP页面使用的语言,目前只支持java语言,该属性默认值是java.例如:
<%@ page language=”java”%>
Import属性:设置jsp导入的类包。JSP页面可以嵌入java代码片段,这些java代码在调用API时需要导入相应的类包。例如:
<%@ page import=”java.util.*”%>
pageEncoding属性:定义JSP页面编码格式。例如:
<%@ page pageEncoding=”utf-8”%>
contentType属性:设置JSP页面的MIME类型和字符编码,浏览器会据此显示网页内容。例如:
<%@ page contentType=”text/html;charset=utf-8”%>
session属性:指定JSP页面是否使用HTTP的session会话对象。其属性值是boolean类型,默认为true.例如:
<%@ page session=”false”%>
buffer属性:设置JSP的out输出对象使用的缓冲区大小,默认是8KB,且单位只能使用KB。建议使用8的倍数作为该属性值。例如:
<%@ page buffer=”128KB”%>
autoFlush属性:该属性用于设置JSP页面缓存满的时候,是否自动刷新缓存。默认为true,如果为false,则缓存被填满时将被抛出异常。例如:
<%@ page autoFlush=”false”%>
Info属性:设置JSP页面的相关信息,该信息可以在Servlet接口的getServletInfo()方法中获取。例如:
<%@ page info=”这是一个登陆页面时系统的入口”%>
isErrorPage属性:通过该属性可以将当前JSP页面设置成错误处理页面来处理另一个JSP页面的错误,也就是异常处理。这意味着当前JSP页面业务的改变。例如:
<%@ page isErrorPage=”true”%>
errorPage属性:该属性用于指定处理当前JSP页面异常错误的另一个JSP页面指定的JSP错误处理页面必须设置isErrorPage属性为true。errorPage属性值是一个URL字符串。例如:
<%@ page errorPage=”error/loginErrorPage.jsp”%>
注:如果设置该属性,那么在web.xml文件中定义的任何错误页面都将被忽略,而优先使用该属性定义的错误处理页面。
isELIgnored属性:设置定义JSP页面是否忽略EL表达式的使用。默认为false,例如:
<%@ page isELIgnored=”false”%>
2.include指令:用于指定文件包含。仅支持静态包含,也就是说被包含文件中的所有内容都被原样包含到该JSP页面中,如果被包含文件中有代码将不被执行。被包含文件可以是一段java代码、HTML代码或另一个JSP页面。例如:
3.taglib指令:用于加载用户自定义标签,语法格式如下:
<%@taglib prefix=”fix” uri=”tagUriorDir”%>
Prefix属性:设置加载自定义标签的前缀。
嵌入java代码
在JSP页面中可以嵌入java的代码片段来完成业务处理。
代码片段:就是在JSP页面中嵌入的java代码,也有称为脚本段或脚本代码的。代码片段将在页面请求的处理期间被执行,可以通过JSP内置对象在页面输出内容、访问session会话、编写流程控制语句等。其语法格式如下:
<% 编写java代码%>
声明:声明脚本用于在JSP页面中定义全局的成员变量或方法,服务器将JSP转换为Servlet类时会把使用JSP声明脚本定义的变量和方法定义为类的成员。其语法格式如下:
<%! 声明%>
例如:
<%!
Int getMax(int a, int b){
Int max=a>b?a:b;
return max;
}
%>
JSP表达式:可以直接把java的表达式结果输出到JSP页面中,并都转换为字符串类型。其语法格式如下:
<%=表达式%>
例如:
圆周率是:<%=Math.PI %>
注释
HTML注释:查看源代码时可以看到注释信息。
语法:
<!--注释文本-->
JSP注释:浏览器查看源代码不会暴露注释信息,因为JSP注释是被服务器编译执行的,不会发送到客户端。
语法:
<%-- 注释文本 --%>
动态注释:由于HTML注释对JSP嵌入的代码不起作用,因此可以利用他们的组合构成动态的HTML注释文本。例如:
<!--<%=new Data()%>-->
上述代码将当前日期和时间作为HTML注释文本。
代码注释:例如:
<%//单行注释%>
<%/*
多行注释
*/
%>
<%/**javaDoc注释,用于成员注释*/%>
JSP动作标签
动作标签是在请求处理阶段按照在页面中出现的顺序被执行的。其优先级低于指令标签。
动作标签遵循XML语法,包括开始和结束标签,通用语法格式如下:
<标签名 属性1=”值1” 属性2=”值2” …/>
或者
<标签名 属性1=”值1” 属性2=”值2” …>
标签内容
</标签名>
<jsp:include>:该动作标签可将另外一个文件的内容包含到当前JSP页面中。被包含内容可以是静态文本,也可以是动态代码。语法格式如下:
<jsp:include page="url" flush="false/true"/>
或者
<jsp:include page="url" flush="false/true">
子标签
</jsp:include>
注意:被包含的JSP页面中不要使用<html>和<body>标签,被包含进其他JSP页面会破坏页面格式。另外,源文件和被包含文件中的变量和方法的名称不要冲突,因为它们最终会生成一个文件,重名会导致错误发生。
<jsp:include>与include指令的的区别:
1.相对路径:include指令使用file属性指定被包含的文件,该属性值使用文件的相对路径指定被包含文件的位置,而<jsp:include>标签以页面的相对路径来指定被包含的资源。
2.包含资源:include指令包含的资源为静态,例如HTML、TXT等;如果将JSP的动态内容用include指令包含的话也会被当做静态资源包含到当前页面;被包含资源与当前JSP页面是一个整体,资源和相对路径的解析在JSP页面转换为Servlet时发生。
<jsp:include>标签包含JSP动态资源时,资源相对路径的解析在请求处理时发生。当前页面和被包含的资源是两个独立的实体,被包含的页面会对包含它的JSP页面中的请求对象进行处理,然后将处理结果作为当前JSP页面的包含内容,与当前页面内容一起发送到客户端。
值得注意的是:JSP在运行前是要被web容器转译成Servlet的,所以为了更好的区分JSP Scriptlet和JSP声明,可以这样认为:JSP Scriptlet就是Servlet里面的service方法里面的内容,JSP声明就是service方法外面的内容,即其他的方法,或者成员变量。
JSP内置对象
request对象
request对象是javax.servlet.http.HttpServletRequest类型的对象。该对象代表了客户端的请求信息,主要用于接收通过HTTP协议传送到服务器端的数据(包括头信息、系统信息、请求方式以及请求参数等)。Request对象的作用域为一次请求。
获取请求参数值:在一个请求中,可以通过?的方式来传递参数,然后通过request对象的getParameter()方法来获取参数的值。例如:
String id=request.getParameter(“id”);
上面的代码使用getParemeter()方法从request对象中获取id的值,如果request对象中不存在此参数,该方法将返回null.
举例:
首先在web项目中创建index.jsp页面,关键代码如下:
<body>
<a href=”show.jsp?id=001”>获取请求参数的值</a>
</body>
新建show.jsp页面,关键代码如下:
<body>
id参数的值为:<%=request.getParameter(“id”)%><br>
name参数的值为:<%=request.getParameter(“name”)%>
</body>
由于请求中只传递了id参数,所以结果如下:
id参数的值为:001
name参数的值为:null
解决中文乱码:
显示参数时中文变成了乱码。这是因为请求参数的文字编码方式与页面中的不一致所造成的,所有的request请求都是iso-8859-1的。只要将获取到的数据通过String的构造方法使用指定的编码类型重新构造一个String对象即可正确的显示出中文信息。
举例:
创建index.jsp页面,加入一个超链接并传递两个参数name和sex,值都为中文,关键代码如下:
<body>
<a href=”show.jsp?name=张三&sex=男”>解决中文乱码</a>
</body>
创建show.jsp页面,仅将第一个参数进行编码转换,比较结果。关键代码如下:
<body>
name参数的值为:<%=new String(request.getParameter(“name”).getBytes(“iso-8859-1”),”gbk”)%>
sex参数的值为:<%=request.getParameter(“sex”)%>
</body>
运行后name参数能正常显示,sex为乱码,结果如下:
name参数的值为:张三
sex参数的值为:??
获取form表单信息
一个表单终会有不同的标签元素,对于文本元素、单选按钮、下拉列表框、都可以使用getParameter()方法来获取其具体的值,但对于复选框、多选列表框被选定的内容就要使用getParameterValues()方法来获取了,该方法会返回一个字符串数组,通过循环遍历这个数组就可以得到用户选定的所有内容。
获取请求客户端信息:
方法 |
返回值 |
说明 |
getHeader(String name) |
String |
返回指定名称的HTTP头信息 |
getMethod() |
String |
获取客户端向服务器发送请求的方法 |
getContextPath() |
String |
返回请求路径 |
getProtocol() |
String |
返回请求使用的协议 |
getRemoteAddr() |
String |
返回客户端IP地址 |
getRemoteHost() |
String |
返回客户端主机名称 |
getRemotePort() |
int |
返回客户端发出请求的端口号 |
getServletPath() |
String |
返回接受客户提交信息的页面 |
getRequestURI() |
String |
返回部分客户端请求的地址,不包括请求的参数 |
getRequestURL() |
StringBuffer |
返回客户端请求地址 |
在作用域中管理属性:
使用setAttribute()方法可以在request对象的属性列表中添加一个属性,然后在request对象的作用域范围内通过使用getAttribute()方法将其属性取出;此外,还可使用removeAttribute()方法将一个属性删除掉。
cookie管理:
cookie是小段的文本信息,通过使用cookie可以标识用户身份、记录用户名及密码、跟踪重复用户。Cookie在服务器端生成并发送给浏览器,浏览器将cookie的key/value保存到某个指定的目录中,服务器的名称与值可以由服务器端定义。通过cookie的getCookies()方法可以获取到所有的cookie对象集合,然后通过cookie对象的getName()方法获取到指定名称的cookie,再通过getValue()方法即可获取到cookie对象的值。另外,将一个cookie对象发送到客户端使用了response对象的addCookie()方法。