posts - 9, comments - 1, trackbacks - 0, articles - 0

2009年12月2日

character set,character encoding和xml encoding declaration

hanlray@gmail.com

Revision: 0.9 Date: 2005/08/28


1. character set和character encoding

一 直以为character set和character encoding是一回事,最近才发现它们差不多是两个概念。从字面意思上看,一个character set就是一些字符的集合,比如26个英文字母,全体汉字,或者两者的组合,然而计算机是只能处理数字的,一个字符必须被表示成一个数字才可能被计算机处 理,因此一个character set还必须定义字符到数字的映射关系,比如字符A映射到数字64,字符Z映射到数字90,这些数字叫做code points;character encoding则用来定义这些code points如何用字节表示出来,比如code point 90可以被编码为一个单字节,一个little-endian的unsigned short,一个big-endian的integer,或者更复杂的形式。换句话说,一个character set仅仅是一张字符和数字的映射表,它并不规定这些数字如何用字节表示出来,这种表示的事情由character encoding来定义。因此,一个character encoding是针对一个character set的,而一个character set可以有多个character encoding,比如UTF-8,UTF-16都是Unicode Character Set的encoding。

2. xml encoding declaration

对 一段编码后的文本,要想正确地处理它,必须要事先知道其采用的编码方式,因此这种编码信息一般是存在于该文本之外的,比如某些编辑器会在文件开始放几个不 可见的字节来指示其正文的编码方式,这些字节叫做BOM(Byte Order Mark);某些网络协议会有一些字段来指示其所携带文本的编码方式。这种方式很直观,很多系统/技术采用这种方式,大多数有关xml的应用也会优先使用 这种外部的编码信息,但是当没有这种外部的编码信息可用的时候呢?一个xml document可以用一个xml declaration来声明其采用的编码,形如<?xml version="1.0" encoding="UTF-8"?>,这种方式看起来不大可能工作,因为这个声明本身就是文本的,并且该声明是xml document的一部分,不可能规定其采用的编码方式。如何能在不知道xml document编码的情况下理解其xml declaration中声明的编码呢?对xml编码声明的位置及内容的限制使自动检测成为可能:编码声明必须出现在文档开头,只允许ASCII字符并且 其头几个字符必须是<?xml,这样,一个xml processor就可以先读出文档的前几个字节,推断其采用的编码的特征,根据该特征能理解xml declaration,读出encoding属性值,从而知道该文档的编码。比如,如果前4个字节的内容为3C 3F 78 6D,则可以确定该文档采用的是一种兼容ASCII的编码,这样xml processor就可以用任一种兼容ASCII的编码(如UTF-8)来理解编码后xml声明,因为其只包含ASCII字符,任何兼容ASCII的编码 对其编码的结果都是相同的。当得到xml declaration中声明的编码时,xml processor再转换到该编码对该xml进行处理。下表来自XML W3C Recommendation,列出了自动检测编码的方式:

00 00 00 3C
3C 00 00 00
00 00 3C 00
00 3C 00 00
UCS-4 or other encoding with a 32-bit code unit and ASCII characters encoded as ASCII values, in respectively big-endian (1234), little-endian (4321) and two unusual byte orders (2143 and 3412). The encoding declaration must be read to determine which of UCS-4 or other supported 32-bit encodings applies.
00 3C 00 3F UTF-16BE or big-endian ISO-10646-UCS-2 or other encoding with a 16-bit code unit in big-endian order and ASCII characters encoded as ASCII values (the encoding declaration must be read to determine which)
3C 00 3F 00 UTF-16LE or little-endian ISO-10646-UCS-2 or other encoding with a 16-bit code unit in little-endian order and ASCII characters encoded as ASCII values (the encoding declaration must be read to determine which)
3C 3F 78 6D UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS, EUC, or any other 7-bit, 8-bit, or mixed-width encoding which ensures that the characters of ASCII have their normal positions, width, and values; the actual encoding declaration must be read to detect which of these applies, but since all of these encodings use the same bit patterns for the relevant ASCII characters, the encoding declaration itself may be read reliably
4C 6F A7 94 EBCDIC (in some flavor; the full encoding declaration must be read to tell which code page is in use)
Other UTF-8 without an encoding declaration, or else the data stream is mislabeled (lacking a required encoding declaration), corrupt, fragmentary, or enclosed in a wrapper of some kind

posted @ 2009-12-09 20:27 TonyZhangtl 阅读(289) | 评论 (0)编辑 收藏

虽然将jxl.jar包添加到工程里了, 但是仍让有java.lang.ClassNotFoundException: jxl.write.WritableCell错误。
需要把jar包放在web-inf/lib目录下再加载才可以解决这个问题。
package tony.servlet.example;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;

public class Hello extends HttpServlet {
    protected void service(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        // ServletOutputStream out = response.getOutputStream();
        // PrintWriter out = response.getWriter();
        // out.println("Hello world!");
        // System.out.println("TEST");
        // request.getRequestDispatcher("/WEB-INF/jspfooder/test1.html").forward(request,
        // response);
        // request.getRequestDispatcher("test.jsp").forward(request, response);
        // request.getRequestDispatcher("/WEB-INF/test.jsp").forward(request,
        // response);
        /*
         * response.setContentType("application/vnd.ms-excel");
         * response.setHeader("Content-disposition","filename="+ "Example.xls"
         * ); HSSFWorkbook demoWorkBook = new HSSFWorkbook(); HSSFSheet sheet =
         * demoWorkBook.createSheet("账号详单"); HSSFRow row = sheet.createRow(0);
         * HSSFCell cell = row.createCell(0); cell.setCellValue(11);
         * ServletOutputStream out = response.getOutputStream();
         * demoWorkBook.write(out); out.flush(); out.close();
         */
        OutputStream out = response.getOutputStream();
        try {

            response.setContentType("application/vnd.ms-excel");

            response.setHeader("Content-Disposition",
                    "attachment; filename=example.xls");

            WritableWorkbook w = Workbook.createWorkbook(out);
            WritableSheet s = w.createSheet("sheet1", 0);

            s.addCell(new Label(0, 0,
                    "this is my first servlet & sheet example."));
            w.write();
            w.close();

        } catch (Exception e) {
            throw new ServletException("Exception in Excel Sample Servlet", e);
        } finally {
            if (out != null)
                out.close();
        }
    }
}


posted @ 2009-12-06 17:42 TonyZhangtl 阅读(881) | 评论 (1)编辑 收藏

EJB与JavaBean之区别
[日期]: 2006-08-17  [来源]:   [作者]:
EJB 不是一般的JavaBean,EJB是企业级JavaBean,EJB一共分为3种,实体Bean,消息Bean,会话Bean,书写EJB是需要遵循一 定的规范的,具体规范你可以参考相关的资料.另外,要运行EJB,你需要相应的EJB容器,比如Weblogic,Jboss等,而JavaBean不需 要,只需要安装Tomcat就可以了
.EJB用于服务端应用开发, 而JavaBeans用于客户端应用开发
也可以使用JavaBeans进行服务端应用开发,但JavaBeans模型没有提供服务框架,当应用需要使用系统级服务(如事务管理,安全性,生命周期管理等)时,不适合。

2.EJB构件是可部署的,EJB构件可以作为独立的单元被部署到EJB应用服务器上,是应用构件(application components),而JavaBeans构件是不可部署的, JavaBeans构件是开发构件,不能被部署为独立的单元。

3.EJB构件是部署可定制的,使用部署描述符可以在部署EJB时对其运行时配置进行定制,而JavaBeans构件在部署时不能进行定制,JavaBeans构件的定制仅发生在开发阶段,只能利用开发工具创建并组装JavaBeans构件,部署时不能定制

4.EJB构件是分布式对象,可以被客户应用或者其它EJB构件进行远程访问,而JavaBeans构件不是分布式对象,JavaBeans构件只能在其构成的应用中使用,不能提供远程访问能力

5.EJB构件对终端用户不可见,运行在服务端,没有人机交互界面,而部分JavaBeans构件对终端用户可见,如GUI应用中使用的按钮构件.

Java bean is just a set of conventions. EJB is a standard for J2EE business components.

Specifically a Java bean:

  • has a public default constructor;
  • readable propertiy methods prepended with "get";
  • writable propertty methods prepended with "set"; and
  • is Serializable.

For example, a Java bean with a property of "margin" would minimally look like this:

public class MyBean implements Serializable {
 
private int margin;

 
public MyBean() { }
 
public int getMargin() { return margin; }
 
public void setMargin(int margin) { this.margin = margin; }
}

EJB, despite the name, is almost completely unrelated.


JavaBeans:-
---------
Basically used to CUSTOMIZE EXISTING OBJECTS. i.e. You can
create USER OBJECTS, which are based on existing objects.
For Example: A default button operates as a Single-State Switch. i.e. when you press a button on a web page, it doesn't remain pressed. Infact, it immediately bounces back to its OFF state like a Door-Bell.

Now, let's say, you need a button, which should have 2 stable states, like the typical Electrical Light Switch. So, in this case, what you can do is, take an existing button (having 1 stable state) and CUSTOMIZE it so that it has 2 stable states.
This is possible using JavaBeans.

Enterprise Java Beans (EJB):-
---------------------------
EJB is a completely different concept than the one mentioned
above. It is NOT used to customize existing objects. Instead
they are basically used to STANDARDIZE the way, in which
business logic is written.
For Example: We can write our business logic as well as the GUI logic, inside Servlets/Applets/StandAlone applications itself. But this way,there will be no clear distinction between the Code that is responsible for the GUI and the actual Business logic code, because everything is written inside the same class file.

So, to COMPONENTIZE we write business logic in seperate class files than the GUI logic, thereby making a clear distinction between the reponsibilities


有一些基本相同之处。它们都是用一组特性创建,以执行其特定任务的对象或组件。它们还有从当前所驻留服务器上的容器获得其它特性的能力。这使得   bean   的行为根据特定任务和所在环境的不同而有所不同。  
        不同的是:  
        EJB   是设计成运行在服务器上,并由客户机调用的非可视远程对象。可通过多个非可视   JavaBean   构建   EJB。它们有一个部署描述符,其目的与   JavaBean   属性相同:它是以后可由工具读取的   bean   的描述。EJB   还独立于平台,一旦编写好,还可以在任何支持   Java   的平台(包括客户机和服务器)上使用。  
        EJB是一种非可视化的构件,完全位于服务器端,规范说明详细说明了EJB容器需要满足的需求以及如何和EJB构件相互协作。EJB可以和远程的客户端程 序通讯,并提供一定的功能,根据规范说明,EJB是client/Server系统的一部分,如果不和客户端程序交互,EJB一般不执行具体的功 能,EJB和JavaBean的一个重要区别是EJB必须在网络计算环境下使用才有意义。  
  EJB的重点是给出服务框架模型,以保证Java构件可以进行可移植性的部署,因此,在EJB规格说明中,并没有提到事件,因为典型的EJB构件不发 送和接收事件,EJB规范说明中也没有提到属性。和一般的JavaBean一样,EJB是高度可定制的,对EJB进行定制不需要存取源代码,但对EJB可 以进行定制不是在开发阶段,而是在部署阶段用部署描述符进行定制。  
  需要说明的是,JavaBean不仅可用于客户端应用程序的开发,也可以用于服务器端应用程序的开发,但和EJB的区别是,如果用JavaBean创 建服务器端应用程序,还必须同时实现服务框架,在多层结构分布式应用系统中,服务框架的实现是非常繁琐的,对于EJB来说,服务框架已经提供,因此大大简 化了系统的开发过程。


我了省时间,我给你一份文档吧!是专门介绍二者区别的。  
   
  java   bean   与   ejb的区别  
   
  您现在可能已在使用   JavaBean,但还不了解它。如果有支持   Java   的浏览器,那么,在桌面上使用   JavaBean   就没有限制。使用的   Web   页面可以将   bean   作为小应用程序的一部分。您很快就会和作为浏览器可视部分的   JavaBean   交互,然后,那些   JavaBean   将与服务器上的   EJB   接口。这种能力也可以扩展到因特网和内部网。  
   
  JavaBean   和   Server   Bean(通常称为   Enterprise   JavaBean   (EJB))有一些基本相同之处。它们都是用一组特性创建,以执行其特定任务的对象或组件。它们还有从当前所驻留服务器上的容器获得其它特性的能力。这使 得   bean   的行为根据特定任务和所在环境的不同而有所不同。  
   
  这开辟了巨大商机。因为   JavaBean   是与平台无关的,所以对于将来的解决方案,供应商可以轻易向不同用户推出其客户机方的   JavaBean,而不必创建或维护不同的版本。这些   JavaBean   可以与执行商业功能(例如订购、信用卡处理、电子汇款、存货分配、运输等)的   EJB   配合使用。这里有巨大潜力,而这正是组件代理(WebSphere   Application   Server   企业版)设计提供的那种潜力。  
   
  JavaBean   是一种组件,它在内部有接口或有与其相关的属性,以便不同人在不同时间开发的   bean   可以询问和集成。可以构建一个   bean,而在以后构造时将其与其它   bean   绑定。这种过程提供了先构建,然后重复使用的方法,这就是组件的概念。可以将这种单一应用程序部署成独立程序、ActiveX   组件或在浏览器中。  
   
  JavaBean   因其外部接口(即属性接口)而与纯对象不同。这种接口允许工具读取组件要执行的功能,将其与其它   bean   挂钩,以及将其插入其它环境。JavaBean   设计成对单一进程而言是本地的,它们在运行时通常可视。这种可视组件可能是按钮、列表框、图形或图表   -   但这不是必需的。  
   
  可执行组件    
  Server   Bean   或   EJB   是部署在服务器上的可执行组件或商业对象。有一个协议允许对其进行远程访问或在特定服务器上安装或部署它们。有一系列机制允许它们将服务安全性、事务行 为、并发性(由多个客户机同时访问的能力)和持久性(其状态可以保存多久)的主要方面授权给   EJB   服务器上其所在的容器。当安装在容器中时,它们获得各自的行为,该行为提供不同质量的服务,因此,选择正确的   EJB   服务器至关重要。这正是   IBM   WebSphere   企业版的优势所在。  
   
  EJB   是设计成运行在服务器上,并由客户机调用的非可视远程对象。可通过多个非可视   JavaBean   构建   EJB。它们有一个部署描述符,其目的与   JavaBean   属性相同:它是以后可由工具读取的   bean   的描述。EJB   还独立于平台,一旦编写好,还可以在任何支持   Java   的平台(包括客户机和服务器)上使用。  
   
  因为   EJB   由诸如   IBM   VisualAge   for   Java   这样的工具集生成,所以,它是基于服务器的对象,并用于远程调用。它们安装在   EJB   服务器上,并象调用其它   CORBA   远程对象那样获得进行调用的远程接口。  
   
  ActiveX   对象    
  可以将   JavaBean   部署成   ActiveX   对象,虽然   EJB   的代理也可以这样做,但是,因为   ActiveX   运行在桌面上,所以,EJB   本身不能成为   ActiveX   对象。要在与平台相关的、仅   Windows   平台上做到这一点,开发人员可以将   JavaBean   变换成   ActiveX   组件。  
   
  好处    
  EJB   的主要好处在于:构建   bean   时,bean   开发人员可以规定需要什么类型的行为,而不必规定如何去做。开发分为两部分:程序员开发   bean,然后验证:它可与构建工具一起工作,并包括标识所需服务质量行为种类的部署描述符。下一步,另一个程序员可以采用这个   bean,并使用读取   EJB   部署描述符的部署工具,然后将该   bean   安装到   Enterprise   Java   Server   上的容器中。在第二步中,部署工具采取一些操作   -   这可能意味着生成如状态保存代码,放入事务挂钩,或执行安全性检查这样的代码。所有这些操作由部署工具生成,bean   开发人员和部署人员可以是不同的人。  
   
  可以通过使用部署工具,将任何独立于平台的   JavaBean   改写成具有可靠服务质量、特定于平台的   EJB,以满足现有商业系统和应用程序的特定需求。这就是   EJB   服务器对集成系统、网络和体系结构如此重要的原因所在。  
   
  EJB   与   IBM   WebSphere   企业版    
  在   IBM   WebSphere   企业版中使用时,可以将   EJB   配置成被管理的商业对象。接受它们授权服务的容器是其安装到的容器。将   EJB   的持久性部分映射在数据或状态对象中。EJB   服务器为   EJB   提供不同的服务质量,选择正确的   EJB   服务器可能对满足完整的商业需求至关重要。“组件代理”功能极其健壮,该功能提供如负载均衡和支持服务器组中多台机器的高级功能。它还有大大超出   Enterprise   Java   Server   (EJS)   规范所倡导的系统管理功能。因此,按照基本标准编写的   JavaBean   或   EJB   可以运行在使用“组件代理”功能的   WebSphere   企业版上,并获得那些所有的附加功能。  
   
  EJB   服务器还提供独特的特性和服务质量,而且不完全相同。IBM“组件代理”有一些强大特性   -   例如,可伸缩性,它允许开发人员将   EJB   部署到从小型系统到大型网络的不同类型服务器。开发人员可以从小处入手,例如,在一个部门中,首先在   LAN   的   Java   服务器上部署,一旦准备好,就知道可以将在那里创建的   JavaBean   和   EJB   部署到全球网络。然后,开发人员可以测试并熟悉这些   bean,试运行,制作样本等等。满意之后,开发人员可以通过将其移至高性能服务器,来大幅度扩大其规模。JavaBean   和   EJB   不受任何计算机体系结构边界的限制。它们用   Java   编写,可以运行在任何具有   Java   虚拟机的系统上,并可以使用任何   Enterprise   Java   Server   (EJS)   来部署对象。因此,开发人员现在可以在方便的系统上构建,以后在方便的系统上部署,而不必是同一台或同样类型的机器。  
   
  IBM   WebSphere   企业版支持将商业对象部署到多台服务器。EJB   作为商业对象集成到“组件代理”功能,并作为任何其它商业对象处理。因此,EJB   可以连接到所选的后端系统,并执行任何所需操作,以满足其商业需求。这就成为“组件代理”为   EJB   提供的基础设施。通过将“组件代理”用作   EJB   服务器,开发人员将能够继续使用当前旧有系统,并将其与电子商务接口一起提供。  
   
  为使   EJB   能在   WebSphere“组件代理”环境中工作,可以使用“组件代理”部署工具将其安装在一台或多台服务器上,然后将其添加到命名服务器,以便可以全局查找到 它。任何可以访问公共命名服务器的人都可以找到它,找到其宿主,并可以在宿主上执行方法,同时创建   EJB。这就是“代理组件”要做的事。  
   
  示例    
  让我们举一个在   Web   购物站点上可以看到的电子购物车的例子。用户的购物车是一个   JavaBean。用户将货架上的商品放入购物车,这些商品本身是   JavaBean。它们全部可视,并且面向用户。结帐时,将用户购物车中的商品发送到服务器上的   EJB,该   EJB   执行一些必要的操作,如检查信用卡授权和可用额度,生成封条,或生成给发货部门的有关提什么货和发货地点的特殊指示   -   这就是商业程序已在进行的活动。  
   
  结束语    
  Bean   的全部意义不只是其现有能力,更在于其可以为商业提供的有竞争力的潜在能力。IT   设计师和应用开发人员现在可以将精力完全集中在商业逻辑,而将如事务、持久性和安全性的底层工作留给服务器。WebSphere   的“组件代理”功能将提供所有这些(还有后端访问)和对象事务管理器。





posted @ 2009-12-05 13:05 TonyZhangtl 阅读(213) | 评论 (0)编辑 收藏

Taking a big step back, a Web server serves pages for viewing in a Web browser, while an application server provides methods that client applications can call. A little more precisely, you can say that:
A Web server exclusively handles HTTP requests, whereas an application server serves business logic to application programs through any number of protocols.


Let's examine each in more detail.

The Web server

A Web server handles the HTTP protocol. When the Web server receives an HTTP request, it responds with an HTTP response, such as sending back an HTML page. To process a request, a Web server may respond with a static HTML page or image, send a redirect, or delegate the dynamic response generation to some other program such as CGI scripts, JSPs (JavaServer Pages), servlets, ASPs (Active Server Pages), server-side JavaScripts, or some other server-side technology. Whatever their purpose, such server-side programs generate a response, most often in HTML, for viewing in a Web browser.

Understand that a Web server's delegation model is fairly simple. When a request comes into the Web server, the Web server simply passes the request to the program best able to handle it. The Web server doesn't provide any functionality beyond simply providing an environment in which the server-side program can execute and pass back the generated responses. The server-side program usually provides for itself such functions as transaction processing, database connectivity, and messaging.

While a Web server may not itself support transactions or database connection pooling, it may employ various strategies for fault tolerance and scalability such as load balancing, caching, and clustering—features oftentimes erroneously assigned as features reserved only for application servers.

The application server

As for the application server, according to our definition, an application server exposes business logic to client applications through various protocols, possibly including HTTP. While a Web server mainly deals with sending HTML for display in a Web browser, an application server provides access to business logic for use by client application programs. The application program can use this logic just as it would call a method on an object (or a function in the procedural world).

Such application server clients can include GUIs (graphical user interface) running on a PC, a Web server, or even other application servers. The information traveling back and forth between an application server and its client is not restricted to simple display markup. Instead, the information is program logic. Since the logic takes the form of data and method calls and not static HTML, the client can employ the exposed business logic however it wants.

In most cases, the server exposes this business logic through a component API, such as the EJB (Enterprise JavaBean) component model found on J2EE (Java 2 Platform, Enterprise Edition) application servers. Moreover, the application server manages its own resources. Such gate-keeping duties include security, transaction processing, resource pooling, and messaging. Like a Web server, an application server may also employ various scalability and fault-tolerance techniques.

posted @ 2009-12-02 21:29 TonyZhangtl 阅读(186) | 评论 (0)编辑 收藏

XML现在已经成为一种通用的数据交换格式,平台的无关性使得很多场合都需要用到XML。本文将详细介绍用Java解析XML的四种方法。

XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关 性,系统无关性,给数据集成与交互带来了极大的方便。对于XML本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有 DOM(Document Object Model),DTD(Document Type Definition),SAX(Simple API for XML),XSD(Xml Schema Definition),XSLT(Extensible Stylesheet Language Transformations),具体可参阅w3c官方网站文档http://www.w3.org获取更多信息。

XML在不同的语言里解析方式都是一样的,只不过实现的语法不同而已。基本的解析方式有两种,一种叫SAX,另一种叫DOM。SAX是基于事件流的解析,DOM是基于XML文档树结构的解析。假设我们XML的内容和结构如下:

<?xml version="1.0" encoding="UTF-8"?> 
<employees>
<employee>
<name>ddviplinux</name>
<sex>m</sex>
<age>30</age>
</employee>
</employees>

本文使用JAVA语言来实现DOM与SAX的XML文档生成与解析。
首先定义一个操作XML文档的接口XmlDocument 它定义了XML文档的建立与解析的接口。

package com.alisoft.facepay.framework.bean; 
/**
*
* @author hongliang.dinghl
* 定义XML文档建立与解析的接口
*/
public interface XmlDocument {
/**
* 建立XML文档
* @param fileName 文件全路径名称
*/
public void createXml(String fileName);
/**
* 解析XML文档
* @param fileName 文件全路径名称
*/
public void parserXml(String fileName);
}

1.DOM生成和解析XML文档

为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后代码就可以使用 DOM 接口来操作这个树结构。优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时 间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。

package com.alisoft.facepay.framework.bean; 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
*
* @author hongliang.dinghl
* DOM生成与解析XML文档
*/
public class DomDemo implements XmlDocument {
private Document document;
private String fileName;
public void init() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
this.document = builder.newDocument();
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
}
}
public void createXml(String fileName) {
Element root = this.document.createElement("employees");
this.document.appendChild(root);
Element employee = this.document.createElement("employee");
Element name = this.document.createElement("name");
name.appendChild(this.document.createTextNode("丁宏亮"));
employee.appendChild(name);
Element sex = this.document.createElement("sex");
sex.appendChild(this.document.createTextNode("m"));
employee.appendChild(sex);
Element age = this.document.createElement("age");
age.appendChild(this.document.createTextNode("30"));
employee.appendChild(age);
root.appendChild(employee);
TransformerFactory tf = TransformerFactory.newInstance();
try {
Transformer transformer = tf.newTransformer();
DOMSource source = new DOMSource(document);
transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
PrintWriter pw = new PrintWriter(new FileOutputStream(fileName));
StreamResult result = new StreamResult(pw);
transformer.transform(source, result);
System.out.println("生成XML文件成功!");
} catch (TransformerConfigurationException e) {
System.out.println(e.getMessage());
} catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (TransformerException e) {
System.out.println(e.getMessage());
}
}
public void parserXml(String fileName) {
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.parse(fileName);
NodeList employees = document.getChildNodes();
for (int i = 0; i < employees.getLength(); i++) {
Node employee = employees.item(i);
NodeList employeeInfo = employee.getChildNodes();
for (int j = 0; j < employeeInfo.getLength(); j++) {
Node node = employeeInfo.item(j);
NodeList employeeMeta = node.getChildNodes();
for (int k = 0; k < employeeMeta.getLength(); k++) {
System.out.println(employeeMeta.item(k).getNodeName()
+ ":" + employeeMeta.item(k).getTextContent());
}
}
}
System.out.println("解析完毕");
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (ParserConfigurationException e) {
System.out.println(e.getMessage());
} catch (SAXException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
}

2.SAX生成和解析XML文档

为 解决DOM的问题,出现了SAX。SAX ,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个 文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态 性;从事件中只能得到文本,但不知该文本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;

Java代码

package com.alisoft.facepay.framework.bean;   
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.IOException;  
import java.io.InputStream;  

import javax.xml.parsers.ParserConfigurationException;  
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;  
/**
*  
* @author hongliang.dinghl
* SAX文档解析
*/
public class SaxDemo implements XmlDocument {  

public void createXml(String fileName) {  
System.out.println("<<"+filename+">>");  
}  

public void parserXml(String fileName) {  
SAXParserFactory saxfac = SAXParserFactory.newInstance();  

try {  

SAXParser saxparser = saxfac.newSAXParser();  

InputStream is = new FileInputStream(fileName);  

saxparser.parse(is, new MySAXHandler());  

} catch (ParserConfigurationException e) {  

e.printStackTrace();  

} catch (SAXException e) {  

e.printStackTrace();  

} catch (FileNotFoundException e) {  

e.printStackTrace();  

} catch (IOException e) {  

e.printStackTrace();  

}  

}  

}  

class MySAXHandler extends DefaultHandler {  

boolean hasAttribute = false;  

Attributes attributes = null;  

public void startDocument() throws SAXException {  

System.out.println("文档开始打印了");  

}  

public void endDocument() throws SAXException {  

System.out.println("文档打印结束了");  

}  

public void startElement(String uri, String localName, String qName,  

Attributes attributes) throws SAXException {  

if (qName.equals("employees")) {  

return;  

}  

if (qName.equals("employee")) {  

System.out.println(qName);  

}  

if (attributes.getLength() > 0) {  

this.attributes = attributes;  

this.hasAttribute = true;  

}  

}  

public void endElement(String uri, String localName, String qName)  

throws SAXException {  

if (hasAttribute && (attributes != null)) {  

for (int i = 0; i < attributes.getLength(); i++) {  

System.out.println(attributes.getQName(0)  
+ attributes.getValue(0));  

}  

}  

}  

public void characters(char[] ch, int start, int length)  

throws SAXException {  

System.out.println(new String(ch, start, length));  

}  

}
package com.alisoft.facepay.framework.bean;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.ParserConfigurationException;
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;
/**
*
* @author hongliang.dinghl
* SAX文档解析
*/
public class SaxDemo implements XmlDocument {
public void createXml(String fileName) {
System.out.println("<<"+filename+">>");
}
public void parserXml(String fileName) {
SAXParserFactory saxfac = SAXParserFactory.newInstance();
try {
SAXParser saxparser = saxfac.newSAXParser();
InputStream is = new FileInputStream(fileName);
saxparser.parse(is, new MySAXHandler());
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class MySAXHandler extends DefaultHandler {
boolean hasAttribute = false;
Attributes attributes = null;
public void startDocument() throws SAXException {
System.out.println("文档开始打印了");
}
public void endDocument() throws SAXException {
System.out.println("文档打印结束了");
}
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if (qName.equals("employees")) {
return;
}
if (qName.equals("employee")) {
System.out.println(qName);
}
if (attributes.getLength() > 0) {
this.attributes = attributes;
this.hasAttribute = true;
}
}
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (hasAttribute && (attributes != null)) {
for (int i = 0; i < attributes.getLength(); i++) {
System.out.println(attributes.getQName(0)
+ attributes.getValue(0));
}
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch, start, length));
}
}

3.DOM4J生成和解析XML文档

DOM4J 是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件。如今你可以看到越来越多的 Java 软件都在使用 DOM4J 来读写 XML,特别值得一提的是连 Sun 的 JAXM 也在用 DOM4J。

Java代码

package com.alisoft.facepay.framework.bean;   
import java.io.File;  
import java.io.FileWriter;  
import java.io.IOException;  
import java.io.Writer;  
import java.util.Iterator;  

import org.dom4j.Document;  
import org.dom4j.DocumentException;  
import org.dom4j.DocumentHelper;  
import org.dom4j.Element;  
import org.dom4j.io.SAXReader;  
import org.dom4j.io.XMLWriter;  
/**
*  
* @author hongliang.dinghl
* Dom4j 生成XML文档与解析XML文档
*/
public class Dom4jDemo implements XmlDocument {  

public void createXml(String fileName) {  
Document document = DocumentHelper.createDocument();  
Element employees=document.addElement("employees");  
Element employee=employees.addElement("employee");  
Element name= employee.addElement("name");  
name.setText("ddvip");  
Element sex=employee.addElement("sex");  
sex.setText("m");  
Element age=employee.addElement("age");  
age.setText("29");  
try {  
Writer fileWriter=new FileWriter(fileName);  
XMLWriter xmlWriter=new XMLWriter(fileWriter);  
xmlWriter.write(document);  
xmlWriter.close();  
} catch (IOException e) {  

System.out.println(e.getMessage());  
}  


}  


public void parserXml(String fileName) {  
File inputXml=new File(fileName);  
SAXReader saxReader = new SAXReader();  
try {  
Document document = saxReader.read(inputXml);  
Element employees=document.getRootElement();  
for(Iterator i = employees.elementIterator(); i.hasNext();){  
Element employee = (Element) i.next();  
for(Iterator j = employee.elementIterator(); j.hasNext();){  
Element node=(Element) j.next();  
System.out.println(node.getName()+":"+node.getText());  
}  

}  
} catch (DocumentException e) {  
System.out.println(e.getMessage());  
}  
System.out.println("dom4j parserXml");  
}   
}  

4.JDOM生成和解析XML  

为减少DOM、SAX的编码量,出现了JDOM;优点:20-80原则,极大减少了代码量。使用场合:要实现的功能简单,如解析、创建等,但在底层,JDOM还是使用SAX(最常用)、DOM、Xanan文档。

    
package com.alisoft.facepay.framework.bean;    

import java.io.FileNotFoundException;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.util.List;  

import org.jdom.Document;  
import org.jdom.Element;  

posted @ 2009-12-02 21:16 TonyZhangtl 阅读(229) | 评论 (0)编辑 收藏


2007-07-15 11:33

关于JAXP,DOM,SAX,JDOM,DOM4J的一些想法

这些API是XSLT的关键部分,它们构建在DOM和SAX解析器基础上。

Sun在XML领域总是后知后觉,等到Sun重视XML的时候,XML的API早就满天飞了,尤其是IBM具有非常大的领先优势。不过Sun是规范 的制订者,于是参考WOffice:smarttags" />3C的标准制订了JAXP规范。JAXP不像Xerces和Crimon那样,它只是一个spec,本身是不做任何事情的,它的作用就是提出一 个统一的接口,让其它的XML API都来遵循JAXP编程,那么用JAXP写出来的程序,底层的API可以任意切换。

具体来说JAXP包括了几个工厂类,这就是JDK1.4里面的Javax.xml.parsers 包,用来寻找符合DOM标准的XML API实现类的位置;此外JAXP还包括一整套interface,这就是JDK1.4里面的org.w3c.dom那几个包。工厂类负责加载DOM的实 现类。

当你严格采用JAXP编程的时候,是遵循W3C的DOm标准的,那么在JAXP底层你实际上可以任意切换不同的DOM实现,例如Xerces,或者Crimon,再或者其它,切换方法就是配置jaxp.properties。因此JAXP就是一些标准接口而已。

JAXP应用程序 -> JAXP接口 -> Xerces DOM实现 -> Xerces DOM/SAX 解析器
JAXP应用程序 -> JAXP接口 -> Crimson DOM实现 -> Crimson DOM/SAX 解析器
JAXP应用程序 -> JAXP接口 -> Crimson DOM实现 -> Xerces DOM/SAX 解析器

W3C的DOM标准API难用的让人想撞墙,于是有一帮人开发Java专用的XML API目的是为了便于使用,这就是jdom的由来,开发到一半的时候,另一部分人又分了出来,他们有自己的想法,于是他们就去开发dom4j,形成了今天 这样两个API,至于他们之间的性能,功能之比较看看上面我推荐的文章就知道了,jdom全面惨败。

jdom 相当于上面的 JAXP接口 + Xerces DOM实现部分,它本身没有解析器,它可以使用Xerces或者Crimson的解析器即
JAXP应用程序 -> JAXP接口 -> Xerces DOM实现 -> Crimson DOM/SAX 解析器 或 Xerces DOM/SAX 解析器

jdom应用程序 -> jdom API -> Xerces/Crimson解析器
dom4j应用程序 -> dom4j API -> Xerces/Crimson解析器
dom4j应用程序 -> dom4j API -> Alfred2解析器

因此可以看出采用dom4j/jdom编写的应用程序,已经不具备可移植性了

Sun是JAXP标准的制订者,甚至很执著的在JDK1.4里面绑定Crimson DOM实现和解析器,然后可笑的是,Sun自己的JAXM RI竟然不是用JAXP写出来的,而是dom4j

我的举例:

1.   仅仅是XSL转换。XMLàHTML,通过XSL

Import javax.xml.transform.TransformerFactory;

Import javax.xml.transform.Transformer;

Import javax.xml.stream.StreamSource;

Import javax.xml.stream.StreamResult;

import java.io.FileOutputStream;

TransformerFactory transFactory = TransformerFactory.newInstance();

Transform transformer = transFacyory.newTransformer(new StreamSource(XMLSheetName));

Transformer.transform(new StreamSource(XMLFileName),new StreamResult(new FileOutputStream(outputURL)));

这里的stream是一个DOM对象。
我感觉这个就是JAXP应用程序 -> JAXP接口 -> Xerces DOM实现 -> Xerces DOM/SAX 解析器,不知道对不对。

2.遍历XML,通过DOM。不仅仅是XSL转换。中间有对XML元素内容的操作。
Import javax.xml.transform.TransformerFactory;

Import javax.xml.transform.Transformer;

Import javax.xml.stream.StreamSource;

Import javax.xml.stream.StreamResult;

import java.io.FileOutputStream;

//Xerces解析器来完成DOM遍历XML.DOMParser是Xerces包的一部分。

Import org.apache.xerces.parsers.DOMParser;

Import org.w3c.dom.Document;

Import org.w3c.dom.NodeList;

//DOM遍历XML

DOMParser parser = new DOMParser();

Parser.parse(XMLFileName);//解析并在内存中创建XML树。

Document document = parser.getDocument();//通过Document对象,可以使用内存中的树。

NodeList products = document.getElementByTagName(“product_id”);

Int num_products = products.getLength();

//XSL转化器

TransformerFactory transFactory = TransformerFactory.newInstance();

Transform transformer = transFacyory.newTransformer(new StreamSource(XMLSheetName));

Transformer.transform(new StreamSource(XMLFileName),new StreamResult(new FileOutputStream(outputURL)));

我感觉XSL转化和对XML对象的操作是两个过程。可以分别对待。最重要的是对对象的操作。这也就是为什么有DOM,JDOM,DOM4J。转化好像只需要JAXP就可以了,关心的是StreamSource和StreamResult。这两个是DOM对象。


3.JDOM使用,生成Document内容并保存到XML文件。
import org.jdom.Element;
import org.jdom.Document;//和Import org.w3c.dom.Document对比一下。一个是JAXP的一个是JDOM的Document

import org.jdom.output.XMLOutputter;

Element root = Element(“orders”);

root.addContent(“ ”);

org.jdom.Document document = new Document(root);//创建JDOM树。

FileOutputStream outStream = new FileOutputStream(XMLFileName);

XMLOutputter outToFile = new XMLOutputter();

outToFile.output(document,outStream);

outStream.flush();

outStream.close();

jdom应用程序 -> jdom API -> Xerces/Crimson解析器
VS
JAXP应用程序 -> JAXP接口 -> Xerces DOM实现 -> Xerces DOM/SAX 解析器

这里的没有Transform的过程,直接把Document的内容存到XML中。没有XSL转化,没有XSL文件。

JDOM提供了几种输出方法。这里XMLOutputter是保存到文件,输出一个实际的XML流。还有DOMOutputter,在内存中创建一个传统的DOM树。还有SAXOutputter,创建一串SAX事件以便被其他对象读取。



4.JDOM使用,读取已有的XML然后生成Document,修改Document
import org.jdom.Element;
import org.jdom.Document;

import org.jdom.output.XMLOutputter;
    import org.jdom.input.SAXBuilder;

    SAXBuilder builder = new SAXBuilder();
    Document document = builder.build(XMLFileName);

Element order = Element(“orders”);

orders.addAttribute(“order_id”,session_id);

Element root = document.getRootElement();//root是已经存在的根元素。

Root.addContent(order);//在根元素里增加orders元素。

//把document保存到文件中。

FileOutputStream outStream = new FileOutputStream(XMLFileName);

XMLOutputter outToFile = new XMLOutputter();

outToFile.output(document,outStream);

outStream.flush();

outStream.close();

即使创建一个DOM式的结构,这里仍使用SAXBuilder来做这这件事情。

DOMBuilder和SAXBuilder中的”DOM”和”SAX”指的是用于建立文档的方法,而不是生成的内容。

5.XSL转换,能把DOM对象转化成输出,也可以向上面所举例的把XMLFileName的流转化成输出的流(文件或屏幕显示)。但是不能把JDOM对象转化,所以需要把JDOM转化成DOM对象,然后再输出。
import org.jdom.Element;
import org.jdom.Document;

import org.jdom.output.XMLOutputter;
    import org.jdom.input.SAXBuilder;  
    //XSL转化需要的包
import org.jdom.output.DOMOutputter;//对比org.jdom.output.XMLOutputter;
Import javax.xml.transform.TransformerFactory;

Import javax.xml.transform.Transformer;

Import javax.xml.transform.DOMSource;//对比Import javax.xml.stream.StreamSource;

Import javax.xml.stream.StreamResult;

   org.w3c.dom.Document DOMDoc;
   DOMOutputter DomOut = DOMOutputter();
   DOMDoc = DomOut.output(org.jdom.Document);//把jdom的document转化成DOM的document

   TransformFactory transFactory = TransformFactory.newInstance();
   Transformer transformer = transFactory.newTransformer(new DOMSource(DOMDoc));//感觉错了,应该是XSL文件。
   Transformer.transform(new DOMSource(DOMDoc),new StreamResult(out));

//对比以前的转化,是从文件到文件,现在是DOM树到屏幕输出。
TransformerFactory transFactory = TransformerFactory.newInstance();

Transform transformer = transFacyory.newTransformer(new StreamSource(XMLSheetName));

Transformer.transform(new StreamSource(XMLFileName),new StreamResult(new FileOutputStream(outputURL)));

posted @ 2009-12-02 21:14 TonyZhangtl 阅读(487) | 评论 (0)编辑 收藏

SAX是基于事件流的解析,DOM是基于XML文档树结构的解析。
dom优点:整个文档树在内存中,便于操作;支持删除、修改、重新排列等多种功能;缺点:将整个文档调入内存(包括无用的节点),浪费时间和空间;使用场合:一旦解析了文档还需多次访问这些数据;硬件资源充足(内存、CPU)。
SAX ,事件驱动。当解析器发现元素开始、元素结束、文本、文档的开始或结束等时,发送事件,程序员编写响应这些事件的代码,保存数据。优点:不用事先调入整个 文档,占用资源少;SAX解析器代码比DOM解析器代码小,适于Applet,下载。缺点:不是持久的;事件过后,若没保存数据,那么数据就丢了;无状态 性;从事件中只能得到文本,但不知该文本属于哪个元素;使用场合:Applet;只需XML文档的少量内容,很少回头访问;机器内存少;

posted @ 2009-12-02 21:13 TonyZhangtl 阅读(252) | 评论 (0)编辑 收藏