hackiller的博客文章 作者: hackiller http://hackiller.javaeye.com J2EE复习资料 http://www.javaeye.com - 做最棒的软件开发交流社区 第 1 / 99 页 本书由JavaEye提供的电子书DIY功能自动生成于 2009-04-14 目 录 1. J2EE复习资料 1.1 J2EE复习(一)HTML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 J2EE复习(二)XML(上) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.3 J2EE复习(二)XML(下)--xml解析 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .17 1.4 J2EE复习(三)JavaScript(上)--基础入门 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .36 1.5 J2EE复习(三)JavaScript(下)--实战应用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .47 1.6 J2EE复习(四)servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 1.7 J2EE复习(五)JSP基础 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 1.8 J2EE复习(六)JSP自定义标签 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 1.9 J2EE复习(七)JSTL(JSP标准标签库) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91 http://hackiller.javaeye.com 第 2 / 99 页 1.1 J2EE复习(一)HTML 发表时间: 2009-04-11 HTML(Hypertext Markup Language) 简介 HTML 是一种标记语言 使用 HTML 标记和元素,可以: 控制页面和内容的外观 发布联机文档 使用 HTML 文档中插入的链接检索联机信息 创建联机表单,收集用户的信息、执行事务等等 插入动画 开发帮助文件 使用META标记 2-1 name和http-equiv 1.提供关于网页的信息 "description"中的content="网页描述",是对一个网页概况的介绍,这些信息可能会出现在搜索结果中,因此 需要根据网页的实际情况来设计,尽量避免与网页内容不相关的“描述”,另外,最好对每个网页有自己相应 的描述(至少是同一个栏目的网页有相应的描述),而不是整个网站都采用同样的描述内容,因为一个网站有 多个网页,每个网页的内容肯定是不同的,如果采用同样的description,显然会有一些网页内容没有直接关 系,这样不仅不利于搜索引擎对网页的排名,也不利于用户根据搜索结果中的信息来判断是否点击进入网站获 取进一步的信息。 2.应用:关键词生成响应 http://hackiller.javaeye.com 1.1 J2EE复习(一)HTML 第 3 / 99 页 3.自动刷新页面 最常用的字符实体 空格:   <小于号:< >大于号:> &号:& "引号:" ¢分: ¢ £镑:£ ¥日圆:¥ §节:§ '撇号:' ?版权:© ?注册商标:® ×乘号:× ÷除号:÷ 链接标记A 1.链接到同一文档的各个部分 使用链接 互联网
HTML简介
多样化和统一性
互联网

互联网是网络的网络。就是说,计算机网络可以跨越国家甚至全球的范围连接到其他网络

HTML简介

超文本标记语言是Web用来创建和识别文档的标准语言。

多样性和统一

万事万物都离不开多样性和统一性这样一条基本准则。

2.链接到另一文档中某个特定位置 http://hackiller.javaeye.com 1.1 J2EE复习(一)HTML 第 4 / 99 页 主文档 互联网
HTML简介
多样性和统一性 3.使用电子邮件 如果希望用户在网页上通过链接直接打开客户端的发送邮件的工具发送电子邮件,则可以在网页内包含发送电 子邮件的功能。实现此功能所需的全部工作就是在链接标记中插入mailto值。 我的电子邮件 基本 HTML 元素 标题标记:可显示六种大小的标题,即

为最大,

为最小 段落级标记:
标记,定义地址元素;
标记; 块标记:
字符级标记: . . . 上标文本 下标文本 . . 强调文本 用于显示编程代码 . . . 用于引用 无序列表 学习 HTML
    http://hackiller.javaeye.com 1.1 J2EE复习(一)HTML 第 5 / 99 页
  • 星期一
  • 星期二
  • 星期三
  • 星期四
  • 星期五
有序列表 学习 HTML
  1. 星期一
  2. 星期二
  3. 星期三
  4. 星期四
  5. 星期五
大写罗马数字
  • 小写罗马数字
  • 大写字母
  • 小写字母
  • 从第n个值开始编号
      定义列表 学习 HTML http://hackiller.javaeye.com 1.1 J2EE复习(一)HTML 第 6 / 99 页
      星期日
      一周的第一天
      HTML
      超文本标记语言
      互联网
      网络的网络
      table 表 http://hackiller.javaeye.com 1.1 J2EE复习(一)HTML 第 7 / 99 页
      创建表
      第一季度 第二季度
      一月 二月 三月 四月 五月 六月
      1000 550 240 1500 2765 1240
      3000 2430 2500 1250 900 3400
      插入GIF动画 冒热汽的咖啡 HTML 文档中的图片 GIF(Graphics Interchange Format )图像 (.GIF) JPEG(Joint Photographic Experts Group)图像 (.JPG) PNG(Portable Network Graphics ) 插入声音 插入视频 使用表单
      表单内容
      HTML 输入元素input属性 TYPE:此属性指定表单元素的类型。可用的选项有TEXT、PASSWORD、CHECKBOX、RADIO、SUBMIT、 http://hackiller.javaeye.com 1.1 J2EE复习(一)HTML 第 8 / 99 页 RESET、 FILE、HIDDEN和BUTTON。默认值为TEXT。 TYPE:此属性指定表单元素的名称。例如,如果表单上有几个文本框,可以按照名称来标识它们 - TEXT1、 TEXT2或用户选择的任何名称。 VALUE:此属性是可选属性,它指定表单元素的初始值 MAXLENGHT:此属性用于指定在TEXT或PASSWORD表单元素中可以输入的最大字符数。默认值为无限的 SRC:SRC="URL"。当使用IMAGE作为输入类型时使用此属性,它用于标识图像的位置。TextArea 元素:属 性有Cols、Rows BUTTON 元素:属性有Name、Value、Type 列表(下拉框)SELECT 元素:Name、Size、Multiple 框架使用 未显示框架。请单击这里 <A href=”main.htm”>查看无框架版本</A> 内嵌框架

      很有趣吧。你已经对框架有所了解。

      上面是一个内嵌框架。 http://hackiller.javaeye.com 1.1 J2EE复习(一)HTML 第 9 / 99 页 1.2 J2EE复习(二)XML(上) 发表时间: 2009-04-11 XML(eXtensible Markup Language)简介 XML 可扩展标记语言 XML是一种您可以用来创建自己的标记的标记语言。 XML由万维网协会(W3C)创建 XML和Html比较 比较内容 HTML XML 可扩展性 不具有扩展性 是元标记言,可用于定义新的标记语言 侧重点 侧重于如何表现信息 侧重于如何结构化地描述信息 语法要求 不要求标记的嵌套、配对等,不 严格要求嵌套、配对,并遵循DTD的树形结构 要求标记之间具有一定的顺序 可读性及可维护性 难于阅读、维护 结构清晰,便于阅读、维护 数据和显示的关系 内容描述与显示方式整合为一体 内容描述与显示方式相分离 编辑及浏览工 已有大量的编辑、浏览工具 编辑、浏览工具 XML优势 数据重用、数据和表示分离、可扩展性、语意信息 XML 声明 XML声明一般是XML文档的第一行 XML声明由以下几个部分组成: version - -文档符合XML1.0规范 encoding - -文档字符编码,默认为"UTF-8" 遵循如下规则的XML文档称为结构完整: 语法规范 1.必须有XML声明语句 http://hackiller.javaeye.com 1.2 J2EE复习(二)XML(上) 第 10 / 99 页 2. 3.必须有且仅有一个根元素 4.标记大小写敏感 5.属性值用引号 6.标记成对 7.空标记关闭 8.元素正确嵌套 元素语法 1.名称中可以包含字母、数字或者其它字符 2.名称不能以数字和"_"(下划线)开头 3.不能以XML/xml/Xml/…开头 4.名称中不能含空格 5.名称中不能含冒号(注:冒号留给命名空间使用) 文本内容PCDATA XML支持Unicde字符集,因此可以在文本中包含字母/数字/标点/符号等。 注意:因为XML使用<,>,和&界定标记,如果在文本中包含有这些字符,必须使用实体替代。 CDATA 1.在特殊的标记CDATA下,所有的标记、实体引用都被忽略,而被XML处理程序一视同仁地当作字符数据看 待。CDATA的形式:〈![CDATA[文本内容]]〉 2.用于把整段文本解释为纯字符数据而不是标记的情况。包含大量<、>、&或者"字符。CDATA节中的所有字 符都会被当作元素字符数据的常量部分,而不是XML标记。 3.可以输入任意字符(除]]>外) 4.不能嵌套使用CDATA CDATA与PCDATA PCDATA是被解析器解析的文本。文本内的标签会被当作标记,实体会被展开。 CDATA是不被解析器解析的文本。文本内的标签不会被当作标记,实体不会被展开。 XML注释 注释内容中不要出现--; 不要把注释放在标记中间; >TOM 注释不能嵌套; 可以在除标记以外的任何地方放注释。 http://hackiller.javaeye.com 1.2 J2EE复习(二)XML(上) 第 11 / 99 页 XML属性 1.属性值用双引号(")或单引号(')分隔(如果属性值中有',用"分隔;有",用'分隔) 2.一个元素可以有多个属性,它的基本格式为:<元素名 属性名="属性值"> 3.特定的属性名称在同一个元素标记中只能出现一次 4.属性值不能包括<, >, & XML文档中的属性有两个规则: 1.属性必须有值 2.那些值必须用引号括起。您可以使用单引号,也可以使用双引号,但要始终保持一致。 命名空间---namespace 为XML中的元素设定一个唯一的标识名称 与URI结合来定义一个唯一标识 去除了XML文件中可能存在的元素名重叠的问题 DOCTYPE 文档类型声明,紧跟XML声明之后,包含所有实体声明语法: ]> 实体引用 为了避免把字符数据和标记中需要用到的一些特殊符号相混淆,XML还提供了一些有用的实体引用。 作用:避免重复输入 自定义实体语法: ]> 引用已定义的实体:&实体名; DTD 内部的 DOCTYPE 声明: 假如 DTD 被包含在您的 XML 源文件中,它应当通过下面的语法包装在一个 DOCTYPE 声明中: (请在 IE5 以及更高的版本打开,并选择查看源代码): http://hackiller.javaeye.com 1.2 J2EE复习(二)XML(上) 第 12 / 99 页 ]> George John Reminder Don't forget the meeting! 以上 DTD 解释如下: !DOCTYPE note (第二行)定义此文档是 note 类型的文档。 !ELEMENT note (第三行)定义 note 元素有四个元素:"to、from、heading,、body" !ELEMENT to (第四行)定义 to 元素为 "#PCDATA" 类型 !ELEMENT from (第五行)定义 frome 元素为 "#PCDATA" 类型 !ELEMENT heading (第六行)定义 heading 元素为 "#PCDATA" 类型 !ELEMENT body (第七行)定义 body 元素为 "#PCDATA" 类型 外部文档声明: 假如 DTD 位于 XML 源文件的外部,那么它应通过下面的语法被封装在一个 DOCTYPE 定义中: 这个 XML 文档和上面的 XML 文档相同,但是拥有一个外部的 DTD: (在 IE5 中打开,并选择“查看源代码”命令。) George John Reminder Don't forget the meeting! http://hackiller.javaeye.com 1.2 J2EE复习(二)XML(上) 第 13 / 99 页 声明一个元素: 在 DTD 中,XML 元素通过元素声明来进行声明。元素声明使用下面的语法: 或者 空元素 空元素通过类别关键词EMPTY进行声明: 只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明: 带有任何内容的元素:通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合 带有一个或多个子元素的元素通过圆括号中的子元素名进行声明: 或者 当子元素按照由逗号分隔开的序列进行声明时,这些子元素必须按照相同的顺序出现在文档中。在一个完整的 声明中,子元素也必须被声明,同时子元素也可拥有子元素。 声明只出现一次的元素: 声明最少出现一次的元素: 声明出现零次或多次的元素: http://hackiller.javaeye.com 1.2 J2EE复习(二)XML(上) 第 14 / 99 页 声明出现零次或一次的元素: 声明“非.../既...”类型的内容: 上面的例子声明了:"note" 元素必须包含 "to" 元素、"from" 元素、"header" 元素,以及非 "message" 元素 既 "body" 元素。 声明混合型的内容: 上面的例子声明了:"note" 元素可包含出现零次或多次的 PCDATA、"to"、"from"、"header" 或者 "message"。 XML Schema 简介 XML Schema 是基于 XML 的 DTD 替代者。 XML Schema 可描述 XML 文档的结构。 XML Schema 语言也可作为 XSD(XML Schema Definition)来引用。 XML Schema 是 DTD 的继任者 XML Schema 相对于 DTD 的优点如下: XML Schema 可针对未来的需求进行扩展 XML Schema 更完善,功能更强大 XML Schema 基于 XML 编写 XML Schema 支持数据类型 XML Schema 支持命名空间 下面这个例子是一个名为 "note.xsd" 的 XML Schema 文件,它定义了下面那个 XML 文档的元素: 对 XML Schema 的引用: George John Reminder Don't forget the meeting! http://hackiller.javaeye.com 1.2 J2EE复习(二)XML(上) 第 16 / 99 页 1.3 J2EE复习(二)XML(下)--xml解析 发表时间: 2009-04-11 xml的四种解析方法及源代码(SAX、DOM、JDOM、DOM4J) 第一种:SAX解析 SAX处理机制:SAX是一种基于事件驱动的API。利用SAX解析XML文档,牵涉到两个部分:解析器和事件处理 器。解析器负责读取XML文档,并向事件处理器发生事件,如元素开始和元素结束事件;而事件处理器则负责 对事件做出响应,对传递的XML数据进行处理。 测试用的xml文件:db.xml oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@localhost:1521:oracle scott tiger DTD文件db.dtd SAX解析实例一 org.xml.sax.DefalutHandler类: 可以扩展该类,给出自己的解析实现 SAXPrinter.java http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 17 / 99 页 import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class SAXPrinter extends DefaultHandler { /** *//** * 文档开始事件 */ public void startDocument() throws SAXException { System.out.println(""); } /** *//** * 接收处理指令事件 */ public void processingInstruction(String target, String data) throws SAXException { System.out.println(""); } /** *//** * 元素开始事件 * 参数说明: * uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。 * localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。 * qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。 * attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。 */ public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 18 / 99 页 { System.out.print("<"+qName);//输出元素名称 int len=attrs.getLength();//元素属性列表长度 //利用循环输出属性列表 for(int i=0;i"); } /** *//** * 元素中字符数据事件:接收元素中字符数据 * 注意:1.应用程序不要试图读取ch数组指定范围外的数据,(即start至length之外) * 2.有些解析器将使用ignorableWhitespace()方法来报告元素内容中的空白,而不是characters()方法,如:进行有效性验证的解析器 */ public void characters(char[] ch, int start, int length) throws SAXException { System.out.print(new String(ch,start,length)); } /** *//** * 结束元素事件 */ public void endElement(String uri, String localName, String qName) throws SAXException { System.out.print(""); } public static void main(String[] args) { SAXParserFactory spf=SAXParserFactory.newInstance(); http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 19 / 99 页 try { SAXParser sp=spf.newSAXParser(); sp.parse(new File("db.xml"),new SAXPrinter()); } catch (Exception e) { e.printStackTrace(); } } } SAX解析实例二 org.xml.sax.ContentHandler接口: 通过实现该接口给出自己的解析实现。 org.xml.sax.ErrorHandler接口:如果SAX应用程序需要实现定制的错误处理,那么它必须实现这个接口,并调 用XMLReader对象的setErrorHandler()方法向解析器注册异常处理实例,这样,解析器将通过这个接口报告所 有的错误和警告。 ContentHandlerImpl.java import org.xml.sax.Attributes; import org.xml.sax.ContentHandler; import org.xml.sax.Locator; import org.xml.sax.SAXException; public class ContentHandlerImpl implements ContentHandler { /** *//** * 文档开始事件 */ public void startDocument() throws SAXException { System.out.println(""); } /** *//** * 接收处理指令事件 http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 20 / 99 页 */ public void processingInstruction(String target, String data) throws SAXException { System.out.println(""); } /** *//** * 元素开始事件 * 参数说明: * uri - 名称空间 URI,如果元素没有任何名称空间 URI,或者没有正在执行名称空间处理,则为空字符串。 * localName - 本地名称(不带前缀),如果没有正在执行名称空间处理,则为空字符串。 * qName - 限定的名称(带有前缀),如果限定的名称不可用,则为空字符串。 * attributes - 附加到元素的属性。如果没有属性,则它将是空的 Attributes 对象。 */ public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException { System.out.print("<"+qName);//输出元素名称 int len=attrs.getLength();//元素属性列表长度 //利用循环输出属性列表 for(int i=0;i"); } /** *//** * 元素中字符数据事件:接收元素中字符数据 * 注意:1.应用程序不要试图读取ch数组指定范围外的数据,(即start至length之外) * 2.有些解析器将使用ignorableWhitespace()方法来报告元素内容中的空白,而不是characters()方法,如:进行有效性验证的解析器 */ public void characters(char[] ch, int start, int length) throws SAXException http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 21 / 99 页 { System.out.print(new String(ch,start,length)); } /** *//** * 结束元素事件 */ public void endElement(String uri, String localName, String qName) throws SAXException { System.out.print(""); } public void endDocument() throws SAXException { } public void endPrefixMapping(String prefix) throws SAXException { } public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException { } public void setDocumentLocator(Locator locator) { } public void skippedEntity(String name) throws SAXException { } http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 22 / 99 页 public void startPrefixMapping(String prefix, String uri) throws SAXException { } } ErrorHandlerImpl.java public class ErrorHandlerImpl implements ErrorHandler { public void warning(SAXParseException e) throws SAXException { System.out.println("[Warning ]"+getLocationString(e)+":"+e.getMessage()); } public void error(SAXParseException e) throws SAXException { System.out.println("[Error ]"+getLocationString(e)+":"+e.getMessage()); } public void fatalError(SAXParseException e) throws SAXException { System.out.println("[Fatal Error ]"+getLocationString(e)+":"+e.getMessage()); } private String getLocationString(SAXParseException e) { StringBuffer sb=new StringBuffer(); String publicId=e.getPublicId(); if(publicId!=null) { sb.append(publicId); sb.append(" "); } http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 23 / 99 页 String systemId=e.getSystemId(); if(systemId!=null) { sb.append(systemId); sb.append(" "); } sb.append(e.getLineNumber()); sb.append(":"); sb.append(e.getColumnNumber()); return sb.toString(); } } SaxParserTest.java import java.io.FileInputStream; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; public class SaxParserTest { public static void main(String[] args) { try { XMLReader xmlReader=XMLReaderFactory.createXMLReader(); //关闭或打开验证 xmlReader.setFeature("http://xml.org/sax/features/validation",true); //注册事件处理器 xmlReader.setContentHandler(new ContentHandlerImpl()); //注册异常处理器 xmlReader.setErrorHandler(new ErrorHandlerImpl()); xmlReader.parse(new InputSource(new FileInputStream("saxdb.xml"))); http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 24 / 99 页 } catch (Exception e) { System.out.println(e.getMessage()); } } } 第二种:DOM解析 DOM中的核心概念就是节点。DOM在分析XML文档时,将将组成XML文档的各个部分(元素、属性、文本、注 释、处理指令等)映射为一个对象(节点)。在内存中,这些节点形成一课文档树。整棵树是一个节点,树中的每 一个节点也是一棵树(子树),可以说,DOM就是对这棵树的一个对象描述,我们通过访问树中的节点来存取 XML文档的内容。 PS:属性节点是附属于元素的,不能被看做是元素的子节点,更不能作为一个单独的节点 DOMPrinter.java import org.w3c.dom.Document; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import com.sun.org.apache.xerces.internal.parsers.DOMParser; public class DOMPrinter { public static void main(String[] args) { try { /** *//** 获取Document对象 */ DOMParser parser = new DOMParser(); parser.parse("db.xml"); Document document = parser.getDocument(); printNode(document); } catch (Exception e) { e.printStackTrace(); } http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 25 / 99 页 } public static void printNode(Node node) { short nodeType=node.getNodeType(); switch(nodeType) { case Node.PROCESSING_INSTRUCTION_NODE://预处理指令类型 printNodeInfo(node); break; case Node.ELEMENT_NODE://元素节点类型 printNodeInfo(node); printAttribute(node); break; case Node.TEXT_NODE://文本节点类型 printNodeInfo(node); break; default: break; } Node child=node.getFirstChild(); while(child!=null) { printNode(child); child=child.getNextSibling(); } } /** *//** * 根据节点类型打印节点 * @param node */ public static void printNodeInfo(Node node) { if (node.getNodeType() == Node.ELEMENT_NODE) { http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 26 / 99 页 System.out.println("NodeName: " + node.getNodeName()); } else if (node.getNodeType() == Node.TEXT_NODE) { String value = node.getNodeValue().trim(); if (!value.equals("")) System.out.println("NodeValue: " + value); else System.out.println(); }else { System.out.println(node.getNodeName()+" : "+node.getNodeValue()); } } /** *//** * 打印节点属性 * @param aNode 节点 */ public static void printAttribute(Node aNode) { NamedNodeMap attrs = aNode.getAttributes(); if(attrs!=null) { for (int i = 0; i < attrs.getLength(); i++) { Node attNode = attrs.item(i); System.out.println("Attribute: " + attNode.getNodeName() + "=\"" + attNode.getNodeValue()+"\""); } } } DOM生成XML文档:DOMCreateExample.java import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 27 / 99 页 import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import com.sun.org.apache.xml.internal.serialize.XMLSerializer; public class DOMCreateExample { public static void main(String[] args) throws ParserConfigurationException { //DOMImplementation domImp = DOMImplementationImpl.getDOMImplementation(); DocumentBuilderFactory builderFact = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFact.newDocumentBuilder(); Document doc = builder.newDocument(); //Document doc = domImp.createDocument(null, null, null); Element root = doc.createElement("games"); Element child1 = doc.createElement("game"); child1.appendChild(doc.createTextNode("Final Fantasy VII")); child1.setAttribute("genre", "rpg"); root.appendChild(child1); doc.appendChild(root); XMLSerializer serial; try { serial = new XMLSerializer(new FileOutputStream("domcreate.xml"), null); serial.serialize(doc); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e) http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 28 / 99 页 { e.printStackTrace(); } } } 第三种JDOM解析 JDOM利用了java语言的优秀特性,极大地简化了对XML文档的处理,相比DOM简单易用。JDOM也使用对象 树来表示XML文档,JDOM使用SAXj解析器来分析XML文档,构建JDOM树。然而JOMD本身并没有提供解析 器,它使用其他开发商提供的标准SAX解析器,JDOM默认通过JAXP来选择解析器,可以通过手动知道解析器 的类名来设置。 首先要在工程中添加jdom的jar包,这里使用jdom1.0.jar。(见附件) JDOMConvert.java import java.io.File; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; import org.jdom.output.XMLOutputter; public class JDOMConvert { public static void main(String[] args) { SAXBuilder saxBuilder=new SAXBuilder(); try { Document doc=saxBuilder.build(new File("domdb.xml")); //首先创建好节点 Element eltDb=new Element("db"); Element eltDriver=new Element("driver"); Element eltUrl=new Element("url"); Element eltUser=new Element("user"); Element eltPassword=new Element("password"); http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 29 / 99 页 //设置节点的值 eltDriver.setText("com.mysql.jdbc.Driver"); eltUrl.setText("jdbc:mysql://localhost/mySql"); eltUser.setText("root"); eltPassword.setText("xlc"); //添加到根节点 eltDb.addContent(eltDriver); eltDb.addContent(eltUrl); eltDb.addContent(eltUser); eltDb.addContent(eltPassword); //根节点设置属性 eltDb.setAttribute("type","mysql"); Element root=doc.getRootElement(); //root.removeChild("db");//删除节点 root.addContent(eltDb);//增加节点 //修改db节点中内容 root.getChild("db").getChild("user").setText("system"); root.getChild("db").getChild("password").setText("manager"); XMLOutputter xmlOut=new XMLOutputter(); //设置XML格式 Format fmt=Format.getPrettyFormat(); fmt.setIndent(" "); fmt.setEncoding("utf-8"); xmlOut.setFormat(fmt); xmlOut.output(doc,System.out); } catch (Exception e) { e.printStackTrace(); } http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 30 / 99 页 } } JDOM生成XML文档:JDOMCreate.java import java.io.IOException; import org.jdom.Document; import org.jdom.Element; import org.jdom.output.XMLOutputter; public class JDOMCreate { public static void main(String[] args) { Document doc = new Document(new Element("games")); Element newGame = new Element("game").setText("Final Fantasy VI"); doc.getRootElement().addContent(newGame); newGame.setAttribute("genre", "rpg"); XMLOutputter domstream = new XMLOutputter(); try { domstream.output(doc, System.out); } catch (IOException e) { e.printStackTrace(); } } } 第四种:DOM4J解析 dom4j与JDOM一样,也是一种用于解析XML文档的开放源代码的XML框架,dom4j也应用于java平台, dom4j API使用了java集合框架并完全支持DOM、SAX和JAXP。与JDOM不同的是,dom4j使用接口和抽象 类,虽然dom4j的API相对复杂些,但它提供了比JDOM更好的灵活性。dom4j也使用SAX解析器来分析XML文 档,创建dom4j树。此外dom4j也可以接收DOM格式的内容,并提供了从dom4j树到SAX事件流或W3C DOM 树的输出机制。与JDOM不同,dom4j自带了一个SAX解析器Aelfred2,如果没有显示的设置SAX解析器,也 没有通过系统属性org.xml.sax.driver设置解析器,dom3j将会使用JAXP来加载JAXP配置的解析器,如果创建 http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 31 / 99 页 解析器失败,那么最后才使用dom4j自带的Aelfred2解析器。 同样,首先要在工程中添加dom4j的jar包,这里使用dom4j-1.6.1.jar。(见附件) Dom4j生成XML文档db.xml:Dom4jCreate.java import java.io.IOException; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.XMLWriter; public class Dom4jCreate { public static void main(String[] args) { Document doc = DocumentHelper.createDocument(); doc.addProcessingInstruction("xml-stylesheet", "type='text/xsl' href='db.xsl'"); doc.addDocType("dbconfig", null,"db.dtd"); //Element root=DocumentHelper.createElement("dbconfig"); // doc.setRootElement(root); Element root = doc.addElement("dbconfig"); Element eltDb= root.addElement("db"); Element eltDriver = eltDb.addElement("driver"); Element eltUrl = eltDb.addElement("url"); Element eltUser = eltDb.addElement("user"); Element eltPassword = eltDb.addElement("password"); eltDriver.setText("com.mysql.jdbc.Driver"); eltUrl.setText("jdbc:mysql://localhost/mySql"); eltUser.setText("root"); eltPassword.setText("xlc"); eltDb.addAttribute("type","mysql"); http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 32 / 99 页 try { //设置输出格式 OutputFormat outFmt = new OutputFormat(" ", true); outFmt.setEncoding("UTF-8"); /**//*PrintWriter pw = new PrintWriter(System.out); doc.write(pw); pw.flush(); pw.close();*/ XMLWriter xmlWriter = new XMLWriter(System.out, outFmt); // XMLWriter xmlWriter=new XMLWriter(new FileWriter("db.xml"),outFmt); xmlWriter.write(doc); xmlWriter.flush(); xmlWriter.close(); } catch (IOException e) { e.printStackTrace(); } } } Dom4j修改XML文档db.xml:Dom4jModify.java import java.io.File; import java.io.FileWriter; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 33 / 99 页 public class Dom4jModify { public Document modifyDocument(File inputXml) { try { SAXReader saxReader = new SAXReader(); Document document = saxReader.read(inputXml); document.addDocType("dbconfig",null,"db.dtd"); List list = document.content(); // Iterator iter = document.nodeIterator(); Iterator iter = list.iterator(); Element element = (Element) iter.next(); element.element("db").attribute("type").setValue("mysql"); element.element("db").element("url").setText("jdbc:mysql://localhost/mySql"); element.element("db").element("driver").setText("com.mysql.jdbc.Driver"); element.element("db").element("user").setText("root"); element.element("db").element("password").setText("xlc"); // 设置输出格式 OutputFormat outFmt = new OutputFormat(" ", true); outFmt.setEncoding("UTF-8"); XMLWriter xmlWriter=new XMLWriter(new FileWriter("domdb-modified.xml"),outFmt); xmlWriter.write(document); xmlWriter.flush(); xmlWriter.close(); return document; } catch (Exception e) { System.out.println(e.getMessage()); return null; } } http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 34 / 99 页 public static void main(String[] args) throws Exception { Dom4jModify dom4jParser = new Dom4jModify(); Document document = dom4jParser.modifyDocument(new File("domdb.xml")); OutputFormat outFmt = new OutputFormat(" ", true); outFmt.setEncoding("UTF-8"); XMLWriter xmlWriter = new XMLWriter(System.out,outFmt); xmlWriter.write(document); xmlWriter.flush(); xmlWriter.close(); } } 附件下载: • jdom1.0.jar (147.5 KB) • http://hackiller.javaeye.com/topics/download/5733ae22-4f07-3779-b619-7156bf2afb51 • dom4j-1.6.1.jar (256.8 KB) • http://hackiller.javaeye.com/topics/download/9448a959-49b2-3735-bb13-2d2d4f4b7530 http://hackiller.javaeye.com 1.3 J2EE复习(二)XML(下)--xml解析 第 35 / 99 页 1.4 J2EE复习(三)JavaScript(上)--基础入门 发表时间: 2009-04-11 就我个人在学习和使用JavaScript过程中,感觉该语言逻辑很混乱,有时会出现莫名其妙的错误,并且没有很好 的开发工具,调试起来很是费神费时,然而在web开发中JavaScript充当着很重要的角色,令我很是苦恼,希望 可以通过长期的学习和编码积累经验从而得到进步。 JavaScript简介 JavaScript是一种基于对象的脚本语言,用于开发基于客户端和基于服务器的Internet应用程序 可用于创建客户端脚本和服务器端脚本 由Sun Microsystems 和 Netscape 开发,是从 Netscapes 的 Livescript 发展而来的 JavaScript数据类型 数字型 (Number) 整数或实数 逻辑型或布尔型 (boolean) true或false 字符串型(String) 如“Hello World”,“123.4” 空型 (null) 表示空值的特殊关键字 算术运算符 加+ 减- 乘* 除/ 取余% 一元递增++ 一元递减-- 比较运算符 等于:== 全等:=== 不等:!= 大于:> 大于等于:>= 小于:< 小于等于:<= PS:全等=== 比较的是数据类型和值,只有两个都相等时才返回true。 逻辑运算符 逻辑与:&& 逻辑或:|| 逻辑非:! PS:JavaScript中没有&逻辑运算符 条件运算符:(condition) ? trueVal : falseVal ;例子:status = (age >= 18) ? "adult" : "minor" typeof运算符:typeof 运算符返回字符串,该字符串代表操作数的类型; JavaScript数组 有两种向数组赋值的方法(你可以添加任意多的值,就像你可以定义你需要的任意多的变量一样)。 var mycars=new Array(); mycars[0]="Saab"; mycars[1]="Volvo"; mycars[2]="BMW"; http://hackiller.javaeye.com 1.4 J2EE复习(三)JavaScript(上)--基础入门 第 36 / 99 页 也可以使用一个整数自变量来控制数组的容量: var mycars=new Array(3); mycars[0]="Saab"; mycars[1]="Volvo"; mycars[2]="BMW"; 还有一种定义方式 var mycars=new Array("Saab","Volvo","BMW"); 在访问数组是同java一样的,mycars[0],下标也是从0开始。 数组方法和属性 使用concat() 方法来合并两个数组。 使用join() 方法将数组的所有元素组成一个字符串。 使用sort() 方法从字面上或数值上对数组进行排序。 JavaScript数组也有length属性 JavaScript多维数组 MyArray = new Array(5,5); MyArray[0, 0] = "Ryan Dias"; MyArray[0, 1] = 1; MyArray[1, 0] = "Mike Donne"; MyArray[1, 1] = 2; JavaScript try...catch throw使用 如果 x 的值大于 10 或者小于 0,错误就会被抛出 (throw)。这个错误被 catch 的参数捕获后,就会显示出自 定义的出错信息。 JavaScript for...in语句使用 for … in语句用于在对象的各个属性,或数组的各个元素之间循环 JavaScript new语句使用 new操作符用于新建对象类型实例。 JavaScript with语句使用 with语句用于执行一组语句,所有这些语句都假定引用指定的对象。 JavaScript 字符串对象 字符串对象示例 http://hackiller.javaeye.com 1.4 J2EE复习(三)JavaScript(上)--基础入门 第 39 / 99 页 字符串左右两端空格处理方法 js String Object JavaScript RegExp(正则表达式)对象 /**语法1 re = new RegExp("pattern",["flags"]); 语法2 re = /pattern/[flags]; 可选项。如果使用语法 2 要用引号将 flag 引起来。标志可以组合使用,可用的有: g (全文查找出现的所有 pattern) i (忽略大小写) m (多行查找)*/ var pattern1 = new RegExp("e","g"); var pattern2 = new RegExp(/^[1-9]\d*$/); var pattern3 = /^[1-9]\d*$/; http://hackiller.javaeye.com 1.4 J2EE复习(三)JavaScript(上)--基础入门 第 41 / 99 页 RegExp 对象有 3 个方法:test()、exec() 以及 compile()。 test() 方法检索字符串中的指定值。返回值是 true 或 false,一般在检查字符串的合法性时使用,如检查输入值 是否为正浮点数。 exec() 方法检索字符串中的指定值。返回值是被找到的值。如果没有发现匹配,则返回 null。 compile() 方法用于改变 RegExp,如果不太清楚请看下面的例子。 JavaScript---获取事件信息 JavaScript中:window.event或event对象获取事件信息调用其keyCode获取按键的键位号 event.keyCode ---- 返回对应键位的值 event.shiftKey ---- 如果触动了shift键则返回true event.ctrlKey ---- 如果触动了ctrl键则返回true event.altKey ---- 如果触动了alt键则返回true HTML事件 onClick ---单击事件 ondblclick---鼠标双击 onMouseDown --- 鼠标按下 onMouseUp---鼠标弹起 oncontextmenu---鼠标右击 http://hackiller.javaeye.com 1.4 J2EE复习(三)JavaScript(上)--基础入门 第 42 / 99 页 onChange --- 值改变事件 onFocus --- 获取焦点 onBlur --- 失去焦点 onMouseOver---鼠标移动 onMouseOut ---鼠标离开 onLoad ---加载事件 onSubmit ---提交事件 Navigator 对象的属性 appCodeName 返回浏览器的代码名。 appMinorVersion 返回浏览器的次级版本。 appName 返回浏览器的名称。 appVersion 返回浏览器的平台和版本信息 browserLanguage 返回当前浏览器的语言。 cookieEnabled 返回指明浏览器中是否启用 cookie 的布尔值。 cpuClass 返回浏览器系统的 CPU 等级。 onLine 返回指明系统是否处于脱机模式的布尔值。 platform 返回运行浏览器的操作系统平台。 Navigator 对象的方法 javaEnabled() 规定浏览器是否启用 Java。 Window对象的属性: closed 返回窗口是否已被关闭。 defaultStatus 设置或返回窗口状态栏中的默认文本。 document 对 Document 对象的只读引用。 history 对 History 对象的只读引用。 length 设置或返回窗口中的框架数量。 location 用于窗口或框架的Location 对象。 name 设置或返回窗口的名称。 Navigator 对 Navigator 对象的只读引用。 opener 返回对创建此窗口的窗口的引用。 outerheight 返回窗口的外部高度。 outerwidth 返回窗口的外部宽度。 parent 返回父窗口。 Screen 对 Screen 对象的只读引用。 self 返回对当前窗口的引用。等价于 Window 属性。 http://hackiller.javaeye.com 1.4 J2EE复习(三)JavaScript(上)--基础入门 第 43 / 99 页 status 设置窗口状态栏的文本。 top 返回最顶层的先辈窗口。 window window 属性等价于 self 属性,它包含了对窗口自身的引用。 Window对象的方法: alert(信息字串) 弹出警告信息 confirm(信息字串) 显示确认信息对话框 prompt(提示字串[,默认值]) 显示提示信息,并提供可输入的字段 atob(译码字串) 对base-64编码字串进行译码 btoa(字串) 将进行base-64编码 back() 回到历史记录的上一网页 forward() 加载历史记录中的下一网页 open(URL,窗口名称[,窗口规格]) close() focus() 焦点移到该窗口 blur() 窗口转成背景 stop() 停止加载网页 enableExternalCapture() 允许有框架的窗口获取事件 disableExternalCapture() 关闭enableExternalCapture() captureEvents(事件类型) 捕捉窗口的特定事件 routeEvent(事件) 传送已捕捉的事件 handleEvent(事件) 使特定事件的处理生效 releaseEvents(事件类型) 释放已获取的事件 moveBy(水平点数,垂直点数) 相对定位 moveTo(x坐标,y坐标) 绝对定位 home() 进入浏览器设置的主页 find([字串[,caseSensitivr,backward]]) 查找窗口中特定的字串 print() 打印当前窗口的内容。 setHotKeys(true|false) 激活或关闭组合键 setZOptions() 设置窗口重叠时的堆栈顺序 setInterval(表达式,毫秒) setTimeout(表达式,毫秒) clearInterval(定时器对象) clearTimeout(定时器对象) showModalDialog() 弹出模态窗体,通过window.dialogArguments获取父窗体传过来的值,通过 window.returnValue给父窗体传值。 http://hackiller.javaeye.com 1.4 J2EE复习(三)JavaScript(上)--基础入门 第 44 / 99 页 Document 对象的属性 body 提供对 元素的直接访问。对于定义了框架集的文档,该属性引用最外层的 。 cookie 设置或返回与当前文档有关的所有 cookie。 domain 返回当前文档的域名。 lastModified 返回文档被最后修改的日期和时间。 referrer 返回载入当前文档的文档的 URL。 title 返回当前文档的标题。 URL 返回当前文档的 URL。 Document 对象的方法 close() 关闭用 document.open() 方法打开的输出流,并显示选定的数据。 getElementById() 返回对拥有指定 id 的第一个对象的引用。 getElementsByName() 返回带有指定名称的对象集合。 getElementsByTagName() 返回带有指定标签名的对象集合。 open() 打开一个流,以收集来自任何 document.write() 或 document.writeln() 方法的输出。 write() 向文档写 HTML 表达式 或 JavaScript 代码。 writeln() 等同于 write() 方法,不同的是在每个表达式之后写一个换行符。 Location 对象的属性 hash 设置或返回从井号 (#) 开始的 URL(锚)。 host 设置或返回主机名和当前 URL 的端口号。 hostname 设置或返回当前 URL 的主机名。 href 设置或返回完整的 URL。 pathname 设置或返回当前 URL 的路径部分。 port 设置或返回当前 URL 的端口号。 protocol 设置或返回当前 URL 的协议。 search 设置或返回从问号 (?) 开始的 URL(查询部分)。 Location 对象的方法 assign() 加载新的文档。 reload() 重新加载当前文档。 replace() 用新的文档替换当前文档。 History 对象的属性 length 返回浏览器历史列表中的 URL 数量 http://hackiller.javaeye.com 1.4 J2EE复习(三)JavaScript(上)--基础入门 第 45 / 99 页 History 对象的方法 back() 加载 history 列表中的前一个 URL forward() 加载 history 列表中的下一个 URL go() 加载 history 列表中的某个具体页面 http://hackiller.javaeye.com 1.4 J2EE复习(三)JavaScript(上)--基础入门 第 46 / 99 页 1.5 J2EE复习(三)JavaScript(下)--实战应用 发表时间: 2009-04-11 本人在学习和做项目中常用的js函数汇总. 一、用js做的表格动态增删查改 工具JavaScript:util.js //全选反选 function checkAll(boxName) { var checkBox = document.getElementsByName(boxName); for (i = 0; i < checkBox.length; i++) { var checked = checkBox[i].checked; if (checked) { checkBox[i].checked = false; } else { checkBox[i].checked = true; } } } //多选验证 function multiCheck(idArray) { //var idArray = document.getElementsByName(boxName); var count = 0; for(i=0;i 学生信息

                 
      http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 51 / 99 页 学生信息列表页面(list.html),此页面内嵌在studentInfo.html中 学生信息列表 http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 52 / 99 页
      07级学生信息列表
      [全选/反选] 学号 姓名 性别 年龄 学校 手机
      430901 hackiller 21 中南林业科技大学涉外学院 12345678901
      更新学生信息对话框页面(dialog.html),用于添加和修改表格 http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 53 / 99 页 更新学生信息 http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 55 / 99 页
      学号
      姓名
      性别 男   
      年龄
      学校
      手机
        
      二、在学习和做项目过程中写的JavaScript验证函数(正则表达式) http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 56 / 99 页 //身份证合法性 function isIdentity(new_num) { var num = new_num; var len = num.length ; var re ; if (len == 15) { if (isNaN(num)) {alert("输入的不是数字!"); return false;} } if (len == 15) re = new RegExp(/^(\d{6})()?(\d{2})(\d{2})(\d{2})(\d{3})$/); else if (len == 18) re = new RegExp(/^(\d{6})()?(\d{4})(\d{2})(\d{2})(\d{3})(\d|[X])$/); else { alert("输入的数字位数不对!"); return false;} var a = num.match(re); if (a != null) { if (len==15) { var D = new Date("19"+a[3]+"/"+a[4]+"/"+a[5]); var B = D.getYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5]; } else { var D = new Date(a[3]+"/"+a[4]+"/"+a[5]); var B = D.getFullYear()==a[3]&&(D.getMonth()+1)==a[4]&&D.getDate()==a[5]; } if (!B) {alert("输入的身份证号 "+ a[0] +" 里出生日期不对!"); return false;} }else { alert("输入的身份证号不对!"); return false; } return true; } //电子邮箱的合法性 http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 57 / 99 页 function checkemail(email) { var myReg = /^([-_A-Za-z0-9\.]+)@([_A-Za-z0-9]+\.)+[A-Za-z0-9]{2,3}$/; if(!myReg.test( email )) { alert("请输入合法的电子邮件地址"); return false; } return true; } //验证邮政编码 function checkPostcode(postcode) { var reobj = new RegExp(/^\d+$/); if(!reobj.test(postcode)||!postcode.length!=6) { alert("请输入正确的邮政编码"); return false; } return true; } //价格验证 function checkPrice(price) { var float = /^\d+(.){0,1}?\d{0,2}$/;//两位小数 var int = /^[1-9]\d*$/;//正整数 if(!float.test(price)&&!int.test(price)) { alert("请输入正确的商品价格"); return false; } return true; } //验证上传图片类型 function valiImgType(fileName) { var extension = fileName.substring(fileName.lastIndexOf(".")+1,fileName.length).toLowerCase(); http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 58 / 99 页 if(extension!="jpg"&&extension!="gif") { alert("请选择jpg或gif格式的图片"); return false; } return true; } //验证是否为中文 function iszhCN(name) { var Expression=/[^\u4E00-\u9FA5]/; var objExp=new RegExp(Expression); if(!/^[\u4e00-\u9fa5]+$/.test(name)) { alert("请输入汉字,验证未通过"); return false; } return true; } //验证IP地址 function checkIP(sIPAddress) { var exp=/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/; var reg = sIPAddress.match(exp); var ErrMsg="你输入的是一个非法的IP地址段!\nIP段为::xxx.xxx.xxx.xxx(xxx为0-255)!" if(reg==null) { alert(ErrMsg); return false; } return true; } 三、在学习和做项目过程中写的常用JavaScript函数 http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 59 / 99 页 //四舍五入,保留valiNumber个小数; function round(number,valiNumber) { document.write(number.toFixed(valiNumber)); } // 判断字符串长度,一个中文按两个字符算 function strlen(str) { var len; var i; len = 0; for (i=0;i255) len+=2; else len++; } return len; } 四、用JavaScript限制html输入框为整数 http://hackiller.javaeye.com 1.5 J2EE复习(三)JavaScript(下)--实战应用 第 60 / 99 页 1.6 J2EE复习(四)servlet 发表时间: 2009-04-12 一、什么是Servlet? Servlet 是在服务器上运行来响应客户端请求的一种java组件。Servlet与具体的客户服务端协议无关,但 Servlet常用于HTTP协议,所以,“Servle”t常被用于“HTTP Servlet”的意思。 Servlet使用的java软件包:javax.servlet(基本Servlet框架)和javax,servlet.http(HTTP Servlet) HTTP Servlets典型应用包括: 1.通过提交HTML表单操作存储数据。 2.提供动态内容,如将从数据库中查询到的结果返回给客户端 3.管理无状态的HTTP上的有状态的信息,如一个为多个同时存在的客户管理购物车并映射每一个请求到正确的 客户的在线购物系统 二、Servlets 和 CGI(Commone Gateway Interface) 最早用来产生动态网页服务的方法便是CGI,CGI是一种与语言无关的接口,此种接口允许服务器启动通过环境变 化来获取与此次请求有关信息的外部程序。每一个请求都通过CGI程序或者CGI脚本由单独的线程响应。 Servlets相比CGI的几个优势: 1.Servlet中,每个请求由一个轻量级的Java线程处理,不用为每一个请求启动新的系统线程。 2.一个Servlet在请求期间会驻留在内存中。 3.响应所有并发的请求只需要唯一一个实例,节省了内存并可以使Servlet管理持久数据显得更快捷。 三、Servlet 生命周期 Servlet 的生命周期就是指创建 Servlet 实例之后其存在的时间以及何时消失 生命周期的 3个方法为:init()、service()、destroy() 1.装载servlet类以及其他可能使用到的类 2.调用init(ServletConfig config)方法加载配置信息,初始化servlet 3.调用service(doGet/doPost)方法处理业务逻辑,service方法在初始化前不会被调用 4.调用destroy方法销毁不再使用的servlet 四、Servlet的部署 1.用myeclipse建立好web工程,写好HelloClientServlet.java类 import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloClientServlet extends HttpServlet { //doGet() 方法处理客户端作出的 GET 请求。 http://hackiller.javaeye.com 1.6 J2EE复习(四)servlet 第 61 / 99 页 public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("Hello Client!"+ "Hello Client!"); out.close(); } //doPost() 方法处理客户端作出的 POST 请求。 public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { doGet(req,res); } } 2.web.xml文件中配置Servlet firstServlet HelloClientServlet的包路径 firstServlet /first.do 3.发布到本机web服务器(使用Tomcat5.5)中,通过http://localhost:服务器端口号/工程名/first.do启动 servlet。 五、javax.servlet 包的接口介绍 http://hackiller.javaeye.com 1.6 J2EE复习(四)servlet 第 62 / 99 页 ServletConfig 用来封装web.xml中对当前Servlet的配置信息 getInitParameter()---可以获取初始化参数 ServletContext 代表当前Servlet运行的上下文环境,Web容器会为每一个Web工程创建一个对应ServletContext对象 setAttribute() getAttribute() removeAttribute() ServletRequest 为Servlet所发送的请求,用ServletRequest封装 setAttribute() getAttribute() removeAttribute() getParameter() 常用子接口HttpServletRequest ServletResponse Servlet对客户段所做的响应,用ServletResponse描述 getWriter():获取PrintWriter输出流给客户发送的响应内容 setContentType:设置响应内容的响应类型和字符集信息 sendRedirect:设置重新请求路径 子接口HttpServletResponse 六、过滤器(Filter) 1.Servlet 过滤器是小型的 Web 组件,它们拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和 服务器之间交换的数据。 2.生命周期 初始化----当容器第一次加载该过滤器时, init() 方法将被调用。 过滤----doFilter() 方法被容器调用,同时传入分别指向这个请求/响应链中的ServletRequest 、 ServletResponse 和 FilterChain 对象的引用 销毁----容器紧跟在垃圾收集之前调用 destroy() 方法 3.编写字符编码过滤器 (1)实现Filter接口中的三个方法: init() ----这个方法在容器实例化过滤器时被调用 doFilter() ----与 servlet 拥有一个 service() 方法(这个方法又调用 doPost() 或者 doGet() )来处理请求一 样,过滤器拥有单个用于处理请求和响应的方法―― doFilter()。 destroy() ---这个方法执行任何清理操作,这些操作可能需要在自动垃圾收集之前进行 http://hackiller.javaeye.com 1.6 J2EE复习(四)servlet 第 63 / 99 页 import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class CharacterEncodingFilter implements Filter { private String encode; public void destroy() { this.encode = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if(encode!=null) { request.setCharacterEncoding(encode); response.setCharacterEncoding(encode); } // 将资源链到下一Filter, 如果这是最后一个Filter, 则将资源链到目的位置. chain.doFilter(request, response); } public void init(FilterConfig config) throws ServletException { encode = config.getInitParameter("encode"); System.out.println("CharacterEncoding...encode="+encode); } http://hackiller.javaeye.com 1.6 J2EE复习(四)servlet 第 64 / 99 页 } (2)web.xml文件中配置字符编码过滤器 encodeFilter CharacterEncodingFilter全路径 encode utf-8 encodeFilter /* 七、监听器(ServletContextListener) 1.ServletContext相关监听接口 (1)javax.servlet.ServletContextListener:监听WEB应用,当应用开始的时候它会调用contextInitialized()方 法,当应用关闭的时候,它同样会调用contextDestroyed()方法 (2)javax.servlet.ServletContextAttributeListener:用于监听WEB应用属性改变的事件,包括:增加属性、删 除属性、修改属性 2.HttpSession相关监听接口 (1)javax.servlet.http.HttpSessionListener:监听HttpSession的操作。当创建一个Session时,激发session Created(HttpSessionEvent se)方法;当销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se) 方法。 (2)avax.servlet.http.HttpSessionBindingListener: 注意:HttpSessionBindingListener接口是唯一不需要再web.xml中设定的Listener 当我们的类实现了HttpSessionBindingListener接口后,只要对象加入Session范围(即调用HttpSession对象 的setAttribute方法的时候)或从Session范围中移出(即调用HttpSession对象的removeAttribute方法的时 候或Session Time out的时候)时,容器分别会自动调用下列两个方法: void valueBound(HttpSessionBindingEvent event) void valueUnbound(HttpSessionBindingEvent event) http://hackiller.javaeye.com 1.6 J2EE复习(四)servlet 第 65 / 99 页 (3)avax.servlet.http.HttpSessionAttributeListener:监听HttpSession中的属性的操作。 当在Session增加一个属性时,激发attributeAdded(HttpSessionBindingEvent se) 方法;当在Session删除一 个属性时,激发attributeRemoved(HttpSessionBindingEvent se)方法;当在Session属性被重新设置时,激 发attributeReplaced(HttpSessionBindingEvent se) 方法。 3.写一个统计在线用户的例子 (1)建立CunterListstener.java类 import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; public class CunterListstener implements HttpSessionListener { public static int count; public void sessionCreated(HttpSessionEvent arg0) { count++; } public void sessionDestroyed(HttpSessionEvent arg0) { if(count>0) count--; } } (2)建立index.jsp,查看在线人数 <%@ page language="java" pageEncoding="UTF-8"%> 站点计数监听器

      站点计数监听器


      当前在线人数:<%=CunterListener.count%> http://hackiller.javaeye.com 1.6 J2EE复习(四)servlet 第 66 / 99 页 3.在web.xml文件中配置监听器 CunterListstener全路径 4.发布工程到Tomcat上,进入index.jsp网页 ,看到网页内容: 当前在线人数:1。代表的是只有自己在线。 九、Cookie Cookie 用于存储 Web 服务器发送给客户端的信息。服务器通过设置响应标题中的 Set-Cookie 方法来发送 cookie。javax.servlet.http.Cookie类方法: getComment/setComment 获取/设置Cookie的注释。 getDomain/setDomain 获取/设置Cookie适用的域。 getMaxAge/setMaxAge 获取/设置Cookie过期之前的时间,以秒计。 getName/setName 获取/设置Cookie的名字。 getPath/setPath 获取/设置Cookie适用的路径。 getSecure/setSecure 获取/设置一个boolean值,表示是否Cookie只能通过加密的连接(即SSL)发送。 getValue/setValue 获取/设置Cookie的值。 getPath()返回的如果不指定路径,Cookie将返回给当前页面所在目录及其子目录下的所有页面。这里的方法可 以用来设定一些更一般的条件。例如,someCookie.setPath("/"),此时服务器上的所有页面都可以接收到该 Cookie。 如果不设置Cookie的过期时间,则Cookie只在当前会话内有效,即在用户关闭浏览器之前有效,而且这些 Cookie不会保存到磁盘上。 通过HttpServletResponse的addCookie方法加入。 Cookie userCookie = new Cookie("userName", "hackiller"); response.addCookie(userCookie); 由于HttpServletRequest的getCookies方法返回的是一个Cookie对象的数组,因此通常要用循环来访问这个 数组查找特定名字,然后用getValue检查它的值。 http://hackiller.javaeye.com 1.6 J2EE复习(四)servlet 第 67 / 99 页 //获取指定名字的Cookie值 public static String getCookieValue(Cookie[] cookies,String cookieName,String defaultValue) { for(int i=0; i,…)。 JSP是以Java和Servlet为基础开发而成的动态网页生成技术,它的底层实现是Java Servlet。 JSP页面由HTML代码和嵌入其中的Java代码所组成。服务器在页面被客户端所请求以后对这些Java代码进行处 理,然后将生成的HTML页面返回给客户端的浏览器。 二、JSP的执行过程 客户端请求JSP页面——>JSP Parser解析*.jsp编译为*.java——>javac命令编译成*.class——>执行class文件 ——>响应返回结果给客户端 JSP代码中包含JSP元素和Template data两类。Template data指的是JSP引擎不处理的部分,就是JSP引擎会 把除在标记<%...%>以外的部分直接传递出去而不进行任何处理。 JSP在第一次或修改JSP文件后执行都会调用JSP Parser将*.jsp文件编译成servlet程序,所以会比较慢。 三、JSP基本语法 1. 两种注释类型 (1)HTML注释 可以在JSP代码中添加一段HTML格式的注释,此注释发生到客户端,但不在页面上显示,语法如下: 如果programmer为hackiller,则在客户端返回的注释是 (2)JSP注释 写在JSP代码中,但不发送到客户端。 <%-- JSP注释,该注释会在JSP编译时被忽略掉 --%> <%-- /*Scriptlet中的多行注释*/ --%> <%-- /**Scriptlet中的多行注释,可以用javadoc从java文件中提取出来*/ --%> <%-- JSP的单行注释 --%> 2. 3个脚本元素 (1)声明(Declaration)全局变量 http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 70 / 99 页 <%! int i=0; String str="Hello World!"; %> (2)表达式(Expression) 在JSP代码中,经常使用表达式来输出变量的值,可以在任何地方 <%! int a=1; int b=2; String str="Hello World!"; %> <%=a+b%> <%=str> PS:不能用“;”号来作为表达式的结束符。但同样的表达式在Scriptlet中必须以分号来结尾。 (3)脚本段(Scriptlet) 脚本段用来包含一个有效地Java程序段 <% int b=3; %>局部变量 3. 3个指令元素 (1)page指令 <%@ page contentType="text/html;charset=utf-8"%> 定义JSP文件的全局属性,属性包括:language、extends、import、session、buffer、autoflush、 isThreadSafe、info、errorPage、isErrorPage、contentType(服务端到客户端的输出格式) 其位置可以在页面的任何位置,但推荐放在页首。 language:声明脚本语言的种类,目前只能用"java"。 extends:标明JSP编译时需要加入的Java Class的全名,它会限制JSP的编译能力,慎用! import:需要导入的java包列表。 session:设定客户是否需要HTTP Session。默认为true。 buffer:buffer的大小被out对象用于处理执行后的JSP对客户浏览器的输出。默认值为8Kb。 autoFlush:设置如果buffer溢出,是否要强制输出,如果定义其为true(默认值),输出正常;如果定义为 false,会导致一个意外错误的发生。 isThreadSafe:设置JSP文件是否能多线程使用。默认为true。 info:文本信息。能够使用Servlet.getServletInfo()方法取回。 errorPage:设置处理异常事件的JSP文件 sErrorPage:设置此页是否为处理异常事件的页面,如果设置为true,就能使用exception对象。 contentType:设置MIME类型和字符编码集。MIME类型默认为text/html,字符集默认为 charset=ISO-8859-1。 可以在一个页面中使用多个<%@page %>指令,但是除了import属性,其他的属性只能使用一次。 JSP缺省引入的包,下面这些包在JSP编译时已经导入了,所以在JSP文件中无需再用page指令引入: java.lang.* javax.servlet.* javax.servlet.jsp.* javax.servlet.http.* http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 71 / 99 页 (2)include指令 <%@ include file = "相对路径" %> 使用include指令可以在JSP中包含一个静态的文件,同时解析这个文件中JSP语句。 如果路径以“/”开头,那么此路径主要是参照jsp应用的上下文关系路径。 如果路径以文件名或文件目录开通,那么此路径就是正在使用的JSP文件的当前路径。 (3)taglib指令 <%@ taglib uri = "TagLibrary" prefix = "mypfx" %> 是用taglib指令定义一个标签库及其自定义的前缀。 uri:Uniform Resource Identifier根据标签的前缀对自定义的标签进行唯一的命名,可以是一个相对或绝对的 路径 prefix:自定义标签的前缀。不要使用jsp、jspx、java、javax、servlet、sun、sunw作为前缀,这些已被Sun 公司声明保留。 4. 8个动作指令 (1)页面跳转: 标签从一个jsp文件向另外一个文件传递一个包含用户请求的request对象。 共包含2个属性 page属性是一个表达式或是一个字符串用于说明将要定向的文件或URL。 向一个动态文件发送一个或多个参数。如果使用了标签,目标文件必须是动态的文 件(如Servlet或者JSP等) 通过request.getParameter("username")获取用户名 (2)包含页面: 允许包含静态和动态Web资源,这两种包含的结果是不同的。 如果包含的仅是静态文件,那么这种包含仅仅是把包含文件的内容加到JSP文件中去,类似于<%@include%>; http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 72 / 99 页 如果包含的是动态web资源,那么这个被包含的文件也会被JSP编译器执行。 如果这个包含文件是动态的,那么还可以使用 创建一个Bean实例并指定她的名字和作用范围。 包含5个属性。 id:在所定义的范围中确认Bean的变量,程序中用id来使用此Bean实例。id的值对大小写敏感。 scope:Bean存在的范围及id变量名的有效范围。默认值为page。 class:使用new关键字及class构造器从一个class中实例一个bean。这个class不能是抽象的,并且必须有一个 公用的,没有参数的构造器。 type:如果这个Bean已经指定范围中存在,使用type将赋予这个Bean一个数据类型。如果使用type的同时没 有使用class或beanName,Bean将不会被实例化。 beanName:beanName可以是字符串的package.class,也可以是jsp表达式,它的值会传递给 Beans.instantiate方法。type的值可以与beanName相同也可以是它的基类,或者是它所实现的接口。 (4)设置Bean属性: name:表示已经在中创建的Bean实例的名字,即id。 property:匹配Bean中的属性 param:指request对象中的参数名,将对应的值设定给Bean的属性。 value:使用指定的值来设定Bean属性。这个值可以是字符串,也可以是表达式。如果是字符串,那么就会被转 换成Bean属性的类型(如"0.98"会转化成double类型0.98)。如果是表达式,则要求它的类型与Bean属性的类型 一致。 PS:在同一个中不能同时使用param属性和value属性 (5)取得Bean属性: 获取已经存在的Bean对象中的属性值,在页面中显示。 name:与存在的对象实例的名字相同。 property:对象中属性名 (6)使用Applet插件: http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 73 / 99 页

      Unable to load applet!

      使用插入一个applet或Bean,必要的话还要下载一个Java插件用于执行它。 (7)定义参数: 可以在中使用。 (8)插件错误提示:插件不能够正常显示时显示提示信息。 三、JSP内置对象 1. Request:请求对象 该对象封装了用户提交的信息,通过调用该对象相应方法可以获取封装的信息。 当request对象获取客户提交的汉字字符是,会出现乱码,必须进行特殊处理。 常用方法: getParameter(String parameterName):获取表单提交的信息。 getProtocol():获取客户使用的协议。 getServletPath():获取客户提交信息的页面。 getMethod():获取客户提交信息的方式。 getHeader(String str):获取HTTP头文件中的accept、accept-encoding和Host的值。 getRermoteHost():获取客户的IP地址。 getServerName:获取服务器名称。 getServerPort:获取服务器的端口号。 getParameterNames():获取客户段提交的所有参数的名字。 2. Response:响应对象 对客户的请求做出动态的响应,向客户端发生数据。 (1)动态响应contentType属性 用page指令静态地设置页面的contentType属性,动态设置这个属性时使用response.setContextType("text/ http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 74 / 99 页 html;charset=utf-8"); (2)Response重定向 response.sendRedirect("index.jsp"); 3. Session:会话对象 (1)什么是Session对象? Session对象在第一个JSP页面被装载时自动创建,完成会话期管理。 从一个客户打开浏览器并连接到服务器开始,到客户关闭浏览器离开这个服务器结束,被称为一个会话。 (2)Session对象的ID 当一个客户首次访问服务器上的一个JSP页面时,JSP引擎产生一个Session对象,同时分配一个String类型的ID 号,JSP引擎同时将这个ID号发送到客户端,存放在Cookie中,这样Session对象,直到客户关闭浏览器后服务 器端改该客户的Session对象才取消,并且和客户的会话对应关系消失。 (3)常用方法 public String getId():获取Session对象的编号。 public void setAttribute(String str,Object obj):将参数对象添加到Session对象中。 public Object getAttribute():根据属性名获取在Session对象中的属性。 public boolean isNew():判断是否是一个新的客户。 4. Application:应用程序对象 (1)什么是Application对象? 在服务器启动后就产生了这个Application对象,当客户在所访问的网站的各个页面之间浏览时,这个 Appliaction对象都是同一个,所有的客户共享这个内置的Application对象。 (2)常用方法 setAttribute(String key,Object obj):将参数对象添加到Application对象中。 getAttibute(String key):根据属性名获取Application对象中的属性 5. Out:输出对象 out对象是一个输出流,用来向客户输出数据。 out.print():输出各种类型数据。 out.newLine():输出一个换行符。 out.close():关闭流。 http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 75 / 99 页 6. Config:配置对象 一般我们使用Config对象获取一些初始化配置信息,常用的方法有getInitParameter和 getInitParameterNames,以获得Servlet初始化时的参数。 7.Page:页面对象 page对象代表了正在运行的由JSP文件产生的类对象,不建议一般读者使用。 8.PageContext:页面上下文对象 JSP引入的PageContext的类,通过它可以访问页面的许多属性。pageContext变量存储与当前页面相关联的 PageContext对象的值。PageContext类拥有getRequest、getResponse、getOut、getSession等方法。 9.Exception:例外对象 exception对象代表了JSP文件运行时所产生的例外对象,此对象不能在一般的JSP文件中直接使用,而只能在使 用了 <%@page isErrorPage="true"%>的JSP文件中使用。这是因为JSP文件运行时产生的错误对象被向外抛出, 只能被使用了<%@page isErrorPage="true"%>标记从而具有拦截错误对象功能的JSP所拦截。最常用的方法 就是getMessage,用来获取错误信息。 四、实例 登陆页面:index.jsp <%@ page language="java" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %> 系统登录
      http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 77 / 99 页
      系统登录
      http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 78 / 99 页
      用户名 密码
      接收数据页面:receive.jsp <%@ page language="java" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" info="动作标签"%> http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 79 / 99 页 This is my JSP page.

      用<jsp:getProperty>获取表单中提交过来的值
      name:
      password:


      <% out.println("从vo对象中直接获取:
      name:"+userVo.getName()+ "
      password:"+userVo.getPassword()+"
      "); String serviceName = request.getServerName();//1.jsp内部的request对象 out.println("

      服务器名: "+serviceName); out.println("
      MIME类型: "+response.getContentType());//2.jsp内部的response对象 session.setAttribute("sessionName","jsp内部的session对象");//3.jsp内部的session对象 out.println("
      session对象: "+session.getAttribute("sessionName"));//4.jsp内部的out对象 pageContext.setAttribute("pageContext","上下文环境的引用");//5.jsp内部的pageContext对象 //6. application //7. config ServletConfig的实例 //8. page java.lang.Object的实例 //9. exception 必须在page指令中isErrorPage=true的页面使用 java.lang.Throwable的一个实例 String info = pageContext.getServletContext().getServerInfo(); out.println("获取page指令中的info属性:"+info); %> http://hackiller.javaeye.com 1.7 J2EE复习(五)JSP基础 第 80 / 99 页 1.8 J2EE复习(六)JSP自定义标签 发表时间: 2009-04-14 一、JSP自定义标签简介 标签是一种XML元素,通过标签可以使JSP网页变得简洁并且易于维护,还可以方便地实现同一个JSP文件支持 多种语言版本。由于标签是XML元素,所以它的名称和属性都是大小写敏感的 标准JSP标签是用来调用JavaBean组件的操作,处理定向请求以简化JSP页面开发与维护。JSP技术提供了一种 封装其它动态类型的机制——自定义标签,它扩展了JSP语言。自定义标签通常发布在标签库中,该库定义了一 个自定义标签集并包含实现标签的对象。 自定义标签是用户定义的JSP语言元素。当JSP页面包含一个自定义标签时被转化为servlet,标签转化为对称为 tag handler的对象的操作。接着当servlet执行时Web container调用那些操作。 二、两种标签 可以定义两种类型的标签: javax.servlet.jsp.tagext.Tag javax.servlet.jsp.tagext.BodyTag 有标签体的标签必须实现 BodyTag 接口。 body 也可能没有标签体: 无标签体的简单标签可以实现 Tag 接口。 三、标签处理程序 int doStartTag() throws JspException---处理开始标签 int doEndTag() throws JspException---处理结束标签 Tag getParent()/void setParent(Tag t)---获得/设置标签的父标签 http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 81 / 99 页 void setPageContext(PageContext pc)--- pageContext 属性的 setter 方法 void release() 释放获得的所有资源 doStartTag()和doEndTag()方法的返回值说明: SKIP_BODY 表示不用处理标签体,直接调用doEndTag()方法。 SKIP_PAGE 忽略标签后面的jsp(SUN企业级应用的首选)内容。 EVAL_PAGE 处理标签后,继续处理jsp(SUN企业级应用的首选)后面的内容。 EVAL_BODY_BUFFERED 表示需要处理标签体,且需要重新创建一个缓冲(调用setBodyContent方法)。 EVAL_BODY_INCLUDE 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方 法 EVAL_BODY_AGAIN 对标签体循环处理。(存在于javax.servlet.jsp.tagext.IterationTag接口中) 实现javax.servlet.jsp.tagext.Tag接口 扩展javax.servlet.jsp.tagext.TagSupport类 TagSupport 类定义了 get/setParent() 和 setPageContext(),这与所有标签处理程序几乎相同。 get/setParent() 方法允许标签嵌套。 TagSupport 类还定义了一个可以被子类使用的 pageContext 实例变量 (protected PageContext pageContext),这个变量是由 setPageContext() 方法设置的。 在创建自定义标签之前,需要创建一个 标签处理程序。标签处理程序是一个执行自定义标签操作的 Java 对象。 在使用自定义标签时,要导入一个 标签库 —— 即一组标签/标签处理程序对。通过在 Web 部署描述符中声明 库导入它,然后用指令 taglib 将它导入 JSP 页。 <%@ taglib uri="firstTag" prefix="my"%> 如果 JSP 容器在转换时遇到了自定义标签,那么它就检查 标签库描述符(tag library descriptor) (TLD) 文件以查询相应的标签处理程序。TLD 文件对于自定义标签处理程序,就像 Web 部署描述符对于 servlet 一 样。 在运行时,JSP 页生成的 servlet 得到对应于这一页面所使用的标签的标签处理程序的一个实例。生成的 servlet 用传递给它的属性初始化标签处理程序。 http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 82 / 99 页 标签处理程序实现了 生存周期 方法。生成的 servlet 用这些方法通知标签处理程序应当启动、停止或者重复自 定义标签操作。生成的 servlet 调用这些生存周期方法执行标签的功能。 四、TLD 文件 TLD 文件的根元素是 taglib。taglib 描述了一个 标签库 —— 即一组标签/标签处理程序对。 因为我们使用的是 JSP 版本 1.2,所以在这个例子中需要 tlib-version 和 short-name 元素。 tlib-version 元素对应于标签库版本。 jsp-version 对应于标签库所依赖的 JSP 技术的版本。 short-name 元素定义了 IDE 和其他开发工具可以使用的标签库的简单名。 taglib 元素包含许多 tag 元素,标签库中每一个标签有一个 tag 元素。 五、编写自定义迭代标签和el表达式调用类的静态方法实例 循环标签体类:ForEach.java import java.util.Collection; import java.util.Iterator; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.BodyTagSupport; public class ForEach extends BodyTagSupport { private String id; private String collection; private Iterator iter; public void setCollection(String collection) { this.collection = collection; } public void setId(String id) { this.id = id; } http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 83 / 99 页 //遇到开始标签执行 public int doStartTag() throws JspException { Collection coll = (Collection) pageContext.findAttribute(collection); // 表示如果未找到指定集合,则不用处理标签体,直接调用doEndTag()方法。 if(coll==null||coll.isEmpty()) return SKIP_BODY; iter = coll.iterator(); pageContext.setAttribute(id, iter.next()); // 表示在现有的输出流对象中处理标签体,但绕过setBodyContent()和doInitBody()方法 // 这里一定要返回EVAL_BODY_INCLUDE,否则标签体的内容不会在网页上输出显示 return EVAL_BODY_INCLUDE; } //在doInitBody方法之前执行,在这里被绕过不执行 @Override public void setBodyContent(BodyContent arg0) { System.out.println("setBodyContent..."); super.setBodyContent(arg0); } //此方法被绕过不会被执行 @Override public void doInitBody() throws JspException { System.out.println("doInitBody..."); super.doInitBody(); } //遇到标签体执行 public int doAfterBody() throws JspException { if(iter.hasNext()) { pageContext.setAttribute(id, iter.next()); return EVAL_BODY_AGAIN;// 如果集合中还有对像,则循环执行标签体 } http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 84 / 99 页 return SKIP_BODY;//迭代完集合后,跳过标签体,调用doEndTag()方法。 } //遇到结束标签执行 public int doEndTag() throws JspException { System.out.println("doEndTag..."); return EVAL_PAGE; } } 获取VO属性类:GetProperty.java import java.lang.reflect.Method; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; public class GetProperty extends BodyTagSupport { private String name; private String property; public void setName(String name) { this.name = name; } public void setProperty(String property) { this.property = property; } @SuppressWarnings("unchecked") public int doStartTag() throws JspException http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 85 / 99 页 { try { Object obj = pageContext.findAttribute(name); if (obj == null) return SKIP_BODY; Class c = obj.getClass(); //构造GET方法名字 get+属性名(属性名第一个字母大写) String getMethodName = "get" + property.substring(0, 1).toUpperCase() + property.substring(1, property.length()); Method getMethod = c.getMethod(getMethodName, new Class[]{}); pageContext.getOut().print(getMethod.invoke(obj)); System.out.print(property + ":" + getMethod.invoke(obj) + "\t"); } catch (Exception e) { e.printStackTrace(); } return SKIP_BODY; } public int doEndTag() throws JspException { return EVAL_PAGE; } } 表达式直接访问此类中静态的方法:ELFunction.java public class ELFunction { public static int add( int i,int j ) { return i+j; } } http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 86 / 99 页 写一个测试用的VO类:UserVo.java public class UserVo { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } } 建好TLD文件tag.tld,放在WEB-INF目录下 自定义标签 JSTL core 1.1 http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 87 / 99 页 firstLabel http://java.sun.com/jsp/jstl/core forEach exercise.taglib.ForEach JSP id true true collection true true getProperty exercise.taglib.GetProperty empty name true true property true true http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 88 / 99 页 add exercise.taglib.ELFunction int add(int,int) 在web.xml文件中配置自定义标签 firstTag /WEB-INF/tag.tld 在jsp文件中使用标签:tag.jsp <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="firstTag" prefix="my"%> <% List list = new ArrayList(); list.add(userVo1); list.add(userVo2); http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 89 / 99 页 pageContext.setAttribute("voList",list); %> My JSP 'tag.jsp' starting page

      This is my JSP page:测试taglib.


      自定义迭代标签:

      姓名密码

      表达式调用类的静态方法:

      2+5=${my:add(2,5)} http://hackiller.javaeye.com 1.8 J2EE复习(六)JSP自定义标签 第 90 / 99 页 1.9 J2EE复习(七)JSTL(JSP标准标签库) 发表时间: 2009-04-14 在学习JSLT时找到的比较好的资料,在这里原文转载 JSTL(JSP标准标签库)介绍 作者:令少爷(shaoye@dev-club.com) 前言 从JSP 1.1规范开始,JSP就支持在JSP中使用自定义标签了,自定义标签的广泛使用造成了程序员重复定义, 这样就促成了JSTL(JavaServer Pages Standard Tag Library)的诞生。 因为工作中需要用到JSTL,但网上却苦于找不到有关JSTL的中文资料,所以就有了这篇文章。 JSTL简介 JSTL是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的。JSTL只能运行在支持 JSP1.2和Servlet2.3规范的容器上,如tomcat 4.x。但是在即将推出的JSP 2.0中是作为标准支持的。 JSTL目前的最新版本为1.02,最终发布版为1.0。JSTL包含两个部分:标签库和EL(Expression Language表达 式语言)语言。标签库目前支持四种标签: 标签 URI 前缀 示例 Core http://java.sun.com/jstl/core c XML processing http://java.sun.com/jstl/xml x I18N capable formatting http://java.sun.com/jstl/fmt fmt Database access (SQL) http://java.sun.com/jstl/sql sql Core支持JSP中的一些基本的操作; XML processing支持XML文档的处理; I18N capable formatting支持对JSP页面的国际化; Database access (SQL)支持JSP对数据库的操作。 由于本人水平有限,本文仅介绍Core标签,如有兴趣,可一起探讨其它三种标签的使用与扩充。 EL语言介绍 EL语言是JSTL输出(输入)一个JAVA表达式的表示形式。 在JSTL中,EL语言只能在属性值中使用。EL语言只能通过建立表达式${exp1}来进行调用。在属性值中使用表达 式有三种方式。 1、 value属性包含一个表达式 在这种情况下,表达式值被计算出来并根据类型转换规则赋值给value属性。比如:中的${username}就是一个EL,它相当于JSP语句 http://hackiller.javaeye.com 1.9 J2EE复习(七)JSTL(JSP标准标签库) 第 91 / 99 页 <%=request.getAttribute(“username”)%>或<%=session.getAttribute(“username”)%> 2、 value属性包含一个或多个属性,这些属性被文本分割或围绕 在这种情况下,表达式从左到右进行计算,并将结果转换为字符串型(根据类型转换规则),并将结果赋值给 value属性 3、 value属性仅仅包含文本 在这种情况下,字符串型属性value将根据类型转换规则转换为标签所希望的类型。 EL语言的操作符 取得某个对象或集合中的属性值 为了获得集合中的属性,EL支持以下两种操作 1. 使用.操作符来获得有名字的属性。例如表达式${user.username}表明对象user的username属性 2. 使用[]操作符来获得有名字或按数字排列的属性。 表达式${user["username"]}和表达式${user. username }含义相同 表达式${row[0]} 表明row集合的第一个条目。 在这里user是一个类的对象,它的属性username必须符合标准JavaBean的规范,即必须为username属性定义 相应的getter、setter方法。 Empty操作符(空值检查) 使用empty操作符来决定对象、集合或字符串变量是否为空或null。例如: ${empty param.username} 如果request的参数列表中的username值为null,则表达式的值为true。 EL也可以直接使用比较操作符与null 进行比较。如${param.firstname == null}。 比较操作符 操作符 描述 ==或eq 相等检查 !=或ne 不等检查 <或lt 小于检查 >或gt 大于检查 <=或le 小于等于检查 >=或ge 大于等于检查 数字运算符与逻辑运算符均与JAVA语言相同,不再列表。 Core标签库 1、 通用标签 标签用于在JSP中显示数据,它有如下属性 http://hackiller.javaeye.com 1.9 J2EE复习(七)JSTL(JSP标准标签库) 第 92 / 99 页 属 性 描 述 是否必须 缺省值 value 输出的信息,可以是EL表达式或常量 是 无 default value为空时显示信息 否 无 escapeXml 为true则避开特殊的xml字符集 否 true 例子: 您的用户名是: 显示用户的用户名,如为空则显示guest 指定从session中获取username的值显示; 显示username的值,默认是从request(page)中取,如果request中没有名为username的对象则从session中 取,session中没有则从application(servletContext)中取,如果没有取到任何值则不显示。 标签用于保存数据,它有如下属性 属 性 描 述 是否必须 缺省值 value 要保存的信息,可以是EL表达式或常量 否 target 需要修改属性的变量名,一般为javabean的实例 否 无 property 需要修改的javabean属性 否 无 var 需要保存信息的变量 否 无 scope 保存信息的变量的范围 否 page 如果指定了target属性, 那么property属性也必须指定。 例子: 将test.testinfo的值保存到session的test2中,其中test是一个javabean的实例,testinfo是test对象的属性。 将对象cust.address的city属性值保存到变量city中 标签用于删除数据,它有如下属性 属 性 描 述 是否必须 缺省值 var 要删除的变量 是 无 scope 被删除变量的范围 否 所有范围,包括page、request、session、application等 例子: 从session中删除test2变量。 2、 流控制标签 http://hackiller.javaeye.com 1.9 J2EE复习(七)JSTL(JSP标准标签库) 第 93 / 99 页 标签有如下属性 属 性 描 述 是否必须 缺省值 test 需要评价的条件,相当于if (...){}语句中的条件 是 无 var 要求保存条件结果的变量名 否 无 scope 保存条件结果的变量范围 否 page 这个标签不接受任何属性 标签有以下属性 属 性 描 述 是否必须 缺省值 test 需要评价的条件 是 无 这个标签同样不接受任何属性 例子: user.wealthy is true. 如果user.wealthy值true,则显示user.wealthy is true. user.generous is true. user.stingy is true. user.generous and user.stingy are false. 只有当条件user.generous返回值是true时,才显示user.generous is true. 只有当条件user.stingy返回值是true时,才显示user.stingy is true. 其它所有的情况(即user.generous和user.stingy的值都不为true)全部显示user.generous and user.stingy are false. 由于JSTL没有形如if (){…} else {…}的条件语句,所以这种形式的语句只能用标签共同来完成了。 3、 循环控制标签 http://hackiller.javaeye.com 1.9 J2EE复习(七)JSTL(JSP标准标签库) 第 94 / 99 页 标签用于通用数据,它有以下属性 属 性 描 述 是否必须 缺省值 items 进行循环的项目 否 无 begin 开始条件 否 0 end 结束条件 否 集合中的最后一个项目 step 步长 否 1 var 代表当前项目的变量名 否 无 varStatus 显示循环状态的变量 否 无 例子: 相当于java语句 for (int i=0;i count=
      输出: count=0 ... count=100 标签有以下属性 属 性 描 述 是否必须 缺省值 items 进行循环的项目 是 无 delims 分割符 是 无 begin 开始条件 否 0 end 结束条件 否 集合中的最后一个项目 http://hackiller.javaeye.com 1.9 J2EE复习(七)JSTL(JSP标准标签库) 第 95 / 99 页 step 步长 否 1 var 代表当前项目的变量名 否 无 varStatus 显示循环状态的变量 否 无 例子 这个标签的使用相当于java.util.StringTokenizer类。在这里将字符串a:b:c:d以:分开循环四次,token是循环 到当前分割到的字符串。 4.导入文件和URL JSTL核心标签库支持使用来包含文件,使用来打印和格式化URL,使用来重定 向URL。 标签包含另外一个页面代码到当前页,它有以下属性 属 性 描 述 是否必须 缺省值 url 需要导入页面的url 是 无 context /后跟本地web应用程序的名字 否 当前应用程序 charEncoding 用于导入数据的字符集 否 ISO-8859-1 var 接受导入文本的变量名 否 page scope 接受导入文本的变量的变量范围 否 1 varReader 用于接受导入文本的java.io.Reader变量名 否 无 varStatus 显示循环状态的变量 否 无 标签输出一个url地址,它有以下属性 属 性 描 述 是否必须 缺省值 url url地址 是 无 context /后跟本地web应用程序的名字 否 当前应用程序 charEncoding 用于导入数据的字符集 否 ISO-8859-1 var 接受处理过的url变量名,该变量存储url 否 输出到页 scope 存储url的变量名的变量范围 否 page 例子: http://hackiller.javaeye.com 1.9 J2EE复习(七)JSTL(JSP标准标签库) 第 96 / 99 页 将url http://www.url.com/edit.js包含到当前页的当前位置,并将url保存到newsfeed变量中 "/> 在当前页的当前位置输出,http://www.yourname.com是当前页的所在的位置。 标签将请求重新定向到另外一个页面,它有以下属性 属 性 描 述 是否必须 缺省值 url url地址 是 无 context /后跟本地web应用程序的名字 否 当前应用程序 例子: 将请求重新定向到http://www.yourname.com/login.jsp页,相当于 response.setRedirect("http://www.yourname.com/login.jsp"); 标签用来传递参数给一个重定向或包含页面,它有以下属性 属 性 描 述 是否必须 缺省值 name 在request参数中设置的变量名 是 无 value 在request参数中设置的变量值 否 无 例子: 将参数888以id为名字传递到login.jsp页面,相当于login.jsp?id=888 JSTL的优点 1、 在应用程序服务器之间提供了一致的接口,最大程序地提高了WEB应用在各应用服务器之间的移植。 2、 简化了JSP和WEB应用程序的开发。 3、 以一种统一的方式减少了JSP中的scriptlet代码数量,可以达到没有任何scriptlet代码的程序。在我们公司 的项目中是不允许有任何的scriptlet代码出现在JSP中。 4、 允许JSP设计工具与WEB应用程序开发的进一步集成。相信不久就会有支持JSTL的IDE开发工具出现。 http://hackiller.javaeye.com 1.9 J2EE复习(七)JSTL(JSP标准标签库) 第 97 / 99 页 总结 上面介绍的仅仅是JSTL的一部分,如果有时间我会继续把其它部分写出来分享给大家。如果要使用JSTL,则必 须将jstl.jar和standard.jar文件放到classpath中,如果你还需要使用XML processing及Database access (SQL)标签,还要将相关JAR文件放到classpath中,这些JAR文件全部存在于下载回来的zip文件中。这个zip文 件可以从http://jakarta.apache.org/builds/jakarta-taglibs/releases/standard/jakarta-taglibs- standard-1.0.zip下载。 参考资料 1、 http://java.sun.com/products/jsp/jstl/ sun公司的JSTL站点 2、 http://jakarta.apache.org/taglibs/doc/standard-doc/intro.html jakarta小组的JSTL站点 3、 http://www.manning.com/bayern/appendixA.pdf JSTL的参考文档,本文很多内容都是从这个PDF文件里翻译的。 4、 <<J2EE编程指南(1.3版)>> 介绍了JSTL的雏形,wrox的书都是精品。 http://hackiller.javaeye.com 1.9 J2EE复习(七)JSTL(JSP标准标签库) 第 98 / 99 页 奋斗、加油! hackiller的博客文章 作者: hackiller http://hackiller.javaeye.com 本书由JavaEye提供电子书DIY功能制作并发行。 更多精彩博客电子书,请访问:http://www.javaeye.com/blogs/pdf http://www.javaeye.com - 做最棒的软件开发交流社区 第 99 / 99 页
  • 还剩98页未读

    继续阅读

    pdf贡献者

    congzi

    贡献于2011-01-25

    下载需要 15 金币 [金币充值 ]
    亲,您也可以通过 分享原创pdf 来获得金币奖励!