DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> XML和JSP交互技術
XML和JSP交互技術
編輯:XML詳解     

XML和JSp都是近兩年才出現的技術,目前已經成為了很多程序員的熱點話題。XML(可擴展的標記語言)是用來定義文檔標記語言的框架,主要用來存儲和發送數據信息,以便各種基於WEB的應用之間能更方便的交換數據。而JSP是服務器端程序動態設計語言,可以用來設計服務器端各種程序如B2B、B2C等各種系統,由於其面向對象、編譯執行、健壯等特性,也得到了越來越多的應用。
  一個很實用的技術就是如何將XML和JSP結合起來,所幸的是我們不用去寫底支持層東西了,因為很多廠商如SUN、IBM等都發布了自己的支持XML的API,其中SUN公司提供了一個支持在Java下使用XML的API-JAXP(JAVATM API for XML Processing Optional Package),這部分API提供了基本的讀寫、操作XML文檔的功能,通過它我們可以很方便的將XML集成到Java應用程序中來。
  目前JAXP的版本是1.1,除了基本XML支持外還支持SAX 2.0 、DOM 2和XSL技術。SUN公司提供的JAXP可以在SUN公司的主頁http://Java.sun.com/XML 下載。 
  一、 JAXP的安裝
  1、安裝前請確認您用的是JDK 1.1.8 以上版本的Java環境。
  2、在http://Java.sun.com/XML 下載JAXP1.1的zip版本,解壓到硬盤中,假定解壓目錄為#JAXP11,解壓後發現有三個jar文件jaxp.jar crimson.jar xalan.jar,這就是JAXP的核心了。
  3、修改系統的CLASSPATH變量,在Windows平台下添加這樣一行:
   #JAXP11\jaxp.jar; #JAXP11\crimson.jar; #JAXP11\xalan.jar
   在Unix/Linux系統下添加下面一行:
   #JAXP11/jaxp.jar: #JAXP11/crimson.jar: #JAXP11/xalan.jar alan.jar 
如果你使用的是Java2的話,有一種更簡單的方法,將上面的三個文件直接拷貝到JDK的Lib擴展目錄中去,如#JAVA_HOME/jre/lib/ext(#Java_HOME代表JDK目錄),這樣就不用修改CLASSPATH了。
  4、好了,安裝完成了,下一步就是編寫程序然後運行了。
二、 簡單的XML例子
  XML (EXtensible Markup Language )是一種類似Html的語言,和Html不同,XML主要用來描述結構化數據,通過XML格式我們可以很方便的在各種應用程序之間交換數據,而這些都是傳統技術需要花費很大精力才能做到的。
  讓我們來看一個簡單的XML文檔例子,這個例子保存了部分個人檔案,請將它保存為personal.XML文件,因為後面我們的JSP文件還會調用它中間的數據。
   
  <個人檔案>
  <姓名>劉玉鋒 
  <性別>男 
  <年齡>24 
  coolknight@263.Net 
  <個人主頁>http://www.21JSP.com 
  <介紹>歡迎大家訪問我的主頁! 
  
是不是很類似於HTML文件,如HTML中的元素"你好"等等,因為XML和HTML一樣都是標准SGML的子集合,所以有類似之處。但也有很多不同之處需要注意,比如XML文件必須有成對地標記而且大小寫敏感,而這些在Html中都是默認允許的。
  第一行是必須的XML聲明, 我們可以看到聲明是在之間的,中間可以定義部分屬性,version="1.0"表示文檔將使用XML1.0的規范,encoding="gb2312"表示采用中文字符集,這樣我們在下面對於數據就可以使用中文了。
  接著就是<個人檔案>標記了,這是XML文件中的根元素,也是不可缺少的,而且必須有一個對應的結束標記,在開始和結束標記之間我們就可以定義自己的數據描述了。
  嵌套在<個人檔案>標記如"<姓名>劉玉鋒"就是具體的數據描述了,同根元素一樣必須是成對的標記,在標記中間可以是標記對應具體的數值。這種表示方法有點類似於數據庫中的記錄了,字段名字為"姓名"、"性別"等,上面的XML文件就相當於一個只有一條記錄的表"個人檔案"。當然在XML文件中可以進行多層嵌套,但這就不在本文的討論范圍了。

  當然,這裡只是一個特別簡單能代表XML的例子,XML的相關內容特別多,如果想更多了解XML的話建議還是看相關的書籍。

三、JSP和XML交互
  前面已經說過了,JSP通過SUN公司的API-JAXP可以實現和XML的交互,那麼具體實現主要有兩種方法,一種是采用DOM2 API,另外一種是采用SAX2 API。
在這裡我們主要討論JAXP中的SAX(Simple API for XML Parsing)技術,DOM2技術可以看SUN公司相關的文檔。
  1)關於SAX模型
  SAX模型是一種處理XML文件的方法,它是事件驅動的,有些類似於AWT中的事件驅動機制,通過事件驅動來識別XML文檔的內容。在API中關於SAX的主要有下面的幾個包:
  oorg.XML.sax
  oorg.XML.sax.helpers
  oorg.XML.sax.ext
在前台的Java程序或者是JSP程序中通過調用這幾個包中的API就可以很好地實現Java和XML的交互。
  2)關於HandlerBase接口
  我們知道在AWT中一般是通過實施ActionListener等接口實現事件的處理的,同樣的在SAX中SUN也提供了一個類似的接口HandlerBase來處理XML解析的功能,通過將HandlerBase和XML文件關聯可以很好的來處理XML文件。
  在實施接口中我們主要重載三個HandlerBase的方法startElement(String tag, AttributeList attrs)、characters(char[] ch, int start, int length)、endElement(String name)。
  startElement()在讀取一行XML數據的開始標記時候觸發,子類必須覆蓋這個方法,這樣就可以在處理XML節點前先進行自己的處理(比如開始讀取或者寫入XML文件中的節點時候)。
  public void startElement (String name, AttributeList attributes)
   throws SAXException
   {
    // no op
    }
參數name代表XML節點名字,attributes代表默認或者特殊的屬性,這個方法拋出一個違例org.XML.sax.SAXException。
  characters()方法主要用來處理和之間具體的數據,在處理節點數據時候觸發,我們可以覆蓋這個方法來進行數據操作的處理,可以添加代碼讀取節點數據值或者是寫入節點數據值。
  public void characters (char ch[], int start, int length)
throws SAXException
   {
    // no op
    }
參數ch[]代表一個字符數組,start代表字符數組的開始位置,length代表要取的字符數組中ch[]中的元素個數,同樣的這個方法拋出一個違例org.XML.sax.SAXException。
  endElement()方法在處理節點元素結束的時候觸發,也就是碰到標記的時候,我們可以覆蓋這個方法來進行數據的收尾工作,比如將節點數據寫入到文件中。
  public void endElement (String name)
   throws SAXException
    {
     // no op
    }
參數name代表XML節點名字,這個方法拋出一個違例org.XML.sax.SAXException
  從上面我們也可以看出,三個方法在XML事件處理中的順序依次為:
   startElement()àcharacters()àendElement(String name)
也許還不好理解,不要緊在下面我們將會寫一個類myHandler類實現HandlerBase接口,並且覆蓋這三個主要的方法來實現我們的XML文件讀取操作。
  3)關於哈希表 
  由於程序用到了哈希表,所以在這裡先簡單的介紹一下哈希表的基本語法以便大家能更好的理解下面的程序。
  哈希表HashTable是從Dictionary派生出來的,裡面具有一系列的關鍵字和數值,一個關鍵字對應一個數值,識別主要是通過對象的哈希代碼hashCode識別。
  我們程序中用到的方法如下:
  put(Object key,Object value)添加一對關鍵字/數值到哈希表中
  get(Object key)根據關鍵字得到它的值
  keys()取得所有關鍵字並返回一個集合Enumeration
此外,哈希表還具有其他很多有用的方法如長度size()、是否為空empty()、是否重復containsKey()等等,限於篇幅在這裡就不進行介紹了。

4) 實施HandlerBase接口
  在這裡我們編寫一個myHandler的類,它用來實施HandlerBase接口,並且覆蓋接口的三個主要方法startElement(String tag, AttributeList attrs)、characters(char[] ch, int start, int length)、endElement(String name)以便能對XML文件進行操作。
為了保存數據以便外部程序能夠調用本類中的數據,我們采用了哈希表結構來保存解析XML文件後的所有節點名字以及節點的數據值,startElement()方法主要用來讀取XML文件中的節點名稱,characters()方法主要用來根據節點名稱讀取節點數據,endElement()方法主要是在一個XML節點處理完畢後將這對節點名稱和節點數據保存在哈希表中。
  在外部程序中我們只需要調用getTable()方法返回一個哈希表對象就可以讀取所有的節點和節點數據值了。

  代碼不多,而且我在下面添加了很多注釋,應該很好看懂了。
  myHandler.Java文件
  file://文件放置在包com.JSP21.www中
  package com.JSP21.www;
  file://導入相關的Java API
  import Java.io.*;
  import org.w3c.dom.*;
  import org.XML.sax.*;
  import Javax.XML.parsers.SAXParser;
  import Javax.XML.parsers.SAXParserFactory;
  import Java.util.Hashtable;
  import Java.util.Enumeration;
  // myHandler類實現HandlerBase接口;
  public class myHandler extends HandlerBase {
  private String myElement = null; file://XML文件中的標記名稱;
  private String myValue = null; file://XML文件中標記對應的值;
  private Hashtable mytable = new Hashtable(); file://用來保存XML文件中所有的數據;
  file://得到保存有XML數據的哈希表Hashtable;
  public Hashtable getTable() {
return mytable;
  }
  file://覆蓋HandlerBase接口中的startElement方法,讀取一行XML數據的開始標記時候執行此方法;
  // tag代表XML中的標記,如前面XML文件中的NAME AGE等;
  public void startElement(String tag, AttributeList attrs)
   throws SAXException {
   myElement = tag;
  }
  file://覆蓋HandlerBase接口中的characters方法,主要用來得到和之間具體的數據;
  // 當對應myElement的標記發現值後,也就是startElement方法執行完畢後,就會觸發這個characters方法來得到具體的數值;
  file://如myElement="姓名"時候,myValue就會等於"劉玉鋒";
  public void characters(char[] ch, int start, int length)
  throws SAXException {
    myValue = new String(ch, start, length);
  }
  file://覆蓋HandlerBase接口中的endElement方法,主要用來在一行XML數據讀取完畢後進行自己的處理;
  // 當XML文件中一行標記讀取完畢後,觸發此endElement方法;
  file://如果存在對應的結束標記,就將前面得到的標記myElement和值myValue
  file://放入到mytable哈希表中;
  public void endElement(String name) throws SAXException {
  if ( myElement.equals(name) ) {
   mytable.put(myElement, myValue);
  }
  }
  }
好了,編譯這個class,並把myHandler.class文件放置在CLASSPATH能找到的路徑中,比如Tomcat中應用程序的Web-inf\classes\com\JSP21\www目錄下。
5)JSP程序調用XML
  在這裡,我們寫了一個比較簡單的JSp程序來調用前面的myHandler類,並通過這個類來讀取personal.XML文件中的內容,最後顯示在JSP頁面中。
  首先我們創建一個SAXParserFactory的實例saxpF,然後通過這個實例來創建一個SAXParser的實例saxpser(可以用來解析XML文件內容),當然還要創建myHandler類的實例,最後通過saxpser.parse()方法將XML文件和myHandler類實例關聯起來(這樣會執行myHandler中的幾個事件處理方法)。
(說明:SAXParserFactory是一個抽象類,定義了一個factory API可以讓Java應用程序配置或者是獲得一個SAX的解析器(SAX parser)。SAXParser也是一個抽象類,通過這個類應用程序可以解析XML文件的內容。)
  到這時候XML所有內容都保存在了myHandler類實例中的哈希表中,最後通過getTable()方法得到這個哈希表對象,將哈希表中的鍵保存在集合Enumeration中,使用一個循環來讀取哈系表中的數據並顯示在JSp頁面上。我們用集合的目的在於使這個JSP程序盡量通用,傳遞一個XML文件名字就可以讀出所有內容,當然你也可以不使用集合而使用(String)hshTable.get("姓名")這樣的方法來讀取特定的節點值。
  下面是Jsp文件代碼,請保存為JSpXML.JSP文件 
這是一個XML+JSP的例子,讀取XML文件中的內容

   
代碼寫完好,將此文件放在Web應用程序目錄下,然後通過浏覽器運行這個程序,如http://192.168.0.98:7070/welcome_Html/JSpXML.JSP?file=e:\\personal.xml,注意必須使用參數?file=路徑\\personal.XML (路徑根據你保存在硬盤中的目錄而定,Java表示:Windows系統下"\\"代表一個"\"),運行後的效果如下面所示:

 

可以看到,XML文件中的所有數據都通過這個JSp文件讀取出來了,因為這個JSP程序是文件無關的,你也可以將file=e:\\personal.xml中的xml文件名字換為其他的XML文件看看最後運行效果。
  要說明一點的就是本人在最後實際采用的是JAXP1.01版本的API,有可能是本人的系統原因,發現程序在1.1版本下可以編譯通過,但運行的時候會出現下面錯誤(即使JAXP1.1包中自帶的例子main.Java也這樣):
Java.lang.NoClassDefFoundError: org.apache.crimson.jaxp.SAXParserFactoryImpl
所以最後換作了1.01版本的JAXP來運行程序,1.01版本的JAXP在上面的地址同樣可以下載。

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved