JSP高级功能-java之JSP学习第三天
文章大纲
一、jsp 标准标签库(jstl)
二、jsp 连接数据库
三、jsp xml 数据处理
四、jsp javabean
五、jsp 自定义标签
六、jsp 表达式语言
七、jsp 异常处理
八、jsp 调试
九、jsp 国际化
十、学习资料下载
十一、参考文章
一、jsp 标准标签库(jstl)
jsp标准标签库(jstl)是一个jsp标签集合,它封装了jsp应用的通用核心功能。
jstl支持通用的、结构化的任务,比如迭代,条件判断,xml文档操作,国际化标签,sql标签。 除了这些,它还提供了一个框架来使用集成jstl的自定义标签。
根据jstl标签所提供的功能,可以将其分为5个类别。
核心标签
格式化标签
sql 标签
xml 标签
jstl 函数
1. jstl 库安装
apache tomcat安装jstl 库步骤如下:
从apache的标准标签库中下载的二进包(jakarta-taglibs-standard-current.zip)。
官方下载地址:http://archive.apache.org/dist/jakarta/taglibs/standard/binaries/
本站下载地址:jakarta-taglibs-standard-1.1.2.zip
下载jakarta-taglibs-standard-1.1.2.zip 包并解压,将jakarta-taglibs-standard-1.1.2/lib/下的两个jar文件:standard.jar和jstl.jar文件拷贝到/web-inf/lib/下。
接下来我们在 web.xml 文件中添加以下配置:
<?xml version="1.0" encoding="utf-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <jsp-config> <taglib> <taglib-uri>http://java.sun.com/jstl/fmt</taglib-uri> <taglib-location>/web-inf/fmt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jstl/fmt-rt</taglib-uri> <taglib-location>/web-inf/fmt-rt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jstl/core</taglib-uri> <taglib-location>/web-inf/c.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jstl/core-rt</taglib-uri> <taglib-location>/web-inf/c-rt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jstl/sql</taglib-uri> <taglib-location>/web-inf/sql.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jstl/sql-rt</taglib-uri> <taglib-location>/web-inf/sql-rt.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jstl/x</taglib-uri> <taglib-location>/web-inf/x.tld</taglib-location> </taglib> <taglib> <taglib-uri>http://java.sun.com/jstl/x-rt</taglib-uri> <taglib-location>/web-inf/x-rt.tld</taglib-location> </taglib> </jsp-config> </web-app> 使用任何库,你必须在每个jsp文件中的头部包含<taglib>标签。
2. 核心标签
jstl格式化标签用来格式化并输出文本、日期、时间、数字。引用格式化标签库的语法如下:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
3. sql标签
jstl sql标签库提供了与关系型数据库(oracle,mysql,sql server等等)进行交互的标签。引用sql标签库的语法如下:
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
3. xml 标签
jstl xml标签库提供了创建和操作xml文档的标签。引用xml标签库的语法如下:
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
在使用xml标签前,你必须将xml 和 xpath 的相关包拷贝至你的<tomcat 安装目录>\lib下:
xercesimpl.jar
下载地址: http://www.apache.org/dist/xerces/j/
xalan.jar
下载地址: http://xml.apache.org/xalan-j/index.html
4. jstl函数
jstl包含一系列标准函数,大部分是通用的字符串处理函数。引用jstl函数库的语法如下:
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
二、jsp 连接数据库
1. 创建测试数据
接下来我们在 mysql 中创建 runoob 数据库,并创建 websites 数据表,表结构如下:
create table `websites` ( `id` int(11) not null auto_increment, `name` char(20) not null default '' comment '站点名称', `url` varchar(255) not null default '', `alexa` int(11) not null default '0' comment 'alexa 排名', `country` char(10) not null default '' comment '国家', primary key (`id`) ) engine=innodb auto_increment=10 default charset=utf8;
插入一些数据:
insert into `websites` values ('1', 'google', 'https://www.google.cm/', '1', 'usa'), ('2', '淘宝', 'https://www.taobao.com/', '13', 'cn'), ('3', '菜鸟教程', 'http://www.runoob.com', '5892', ''), ('4', '微博', 'http://weibo.com/', '20', 'cn'), ('5', 'facebook', 'https://www.facebook.com/', '3', 'usa');
数据表显示如下:
2. select操作
接下来的这个例子告诉我们如何使用jstl sql标签来运行sql select语句:
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <%@ page import="java.io.*,java.util.*,java.sql.*"%> <%@ page import="javax.servlet.http.*,javax.servlet.*" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%> <html> <head> <title>select 操作</title> </head> <body> <!-- jdbc 驱动名及数据库 url 数据库的用户名与密码,需要根据自己的设置 useunicode=true&characterencoding=utf-8 防止中文乱码 --> <sql:setdatasource var="snapshot" driver="com.mysql.jdbc.driver" url="jdbc:mysql://localhost:3306/runoob?useunicode=true&characterencoding=utf-8" user="root" password="123456"/> <sql:query datasource="${snapshot}" var="result"> select * from websites; </sql:query> <h1>jsp 数据库实例 - 菜鸟教程</h1> <table border="1" width="100%"> <tr> <th>id</th> <th>站点名</th> <th>站点地址</th> </tr> <c:foreach var="row" items="${result.rows}"> <tr> <td><c:out value="${row.id}"/></td> <td><c:out value="${row.name}"/></td> <td><c:out value="${row.url}"/></td> </tr> </c:foreach> </table> </body> </html>
访问这个jsp例子,运行结果如下:
3. insert操作
这个例子告诉我们如何使用jstl sql标签来运行sql insert语句:
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <%@ page import="java.io.*,java.util.*,java.sql.*"%> <%@ page import="javax.servlet.http.*,javax.servlet.*" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%> <html> <head> <title>select 操作</title> </head> <body> <!-- jdbc 驱动名及数据库 url 数据库的用户名与密码,需要根据自己的设置 useunicode=true&characterencoding=utf-8 防止中文乱码 --> <sql:setdatasource var="snapshot" driver="com.mysql.jdbc.driver" url="jdbc:mysql://localhost:3306/runoob?useunicode=true&characterencoding=utf-8" user="root" password="123456"/> <!-- 插入数据 --> <sql:update datasource="${snapshot}" var="result"> insert into websites (name,url,alexa,country) values ('菜鸟教程移动站', 'http://m.runoob.com', 5093, 'cn'); </sql:update> <sql:query datasource="${snapshot}" var="result"> select * from websites; </sql:query> <h1>jsp 数据库实例 - 菜鸟教程</h1> <table border="1" width="100%"> <tr> <th>id</th> <th>站点名</th> <th>站点地址</th> </tr> <c:foreach var="row" items="${result.rows}"> <tr> <td><c:out value="${row.id}"/></td> <td><c:out value="${row.name}"/></td> <td><c:out value="${row.url}"/></td> </tr> </c:foreach> </table> </body> </html>
访问这个jsp例子,运行结果如下:
4. delete操作
这个例子告诉我们如何使用jstl sql标签来运行sql delete语句:
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <%@ page import="java.io.*,java.util.*,java.sql.*"%> <%@ page import="javax.servlet.http.*,javax.servlet.*" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%> <html> <head> <title>select 操作</title> </head> <body> <!-- jdbc 驱动名及数据库 url 数据库的用户名与密码,需要根据自己的设置 useunicode=true&characterencoding=utf-8 防止中文乱码 --> <sql:setdatasource var="snapshot" driver="com.mysql.jdbc.driver" url="jdbc:mysql://localhost:3306/runoob?useunicode=true&characterencoding=utf-8" user="root" password="123456"/> <!-- 删除 id 为 11 的数据 --> <sql:update datasource="${snapshot}" var="count"> delete from websites where id = ? <sql:param value="${11}" /> </sql:update> <sql:query datasource="${snapshot}" var="result"> select * from websites; </sql:query> <h1>jsp 数据库实例 - 菜鸟教程</h1> <table border="1" width="100%"> <tr> <th>id</th> <th>站点名</th> <th>站点地址</th> </tr> <c:foreach var="row" items="${result.rows}"> <tr> <td><c:out value="${row.id}"/></td> <td><c:out value="${row.name}"/></td> <td><c:out value="${row.url}"/></td> </tr> </c:foreach> </table> </body> </html>
访问这个jsp例子,运行结果如下:
5. update操作
这个例子告诉我们如何使用jstl sql标签来运行sql update语句:
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <%@ page import="java.io.*,java.util.*,java.sql.*"%> <%@ page import="javax.servlet.http.*,javax.servlet.*" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql"%> <html> <head> <title>select 操作</title> </head> <body> <!-- jdbc 驱动名及数据库 url 数据库的用户名与密码,需要根据自己的设置 useunicode=true&characterencoding=utf-8 防止中文乱码 --> <sql:setdatasource var="snapshot" driver="com.mysql.jdbc.driver" url="jdbc:mysql://localhost:3306/runoob?useunicode=true&characterencoding=utf-8" user="root" password="123456"/> <!-- 修改 id 为 3 的名字:菜鸟教程改为 runoob --> <c:set var="siteid" value="3"/> <sql:update datasource="${snapshot}" var="count"> update websites set name = 'runoob' where id = ? <sql:param value="${siteid}" /> </sql:update> <sql:query datasource="${snapshot}" var="result"> select * from websites; </sql:query> <h1>jsp 数据库实例 - 菜鸟教程</h1> <table border="1" width="100%"> <tr> <th>id</th> <th>站点名</th> <th>站点地址</th> </tr> <c:foreach var="row" items="${result.rows}"> <tr> <td><c:out value="${row.id}"/></td> <td><c:out value="${row.name}"/></td> <td><c:out value="${row.url}"/></td> </tr> </c:foreach> </table> </body> </html>
访问这个jsp例子,运行结果如下:
四、jsp javabean
javabean是特殊的java类,使用j ava语言书写,并且遵守javabean api规范。
接下来给出的是javabean与其它java类相比而言独一无二的特征:
提供一个默认的无参构造函数。
需要被序列化并且实现了serializable接口。
可能有一系列可读写属性。
可能有一系列的"getter"或"setter"方法。
1. javabean属性
一个javabean对象的属性应该是可访问的。这个属性可以是任意合法的java数据类型,包括自定义java类。
一个javabean对象的属性可以是可读写,或只读,或只写。javabean对象的属性通过javabean实现类中提供的两个方法来访问:
2. javabean 程序示例
这是studentbean.java文件:
package com.runoob; public class studentsbean implements java.io.serializable { private string firstname = null; private string lastname = null; private int age = 0; public studentsbean() { } public string getfirstname(){ return firstname; } public string getlastname(){ return lastname; } public int getage(){ return age; } public void setfirstname(string firstname){ this.firstname = firstname; } public void setlastname(string lastname){ this.lastname = lastname; } public void setage(int age) { this.age = age; } }
编译 studentbean.java 文件(最后一个实例会用到):
$ javac studentsbean.java
编译后获得 studentbean.class 文件,将其拷贝到 <jsp 项目>/webcontent/web-inf/classes/com/runoob,如下图所示:
3. 访问javabean
<jsp:usebean> 标签可以在jsp中声明一个javabean,然后使用。声明后,javabean对象就成了脚本变量,可以通过脚本元素或其他自定义标签来访问。<jsp:usebean>标签的语法格式如下:
<jsp:usebean id="bean 的名字" scope="bean 的作用域" typespec/>
其中,根据具体情况,scope的值可以是page,request,session或application。id值可任意只要不和同一jsp文件中其它<jsp:usebean>中id值一样就行了。
接下来给出的是 <jsp:usebean> 标签的一个简单的用法:
<%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <html> <head> <title>usebean 实例</title> </head> <body> <jsp:usebean id="date" class="java.util.date" /> <p>日期为:<%= date %> </body> </html>
它将会产生如下结果:
日期为:tue jun 28 15:22:24 cst 2016
4. 访问 javabean 对象的属性
在 <jsp:usebean> 标签主体中使用 <jsp:getproperty/> 标签来调用 getter 方法,使用 <jsp:setproperty/> 标签来调用 setter 方法,语法格式如下:
<jsp:usebean id="id" class="bean 编译的类" scope="bean 作用域"> <jsp:setproperty name="bean 的 id" property="属性名" value="value"/> <jsp:getproperty name="bean 的 id" property="属性名"/> ........... </jsp:usebean> name属性指的是bean的id属性。property属性指的是想要调用的getter或setter方法。 接下来给出使用以上语法进行属性访问的一个简单例子: <%@ page language="java" contenttype="text/html; charset=utf-8" pageencoding="utf-8"%> <html> <head> <title>get 和 set 属性实例</title> </head> <body> <jsp:usebean id="students" class="com.runoob.studentsbean"> <jsp:setproperty name="students" property="firstname" value="小强"/> <jsp:setproperty name="students" property="lastname" value="王"/> <jsp:setproperty name="students" property="age" value="10"/> </jsp:usebean> <p>学生名字: <jsp:getproperty name="students" property="firstname"/> </p> <p>学生姓氏: <jsp:getproperty name="students" property="lastname"/> </p> <p>学生年龄: <jsp:getproperty name="students" property="age"/> </p> </body> </html>
访问以上 jsp,运行结果如下:
学生名字: 小强 学生姓氏: 王 学生年龄: 10
五、jsp 自定义标签
自定义标签是用户定义的jsp语言元素。当jsp页面包含一个自定义标签时将被转化为servlet,标签转化为对被 称为tag handler的对象的操作,即当servlet执行时web container调用那些操作。
jsp标签扩展可以让你创建新的标签并且可以直接插入到一个jsp页面。 jsp 2.0规范中引入simple tag handlers来编写这些自定义标记。
你可以继承simpletagsupport类并重写的dotag()方法来开发一个最简单的自定义标签。
1. 创建"hello"标签
接下来,我们想创建一个自定义标签叫作<ex:hello>,标签格式为:
<ex:hello />
要创建自定义的jsp标签,你首先必须创建处理标签的java类。所以,让我们创建一个hellotag类,如下所示:
package com.runoob; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; public class hellotag extends simpletagsupport { public void dotag() throws jspexception, ioexception { jspwriter out = getjspcontext().getout(); out.println("hello custom tag!"); } } 以下代码重写了dotag()方法,方法中使用了getjspcontext()方法来获取当前的jspcontext对象,并将"hello custom tag!"传递给jspwriter对象。 编译以上类,并将其复制到环境变量classpath目录中。最后创建如下标签库:<tomcat安装目录>webapps\root\web-inf\custom.tld。 <taglib> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>example tld</short-name> <tag> <name>hello</name> <tag-class>com.runoob.hellotag</tag-class> <body-content>empty</body-content> </tag> </taglib> 接下来,我们就可以在jsp文件中使用hello标签: <%@ taglib prefix="ex" uri="web-inf/custom.tld"%> <html> <head> <title>a sample custom tag</title> </head> <body> <ex:hello/> </body> </html>
以上程序输出结果为:
hello custom tag!
2. 访问标签体
你可以像标准标签库一样在标签中包含消息内容。如我们要在我们自定义的hello中包含内容,格式如下:
<ex:hello> this is message body </ex:hello>
我们可以修改标签处理类文件,代码如下:
package com.runoob; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; public class hellotag extends simpletagsupport { stringwriter sw = new stringwriter(); public void dotag() throws jspexception, ioexception { getjspbody().invoke(sw); getjspcontext().getout().println(sw.tostring()); } }
接下来我们需要修改tld文件,如下所示:
<taglib> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>example tld with body</short-name> <tag> <name>hello</name> <tag-class>com.runoob.hellotag</tag-class> <body-content>scriptless</body-content> </tag> </taglib> 现在我们可以在jsp使用修改后的标签,如下所示: <%@ taglib prefix="ex" uri="web-inf/custom.tld"%> <html> <head> <title>a sample custom tag</title> </head> <body> <ex:hello> this is message body </ex:hello> </body> </html>
以上程序输出结果如下所示:
this is message body
3. 自定义标签属性
你可以在自定义标准中设置各种属性,要接收属性,值自定义标签类必须实现setter方法, javabean 中的setter方法如下所示:
package com.runoob; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; public class hellotag extends simpletagsupport { private string message; public void setmessage(string msg) { this.message = msg; } stringwriter sw = new stringwriter(); public void dotag() throws jspexception, ioexception { if (message != null) { /* 从属性中使用消息 */ jspwriter out = getjspcontext().getout(); out.println( message ); } else { /* 从内容体中使用消息 */ getjspbody().invoke(sw); getjspcontext().getout().println(sw.tostring()); } } }
属性的名称是"message",所以setter方法是的setmessage()。现在让我们在tld文件中使用的<attribute>元素添加此属性:
<taglib> <tlib-version>1.0</tlib-version> <jsp-version>2.0</jsp-version> <short-name>example tld with body</short-name> <tag> <name>hello</name> <tag-class>com.runoob.hellotag</tag-class> <body-content>scriptless</body-content> <attribute> <name>message</name> </attribute> </tag> </taglib>
现在我们就可以在jsp文件中使用message属性了,如下所示:
<%@ taglib prefix="ex" uri="web-inf/custom.tld"%> <html> <head> <title>a sample custom tag</title> </head> <body> <ex:hello message="this is custom tag" /> </body> </html>
以上实例数据输出结果为:
this is custom tag
你还可以包含以下属性:
以下是指定相关的属性实例:
..... <attribute> <name>attribute_name</name> <required>false</required> <type>java.util.date</type> <fragment>false</fragment> </attribute> .....
如果你使用了两个属性,修改tld文件,如下所示:
..... <attribute> <name>attribute_name1</name> <required>false</required> <type>java.util.boolean</type> <fragment>false</fragment> </attribute> <attribute> <name>attribute_name2</name> <required>true</required> <type>java.util.date</type> </attribute> .....
六、jsp 表达式语言
jsp表达式语言(el)使得访问存储在javabean中的数据变得非常简单。jsp el既可以用来创建算术表达式也可以用来创建逻辑表达式。在jsp el表达式内可以使用整型数,浮点数,字符串,常量true、false,还有null。
1. 一个简单的语法
一个简单的语法
典型的,当您需要在jsp标签中指定一个属性值时,只需要简单地使用字符串即可:
<jsp:setproperty name="box" property="perimeter" value="100"/>
jsp el允许您指定一个表达式来表示属性值。一个简单的表达式语法如下:
${expr}
其中,expr指的是表达式。在jsp el中通用的操作符是 . 和 {} 。这两个操作符允许您通过内嵌的jsp对象访问各种各样的javabean属性。
举例来说,上面的<jsp:setproperty>标签可以使用表达式语言改写成如下形式:
<jsp:setproperty name="box" property="perimeter" value="${2*box.width+2*box.height}"/>
当jsp编译器在属性中见到"${}"格式后,它会产生代码来计算这个表达式,并且产生一个替代品来代替表达式的值。
您也可以在标签的模板文本中使用表达式语言。比如<jsp:text>标签简单地将其主体中的文本插入到jsp输出中:
<jsp:text> <h1>hello jsp!</h1> </jsp:text>
现在,在<jsp:text>标签主体中使用表达式,就像这样:
<jsp:text> box perimeter is: ${2*box.width + 2*box.height} </jsp:text>
在el表达式中可以使用圆括号来组织子表达式。比如{1 + (2 * 3)} 等于7。
想要停用对el表达式的评估的话,需要使用page指令将iselignored属性值设为true:
<%@ page iselignored ="true|false" %>
这样,el表达式就会被忽略。若设为false,则容器将会计算el表达式。
2. el中的基础操作符
el表达式支持大部分java所提供的算术和逻辑操作符:
3. jsp el中的函数
jsp el允许您在表达式中使用函数。这些函数必须被定义在自定义标签库中。函数的使用语法如下:
${ns:func(param1, param2, ...)}
ns指的是命名空间(namespace),func指的是函数的名称,param1指的是第一个参数,param2指的是第二个参数,以此类推。比如,有函数fn:length,在jstl库中定义,可以像下面这样来获取一个字符串的长度:
${fn:length("get my length")}
要使用任何标签库中的函数,您需要将这些库安装在服务器中,然后使用<taglib>标签在jsp文件中包含这些库。
4. jsp el隐含对象
jsp el支持下表列出的隐含对象:
您可以在表达式中使用这些对象,就像使用变量一样。接下来会给出几个例子来更好的理解这个概念。
6. scope对象
pagescope,requestscope,sessionscope,applicationscope变量用来访问存储在各个作用域层次的变量。
举例来说,如果您需要显式访问在applicationscope层的box变量,可以这样来访问:applicationscope.box。
7. param和paramvalues对象
param和paramvalues对象用来访问参数值,通过使用request.getparameter方法和request.getparametervalues方法。
举例来说,访问一个名为order的参数,可以这样使用表达式:{param["order"]}。
接下来的例子表明了如何访问request中的username参数:
<%@ page import="java.io.*,java.util.*" %> <% string title = "accessing request param"; %> <html> <head> <title><% out.print(title); %></title> </head> <body> <center> <h1><% out.print(title); %></h1> </center> <div align="center"> <p>${param["username"]}</p> </div> </body> </html>
param对象返回单一的字符串,而paramvalues对象则返回一个字符串数组。
8. header和headervalues对象
header和headervalues对象用来访问信息头,通过使用 request.getheader方法和request.getheaders方法。
举例来说,要访问一个名为user-agent的信息头,可以这样使用表达式:{header["user-agent"]}。
接下来的例子表明了如何访问user-agent信息头:
<%@ page import="java.io.*,java.util.*" %> <% string title = "user agent example"; %> <html> <head> <title><% out.print(title); %></title> </head> <body> <center> <h1><% out.print(title); %></h1> </center> <div align="center"> <p>${header["user-agent"]}</p> </div> </body> </html>
运行结果如下:
header对象返回单一值,而headervalues则返回一个字符串数组。
七、jsp 异常处理
当编写jsp程序的时候,程序员可能会遗漏一些bug,这些bug可能会出现在程序的任何地方。jsp代码中通常有以下几类异常:
检查型异常:检查型异常就是一个典型的用户错误或者一个程序员无法预见的错误。举例来说,如果一个文件将要被打开,但是无法找到这个文件,则一个异常被抛出。这些异常不能再编译期被简单地忽略。
运行时异常:一个运行时异常可能已经被程序员避免,这种异常在编译期将会被忽略。
错误:错误不是异常,但问题是它超出了用户或者程序员的控制范围。错误通常会在代码中被忽略,您几乎不能拿它怎么样。举例来说,栈溢出错误。这些错误都会在编译期被忽略。
本节将会给出几个简单而优雅的方式来处理运行时异常和错误。
1. 使用exception对象
exception对象是throwable子类的一个实例,只在错误页面中可用。下表列出了throwable类中一些重要的方法:
jsp提供了可选项来为每个jsp页面指定错误页面。无论何时页面抛出了异常,jsp容器都会自动地调用错误页面。
接下来的例子为main.jsp指定了一个错误页面。使用<%@page errorpage="xxxxx"%>指令指定一个错误页面。
<%@ page errorpage="showerror.jsp" %> <html> <head> <title>error handling example</title> </head> <body> <% // throw an exception to invoke the error page int x = 1; if (x == 1) { throw new runtimeexception("error condition!!!"); } %> </body> </html>
现在,编写showerror.jsp文件如下:
<%@ page iserrorpage="true" %> <html> <head> <title>show error page</title> </head> <body> <h1>opps...</h1> <p>sorry, an error occurred.</p> <p>here is the exception stack trace: </p> <pre> <% exception.printstacktrace(response.getwriter()); %> 注意到,showerror.jsp文件使用了<%@page iserrorpage="true"%>指令,这个指令告诉jsp编译器需要产生一个异常实例变量。 现在试着访问main.jsp页面,它将会产生如下结果: java.lang.runtimeexception: error condition!!! ...... opps... sorry, an error occurred. here is the exception stack trace:
2. 在错误页面中使用jstl标签
可以利用jstl标签来编写错误页面showerror.jsp。这个例子中的代码与上例代码的逻辑几乎一样,但是本例的代码有更好的结构,并且能够提供更多信息:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@page iserrorpage="true" %> <html> <head> <title>show error page</title> </head> <body> <h1>opps...</h1> <table width="100%" border="1"> <tr valign="top"> <td width="40%"><b>error:</b></td> <td>${pagecontext.exception}</td> </tr> <tr valign="top"> <td><b>uri:</b></td> <td>${pagecontext.errordata.requesturi}</td> </tr> <tr valign="top"> <td><b>status code:</b></td> <td>${pagecontext.errordata.statuscode}</td> </tr> <tr valign="top"> <td><b>stack trace:</b></td> <td> <c:foreach var="trace" items="${pagecontext.exception.stacktrace}"> <p>${trace}</p> </c:foreach> </td> </tr> </table> </body> </html>
运行结果如下:
3. 使用 try…catch块
如果您想要将异常处理放在一个页面中,并且对不同的异常进行不同的处理,那么您就需要使用try…catch块了。
接下来的这个例子显示了如何使用try…catch块,将这些代码放在main.jsp中:
<html> <head> <title>try...catch example</title> </head> <body> <% try{ int i = 1; i = i / 0; out.println("the answer is " + i); } catch (exception e){ out.println("an exception occurred: " + e.getmessage()); } %> </body> </html>
试着访问main.jsp,它将会产生如下结果:
an exception occurred: / by zero
八、jsp 调试
要测试/调试一个jsp或servlet程序总是那么的难。jsp和servlets程序趋向于牵涉到大量客户端/服务器之间的交互,这很有可能会产生错误,并且很难重现出错的环境。
接下来将会给出一些小技巧和小建议,来帮助您调试程序。
1. 使用system.out.println()
system.out.println()可以很方便地标记一段代码是否被执行。当然,我们也可以打印出各种各样的值。此外:
自从system对象成为java核心对象后,它便可以使用在任何地方而不用引入额外的类。使用范围包括servlets,jsp,rmi,ejb's,beans,类和独立应用。
与在断点处停止运行相比,用system.out进行输出不会对应用程序的运行流程造成重大的影响,这个特点在定时机制非常重要的应用程序中就显得非常有用了。
接下来给出了使用system.out.println()的语法:
system.out.println("debugging message");
这是一个使用system.out.print()的简单例子:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head><title>system.out.println</title></head> <body> <c:foreach var="counter" begin="1" end="10" step="1" > <c:out value="${counter-5}"/></br> <% system.out.println( "counter= " + pagecontext.findattribute("counter") ); %> </c:foreach> </body> </html>
现在,如果运行上面的例子的话,它将会产生如下的结果:
-4 -3 -2 -1 0 1 2 3 4 5
如果使用的是tomcat服务器,您就能够在logs目录下的stdout.log文件中发现多出了如下内容:
counter=1 counter=2 counter=3 counter=4 counter=5 counter=6 counter=7 counter=8 counter=9 counter=10
使用这种方法可以将变量和其它的信息输出至系统日志中,用来分析并找出造成问题的深层次原因。
2. 使用jdb logger
j2se日志框架可为任何运行在jvm中的类提供日志记录服务。因此我们可以利用这个框架来记录任何信息。
让我们来重写以上代码,使用jdk中的 logger api:
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@page import="java.util.logging.logger" %> <html> <head><title>logger.info</title></head> <body> <% logger logger=logger.getlogger(this.getclass().getname());%> <c:foreach var="counter" begin="1" end="10" step="1" > <c:set var="mycount" value="${counter-5}" /> <c:out value="${mycount}"/></br> <% string message = "counter=" + pagecontext.findattribute("counter") + " mycount=" + pagecontext.findattribute("mycount"); logger.info( message ); %> </c:foreach> </body> </html>
它的运行结果与先前的类似,但是,它可以获得额外的信息输出至stdout.log文件中。在这我们使用了logger中的info方法。下面我们给出stdout.log文件中的一个快照:
24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=1 mycount=-4 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=2 mycount=-3 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=3 mycount=-2 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=4 mycount=-1 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=5 mycount=0 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=6 mycount=1 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=7 mycount=2 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=8 mycount=3 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=9 mycount=4 24-sep-2013 23:31:31 org.apache.jsp.main_jsp _jspservice info: counter=10 mycount=5
消息可以使用各种优先级发送,通过使用sever(),warning(),info(),config(),fine(),finer(),finest()方法。finest()方法用来记录最好的信息,而sever()方法用来记录最严重的信息。
使用log4j 框架来将消息记录在不同的文件中,这些消息基于严重程度和重要性来进行分类。
3. 调试工具
netbeans是树形结构,是开源的java综合开发环境,支持开发独立的java应用程序和网络应用程序,同时也支持jsp调试。
netbeans支持如下几个基本的调试功能:
断点
单步跟踪
观察点
详细的信息可以查看netbeans使用手册。
.4. 使用jdb debugger
可以在jsp和servlets中使用jdb命令来进行调试,就像调试普通的应用程序一样。
通常,我们直接调试sun.servlet.http.httpserver 对象来查看httpserver在响应http请求时执行jsp/servlets的情况。这与调试applets非常相似。不同之处在于,applets程序实际调试的是sun.applet.appletviewer。
大部分调试器在调试applets时都能够自动忽略掉一些细节,因为它知道如何调试applets。如果想要将调试对象转移到jsp身上,就需要做好以下两点:
设置调试器的classpath,让它能够找到sun.servlet.http.http-server 和相关的类。
设置调试器的classpath,让它能够找到您的jsp文件和相关的类。
设置好classpath后,开始调试sun.servlet.http.http-server 。您可以在jsp文件的任意地方设置断点,只要你喜欢,然后使用浏览器发送一个请求给服务器就应该可以看见程序停在了断点处。
5. 使用注释
程序中的注释在很多方面都对程序的调试起到一定的帮助作用。注释可以用在调试程序的很多方面中。
jsp使用java注释。如果一个bug消失了,就请仔细查看您刚注释过的代码,通常都能找出原因。
6. 客户端和服务器的头模块
有时候,当jsp没有按照预定的方式运行时,查看未加工的http请求和响应也是很有用的。如果对http的结构很熟悉的话,您可以直接观察request和response然后看看这些头模块到底怎么了。
7. 重要调试技巧
这里我们再透露两个调试jsp的小技巧:
使用浏览器显示原始的页面内容,用来区分是否是格式问题。这个选项通常在view菜单下。
确保浏览器在强制重新载入页面时没有捕获先前的request输出。若使用的是netscape navigator浏览器,则用shift-reload;若使用的是ie浏览器,则用shift-refresh。
九、jsp 国际化
在开始前,需要解释几个重要的概念:
国际化(i18n):表明一个页面根据访问者的语言或国家来呈现不同的翻译版本。
本地化(l10n):向网站添加资源,以使它适应不同的地区和文化。比如网站的印度语版本。
区域:这是一个特定的区域或文化,通常认为是一个语言标志和国家标志通过下划线连接起来。比如"en_us"代表美国英语地区。
如果想要建立一个全球化的网站,就需要关心一系列项目。本章将会详细告诉您如何处理国际化问题,并给出了一些例子来加深理解。
jsp容器能够根据request的locale属性来提供正确地页面版本。接下来给出了如何通过request对象来获得locale对象的语法:
java.util.locale request.getlocale()
1. 检测locale
下表列举出了locale对象中比较重要的方法,用于检测request对象的地区,语言,和区域。所有这些方法都会在浏览器中显示国家名称和语言名称:
2. 实例演示
这个例子告诉我们如何在jsp中显示语言和国家:
<%@ page import="java.io.*,java.util.locale" %><%@ page import="javax.servlet.*,javax.servlet.http.* "%><% //获取客户端本地化信息 locale locale = request.getlocale(); string language = locale.getlanguage(); string country = locale.getcountry(); %><html><head><title>detecting locale</title></head><body><center><h1>detecting locale</h1></center><p align="center"><% out.println("language : " + language + "<br />"); out.println("country : " + country + "<br />"); %></p></body></html>
3. 语言设置
jsp可以使用西欧语言来输出一个页面,比如英语,西班牙语,德语,法语,意大利语等等。由此可见,设置content-language信息头来正确显示所有字符是很重要的。
第二点就是,需要使用html字符实体来显示特殊字符,比如"ñ" 代表的是"?","¡"代表的是 "?" :
<%@ page import="java.io.*,java.util.locale" %><%@ page import="javax.servlet.*,javax.servlet.http.* "%><% // set response content type response.setcontenttype("text/html"); // set spanish language code. response.setheader("content-language", "es"); string title = "en espa?ol"; %><html><head><title><% out.print(title); %></title></head><body><center><h1><% out.print(title); %></h1></center><div align="center"><p>en espa?ol</p><p>?hola mundo!</p></div></body></html>
4. 区域特定日期
可以使用java.text.dateformat类和它的静态方法getdatetimeinstance()来格式化日期和时间。接下来的这个例子显示了如何根据指定的区域来格式化日期和时间:
<%@ page import="java.io.*,java.util.locale" %><%@ page import="javax.servlet.*,javax.servlet.http.* "%><%@ page import="java.text.dateformat,java.util.date" %> <% string title = "locale specific dates"; //get the client's locale locale locale = request.getlocale( ); string date = dateformat.getdatetimeinstance( dateformat.full, dateformat.short, locale).format(new date( )); %><html><head><title><% out.print(title); %></title></head><body><center><h1><% out.print(title); %></h1></center><div align="center"><p>local date: <% out.print(date); %></p></div></body></html>
5. 区域特定货币
可以使用java.text.numberformat类和它的静态方法getcurrencyinstance()来格式化数字。比如在区域特定货币中的long型和double型。接下来的例子显示了如何根据指定的区域来格式化货币:
<%@ page import="java.io.*,java.util.locale" %><%@ page import="javax.servlet.*,javax.servlet.http.* "%><%@ page import="java.text.numberformat,java.util.date" %> <% string title = "locale specific currency"; //get the client's locale locale locale = request.getlocale( ); numberformat nft = numberformat.getcurrencyinstance(locale); string formattedcurr = nft.format(1000000); %><html><head><title><% out.print(title); %></title></head><body><center><h1><% out.print(title); %></h1></center><div align="center"><p>formatted currency: <% out.print(formattedcurr); %></p></div></body></html>
6. 区域特定百分比
可以使用java.text.numberformat类和它的静态方法getpercentinstance()来格式化百分比。接下来的例子告诉我们如何根据指定的区域来格式化百分比:
<%@ page import="java.io.*,java.util.locale" %><%@ page import="javax.servlet.*,javax.servlet.http.* "%><%@ page import="java.text.numberformat,java.util.date" %> <% string title = "locale specific percentage"; //get the client's locale locale locale = request.getlocale( ); numberformat nft = numberformat.getpercentinstance(locale); string formattedperc = nft.format(0.51); %><html><head><title><% out.print(title); %></title></head><body><center><h1><% out.print(title); %></h1></center><div align="center"><p>formatted percentage: <% out.print(formattedperc); %></p></div></body></html>
十、学习资料下载
链接:https://pan.baidu.com/s/1ugrareith7bucip66htlsq
提取码:ve39