posts - 7, comments - 2, trackbacks - 0, articles - 6
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

2007年11月3日


 什么是 Java 技术?  
Java 技术(版本 2)是一种面向对象的编程语言,是 Sun Microsystems 所开发的编程平台。Java 技术基于单一 Java 虚拟机(JVM)的概念,JVM 是编程语言与机器底层软件和硬件之间的翻译器。编程语言的所有实现都必须模拟 JVM,从而使 Java 程序可以在具有 JVM 版本的任何系统上运行。

Java 编程语言是与众不同的,因为 Java 程序需要经过编译(翻译为叫做 Java 字节码的中间语言)和解释(通过 JVM 分析和运行字节码)。编译只进行一次,而解释则在每次运行程序时都要进行。编译的字节码是 JVM 的最佳机器码形式;解释程序是 JVM 的实现。

Java 平台具有三个版本(请参阅下面的 Java 平台的多个版本),该平台由 JVM 和 Java Application Programming Interface (API) 组成,Java API 是现成软件组件的集合,便于进行 applet 和应用程序的开发和部署,其中包括健壮的、安全的和可互操作的企业应用程序。Java API 被分组到相关类和接口的库中;这些库称为包。

了解更多信息:

要了解 Sun 的 Java 编程语言的未来发展方向,请阅读 2003 JavaOne Developer Conference 的 technical keynote digest。 
Java 平台的多个版本
因为 Java 技术的迅速普及,开发人员强烈要求某些东西更简单些。Sun Microsystems 通过创建三个 Java 平台版本来满足此需要 ― Standard Edition、Enterprise Edition 和 Micro Edition。

了解更多信息:

J2SE (Java 2 Standard Edition)。包括标准的 Java 2 SDK、工具、运行时环境和 API,用于那些采用 Java 程序设计语言编写、部署和运行 applet 和应用程序的开发人员。 Merlin 的魔力 专栏极好地介绍了最新版本的 J2SE 1.4。


J2EE (Java 2 Enterprise Edition)。通过基于标准化模块组件,通过为这些组件提供一整套服务,以及通过自动处理应用程序行为的许多细节,而无需进行复杂编程,企业版简化了多层企业应用程序的构造和部署。J2EE 探索者 专栏将增加您对此版本的了解。


J2ME (Java 2 Micro Edition)。该版本是高度优化的 Java 运行时环境,针对特定的消费者领域,从智能型手机或寻呼机到机顶盒等一系列小型设备(外形小或者存储能力受限)。在“ J2ME 101,第 1 部分:介绍 MIDP 的高层 UI”教程中可以了解更多关于 J2ME 的信息。(您还可以在 developerWorks 无线 专题找到许多 J2ME 参考资料。) 
 
 
 到页首  
 
 
  Java 技术为什么重要?  
总体来说,Java 语言的主要优点在于跨平台和操作系统的可移植性,以及它可以通过带宽相对较窄的通道提供(比如拨号连接)。Java 语言还具有可伸缩性;现有应用程序可以很容易地适应那些受内存资源限制的设备。另外,由于 Java 语言设计用于通过网络以安全的方式运行,所以当通过 Internet 操作时,它也提供了此级别的安全性。本质上,Java 技术将用户计算能力从桌面扩展到了 Web 资源。
 
 
 到页首  
 
 
  什么是 Java 组件技术?  
管理 Java 技术缩略词的字母汤(alphabet soup)可能是一项巨大的任务,就正如通过 Java Community Process 管理 Java 语言的发展一样。下面是 Java 语言各版本的组件、可选包和扩展包的部分列表(也就是组成这个平台的复杂部件),并给出了简短描述和参考资料链接,用以说明它在 Java 开发领域中的作用。注意下面许多参考资料都可以在各版本中使用。

J2SE 中的技术:

Java Access Bridge 用于 Microsoft Windows,它起到了网桥的作用,允许基于 Windows 的辅助技术与 Java Accessibility API 进行交互(请参阅“为可访问性编码”。)


JavaBeans Component Architecture 是平台独立的规范,它为 Java 平台定义了一套标准组件软件 API。(请参阅“Reflecting, introspecting, and customizing JavaBeans”。)


Javadoc 是一种工具,用于从源代码的 doc 注释中生成 HTML 格式的 API 文档。(请参阅“Java 理论和实践:我必须对那些内容进行文档编制吗?”。)


Java Foundation Classes (Swing) (JFC) 是 Java 类库的集合,它支持为基于 Java 的客户机应用程序构建 GUI 和图形功能。(请参阅“Java 2 用户界面”。)


Java Platform Debugger Architecture (JPDA) 是 Java 2 的调试支持基础设施。JPDA 包括三层 API: 
JDI (Java Debug Interface)是一种支持远程调试的高级别编程语言接口。 
JDWP (Java Debug Wire Protocol) 定义在调试过程和调试器前端之间传输的信息和请求的格式。 
JVMDI (Java Virtual Machine Debug Interface) 是低级别本地接口,定义了调试时 JVM 必须提供的服务。 
(请参阅“ 软件开发的未来 ”。)

Java 2D API 是用于高级 2D 图形和成像(为图像合成和 alpha 通道图像提供广泛支持)的类集合,是提供正确的色彩空间定义和转换的类集合,是面向显示的成像操作符的集合。(请参阅教程“Java 2D简介”。)


Java Web Start 使您可以通过单击而无需经历安装过程来下载和启动功能完善的应用程序(如电子表格),从而简化 Java 应用程序的部署。(请参阅“Java Web Start”。)


Java Database Connectivity (JDBC) 是一种 API,使您可以从 Java 内访问大多数表格式数据源,它提供了大多数 SQL 数据库的跨 DBMS 连通性,以及对其他表格式数据源的访问(如电子表格或平面文件)。(请参阅“JDBC 3.0 有什么新特性”。)


Remote Method Invocation (RMI) 提供引导命名服务,不会改变类型,并使用对象序列化使编程人员能够创建基于 Java 技术的分布式应用程序,在该应用程序中,可以从不同主机上的其他 Java 虚拟机上调用远程 Java 对象的方法。(请参阅教程“分布式对象 101-使用RMI和CORBA ”。)


Java Advanced Imaging (JAI) 是一种 API,提供了面向对象的接口的集合,这些接口支持简单的高级编程模型,使得开发人员可以很容易地操纵图像。(请参阅“利用 JSP 代码管理您的图像”。)


Java Authentication and Authorization Service (JAAS) 是一个包,它启用服务,通过实现标准 Pluggable Authentication Module (PAM) 框架的 Java 版本,通过支持基于用户的授权,对用户进行验证和执行访问控制。(请参阅教程“Java 安全性 第二部分 认证与授权”;“扩展 JAAS 实现类实例级授权”也是很好的信息来源。)


Java Cryptography Extension (JCE) 是一个包集合,提供了加密、密钥生成和协议以及 Message Authentication Code (MAC) 算法的框架和实现。它提供了对称、非对称、分组和流密码的加密支持,并支持安全流和密封对象。(请参阅教程“Java 安全性第一部分 密码学基础”。)


Java Data Objects (JDO) 是持久性的基于标准接口的 Java 模型抽象,它允许编程人员直接将 Java 域模型实例存储到持久存储(数据库)中,可能替代直接文件输入输出、序列化、JDBC 和 EJB Bean Managed Persistence (BMP) 或 Container Managed Persistence (CMP) Entity Bean 等方法。(请参阅教程“Java 数据对象上机实践”。)


Java Management Extensions (JMX) 提供的工具用于构建分布式、基于 Web 的、模块化和动态应用程序,以便管理和监视设备、应用程序和服务驱动的网络。(请参阅由三部分组成的“从黑箱到企业,第 1 部分:管理,JMX 1.1 样式”。)


Java Media Framework (JMF) 允许音频、视频和其他基于时间的媒体添加到 Java 应用程序和 applet 中。(请参阅教程“Java Media Framework 基础”。)


Java Naming and Directory Interface (JNDI) 是一种标准扩展包,为企业中的多个命名和目录服务提供具有统一接口的 Java 应用程序,允许不同种类的企业命名和目录服务的无缝连通性。(请参阅“EJB 最佳实践:工业强度的 JNDI 优化”。)


Java Secure Socket Extensions (JSSE) 是启用安全 Internet 通信的包集合,实现 SSL (Secure Sockets Layer) 和 TLS (Transport Layer Security) 协议的 Java 版本,并包括数据加密、服务器验证、消息完整性和可选客户机验证的功能。(请参阅教程“将 JSSE 用于安全套接字通信”。)


Java Speech API (JSAPI) 允许 Java 应用程序将语音技术合并到用户接口中。JSAPI 定义了跨平台的 API,以支持命令和控制识别程序、听写系统和语音合成器。(请参阅“The Java 2 user interface”部分。)


Java 3D 是一种 API,通过提供支持简单高级编程模型的一组面向对象的接口,开发人员可以使用它容易地将可伸缩的平台独立的 3D 图形合并到 Java 应用程序中。(请参阅教程“Java 3D 探奇 ”。) 
J2EE 中的技术:

Java API for XML Processing (JAXP) 通过使应用程序解析和转换不依赖特定 XML 处理实现的 XML 文档,通过使开发人员可以灵活地在 XML 处理器程序之间进行交换,而无需更改应用程序代码,从而支持使用 DOM、SAX 和 XSLT 处理 XML 文档。(请参阅“使用 Java 编程利用在线 XML 数据”。)


Java API for XML Registries (JAXR) 为访问不同种类的 XML 注册中心提供了统一和标准的 API (用于构建、部署和发现 Web 服务的可用基础设施)。(请参阅 Java 技术标准。)


Java API for XML-based RPC (JAX-RPC) 使开发人员可以开发基于 SOAP 的可互操作的和可移植的 Web 服务。(请参阅 Java 技术标准。)


SOAP with Attachments API for Java (SAAJ) 使开发人员可以生产和消费符合 SOAP 1.1 规范和 SOAP with Attachments 注解的消息。(从“使用SAAJ发送和接收SOAP消息”开始;有关 XML 技术的详细信息,请参阅 developerWorks XML 专区。)


Common Object Request Broker Architecture (CORBA) 是异构计算的开放标准,通过提供分布式对象框架、支持该框架的服务以及与其他语言的互操作性,该标准对 Java 进行了补充。(请参阅教程“使用RMI和CORBA ”;“企业中的 RMI-IIOP”也是很好的信息来源)。


ECperf 是用于度量 Web 商务系统的性能和可伸缩性的基准。它包括:组成应用程序的 EJB 组件;使用 JSP 进行单一用户/交互测试的 Web 客户机;模式脚本和加载程序;makefile 和部署描述符;用于实现运行规则和模拟客户机加载的驱动程序。(请参阅 Java 技术标准。)


Enterprise JavaBeans (EJB) 是一种技术,通过提供对事务、安全性、数据库连通性等服务的支持,它使用组件模型来简化中间件应用程序的部署。(请参阅介绍该技术的教程“Enterprise JavaBean 基础”;另请参阅系列文章 EJB 最佳实践。)


Java Authorization Contract for Containers (Java ACC) 是一种规范,它定义了容器使用的授权提供者的安装和配置。Java ACC 定义了提供者必须使用的接口,从而允许容器部署工具创建和管理与角色相对应的权限集合。(请参阅教程“Developing accessible GUIs with Swing”。)


JavaMail 是一种 API,它提供了模拟邮件系统的抽象类的集合。(请参阅教程“ JavaMail API 基础”。)


Java Message Service (JMS) 是一种用来添加提供者框架的 API。通过定义所有兼容 JMS 技术的消息系统所支持的消息概念和编程策略的公共集合,该框架为 Java 平台启用了可移植的、基于消息的应用程序的部署。(请参阅“实现独立于供应商的 JMS 解决方案”。)


JavaServer Faces 提供了一种编程模型,通过汇集页面中可重用的 UI 组件,将这些组件连接到应用程序数据源以及将客户机生成的事件写入服务器端事件处理程序,该模型有助于开发人员开发 Web 应用程序。(请参阅“JSP pages, evolving and contributing to Web services”。)


JavaServer Pages (JSP) 使 Web 开发人员可以使用单独的用户界面和内容生成功能,快速地进行开发和轻松地维护动态的、平台独立的 Web 页面,这样设计人员就可以更改页面布局,而无需改变动态内容。该技术使用类似于 XML 的标签,这些标签封装了用于生成页面内容的逻辑。(请参阅教程“JSP 技术入门 ”;另请参阅系列文章 JSP 最佳实践。)


Java Servlets 是一种扩展和增强 Web 服务器功能的 Java 方式。要做到这一点,应该为构建基于 Web 的应用程序提供基于组件的平台独立的方法,而不会出现 CGI 程序的性能限制。(developerWorks 中有许多关于 servlet 的信息。“创建 Java HTTP Servlet”和“构建带会话跟踪的 Servlet”这两篇入门教程应该是最好的起点。)


J2EE Connector Architecture 定义了一种标准体系结构,通过定义一组可伸缩的、安全的事务性机制,允许 EIS 供应商提供插入到应用服务器中的标准资源适配器,该体系结构用于将 J2EE 平台连接到异构企业信息系统(Enterprise Information Systems, EIS)。(请参阅教程“J2EE Connector Architecture 介绍”。)


J2EE Management Specification (JMX) 定义了 J2EE 平台的管理信息模型。该模型设计用于与许多管理系统和协议互操作,包括到 Common Information Model (CIM)、SNMP Management Information Base (MIB)的模型的标准映射,以及通过服务器驻留 EJB 组件(J2EE Management EJB Component,MEJB)到 Java 对象模型的模型的标准映射。(请参阅“从黑箱到企业,第 1 部分:管理,JMX 1.1 样式”。)


Java Transaction API (JTA) 是高级的独立于实现和协议的 API,它允许应用程序和应用程序服务器访问事务。Java Transaction Service (JTS) 指定 Transaction Manager 的实现, Transaction Manager 支持 JTA,并在低于 API 的级别上实现 OMG Object Transaction Service (OTS) 1.1 规范的 Java 映射。JTS 使用 Internet Inter-ORB Protocol (IIOP) 传输事务。(请参阅“理解 JTS ― 平衡安全性和性能 ”。) 
J2ME 中的技术:

Connected Limited Device Configuration (CLDC) 是组成资源受限移动信息设备的 Java 运行时环境的两个配置之一。CLDC 提供了最基本的库集合和虚拟机功能,在包含 K 虚拟机(KVM)的 J2ME 环境的每个实现中,这些都是必须存在的。(请参阅“Know no limits: Approaches to mobile device constraints”)


Mobile Information Device Profile (MIDP) 是组成资源受限移动信息设备的 Java 运行环境的两个配置之一。MIDP 提供核心应用程序功能,包括用户界面、网络连通性、本地数据存储和应用程序生命周期管理。(请参阅教程“Implementing Push technology with J2ME and MIDP”。)


Connected Device Configuration (CDC) 是一种基于标准的框架,用于构建和提供可在许多网络连接消费者和嵌入式设备之间共享的应用程序。(请参阅“Securing wireless J2ME”。)


developerWorks Wireless technology 专区包含了 J2ME 相关技术的多篇文章和教程。 
Java 网络技术:

JAIN APIs 是一组基于 Java 的 API,用于快速开发下一代电信产品和服务。(请参阅 Java 技术标准。) 



Java Metadata Interface (JMI) 是实现动态的、平台独立的基础设施的规范,它允许进行元数据的创建、存储、访问、发现和交换。该规范基于 Object Management Group (OMG) 的 Meta Object Facility (MOF) 规范,由一组使用统一建模语言(Unified Modeling Language,UML)描述的基本建模工件组成。(请参阅 Java 技术标准。)


JavaGroups 是一个软件工具包(API 库),用于使用分布式系统解决方案进行设计、实现和实验。(请参阅“High-impact Web tier clustering, Part 1”和 Part 2。)


Jini 是一种开放体系结构,用于为硬件和软件创建高适应性的以网络为中心的服务。Jini 系统体系结构由三个类别组成:编程模型、基础设施和服务。(请参阅“Jini networking technology, the next step”。)


JXTA 是一组开放协议,允许网络上所有连接设备以 P2P 方式通信和协作。JXTA 对等方创建虚拟网络,任何对等方都可以在其中与其他对等方或资源进行直接交互,甚至当一些对等方和资源位于防火墙或 NAT 后或者位于不同的网络传输中也是如此。(请参阅“Making P2P interoperable: The JXTA story”。) 
 
 
 到页首  
 
 
 Java 技术如何与 Web 服务联系起来?  
Web 服务是一种技术,允许用 XML 定义业务规则和过程,这样软件应用程序能够以平台独立和编程语言无关的方式进行通信。XML 技术使数据可以移植,方便了消息创建,而 Java 技术则使代码可以移植。事实上,XML 和 Java 语言可以很好地结合起来,成为构建和部署 Web 服务的完美组合。

了解更多信息:

developerWorks 的“Web services 新手入门”和“XML 新手入门”页面将帮助您了解这些复杂的技术。 
 
 

 
 
 如何提高 Java 编程技能?  
有两种途径可以提高您的技能:选学一门课程(为获得证书或仅为了学习)或者自学(当然要通过编写代码来练习)。除了汲取有经验的开发人员的知识外,获取证书途径还可以向未来的雇主提供确实的证据,证明您拥有构建他们要求的技术所需的技能。通过试验自己的技能,使用可用资源,您可以在 Java 技术的不同领域提高您的技能。下列参考资料对以上两种途径都应该有帮助。 

了解更多信息:

要获得 Java 语言的全面介绍,Java 语言基础 教程是个很好的起点。


如果基本教程看起来有些复杂,您可以尝试 Robocode。Robocode 是基于 Java 技术构建的易于使用的机器人战争模拟程序,它在提供纯粹娱乐的同时教您如何编程。要获得 Robocode 的介绍,请阅读“重锤痛击 Robocode!”


如果您是 C/C++ 编程人员,不熟悉 Java,“Java programming for C/C++ developers”教程通过比较和对照 Java 编程概念和 C/C++ 编程概念,可以帮助您快速入门 Java。


本文是循序渐进的 帮助您准备 SCJP 考试指南,即 Sun Certified Java Programmer 证书考试。


IBM 在 WebSphere 开发(用于企业 Java 应用程序)、DB2、XML、电子商务和 Linux 这些相关技术方面提供了 专业认证。


如果您没有听说过 XP 精华 或 XP,它是一种应用程序设计理念,它合并了连续阶段测试、在编码前编写测试、现场客户输入、重构(在不更改功能的情况下改进代码)等,本文可提供用于编写 Java 应用程序的极好工具。(揭开极端编程的神秘面纱:“XP 精华”重访,第 2 部分 中详细描述了如何进行实践。)


将设计理论转换为实际应用程序是 Java 理论与实践 系列文章的出发点。


Java 编程人员知道利用集成 bug 检测和测试进行程序设计,所以利用 Java 调试 提高您的调试技能。而且,developerWorks 提供了关于 Java 调试(重点是称为 bug 模式的工具)的专栏集,称为 诊断 Java 代码。


developerWorks 提供了大量 基于 Java 的教程,这是下一代自己编写代码的最佳学习体验。


要获得更多学习如何使用 Java 语言的交互式方法,请参加 Java 讨论区,该论坛由具有多年 Java 相关技术开发经验的著名专家主持。 
 
 
  
 
 
  Java 编程人员可以使用哪些 IBM 工具和产品?  
作为在 Java 技术使用方面的一流创新者,IBM 站在了最前线。浏览 Java technology downloads and products 页面可以获得工具和产品的完整列表。以下提供了一些重要部分。

了解更多信息:

软件开发工具箱:构造应用程序的工具箱,用于各种 Java 相关技术的大量工具。下面只是其中的几个: 
IBM developer kits for Java technology,用于在一些最普通的 IBM 平台上创建和测试 Java applet 和应用程序。 
Agent Building and Learning Environment,用于开发混合智能软件代理和代理应用程序。 
Emerging Technologies Toolkit 在网格计算、异步 Web 服务、业务流程、自主计算和其他服务中为 Web 服务开发提供高级工具。 
Toolkit for MPEG-4,Java 类和带有简单应用程序的 API 的集合,用于生成 MPEG-4 内容,以便与兼容 MPEG-4 的设备一起使用。 
Update Tool,一种使基于 Java 桌面应用程序的用户可以易于升级的机制。


Java technology on alphaWorks 是 IBM 生成的 Java 相关技术的虚拟仓库,包括 API、集成开发环境和 devkit、组件、参考实现和实用程序。


WebSphere 系列的 Java 开发工具: 
Application Server。 
Branch Transformation Toolkit for WebSphere Studio,以前称为 WebSphere Business Components Composer,是一组工具、组件和服务,它们用于加速构建访问事务系统的多通道银行应用程序。 
MQ 是允许应用程序相互通信的应用程序编程服务。 
MQ Everyplace 允许利用确定的消息提供方式访问移动工作者和远程设备的企业数据。 
Business Integration Message Broker 帮助将信息引向需要它的位置和时间,以及帮助访问公司数据,而不管数据位于何处,采用何种格式。 
SDK for Web Services。 
Studio Site Developer 为构建和维护动态 Web 站点、Web 服务和 Java 应用程序提供开发环境。 
Studio Application Developer 是基于 Web 的应用程序的集成开发环境。 

posted @ 2007-11-03 22:01 卓韦 阅读(604) | 评论 (0)编辑 收藏

2007年9月25日

需要下载fileupload和beanutils两个包,代码如下。

实现文件的上传,代码如下:
<%!
 //服务器端保存上传文件的路径
    String saveDirectory = "g:\\upload\\";
    // 临时路径 一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录
    String tmpDirectory = "g:\\upload\\tmp\\";
    // 最多只允许在内存中存储的数据大小,单位:字节
    int maxPostSize = 1024 * 1024;
%>
<%
    // 文件内容 
    String FileDescription = null;
    // 文件名(包括路径)
    String FileName = null;
    // 文件大小
    long FileSize = 0;
    // 文件类型
    String ContentType = null;

%>

<%
   DiskFileUpload fu = new DiskFileUpload();
    // 设置允许用户上传文件大小,单位:字节
   fu.setSizeMax(200*1024*1024);
    // 设置最多只允许在内存中存储的数据,单位:字节
   fu.setSizeThreshold(maxPostSize);
    // 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录
   fu.setRepositoryPath("g:\\upload\\tmp\\");
    //开始读取上传信息 得到所有文件
   try{
      List fileItems = fu.parseRequest(request);
     }catch(FileUploadException e){
         //这里异常产生的原因可能是用户上传文件超过限制、不明类型的文件等
         //自己处理的代码
     }
%>
<%
   // 依次处理每个上传的文件
   Iterator iter = fileItems.iterator();
   while (iter.hasNext()) {
     FileItem item = (FileItem) iter.next();
       //忽略其他不是文件域的所有表单信息
     if (!item.isFormField()) {
       String name = item.getName();
       long size = item.getSize();
       String  contentType = item.getContentType();
     if((name==null||name.equals("")) && size==0)
       continue;
%>
<%
   //保存上传的文件到指定的目录
  String[] names=StringUtils.split(name,"\\");  //对原来带路径的文件名进行分割
   name = names[names.length-1];
   item.write(new File(saveDirectory+ name));
  }
}
%>
 下面是其简单的使用场景:
 A、上传项目只要足够小,就应该保留在内存里。
 B、较大的项目应该被写在硬盘的临时文件上。
 C、非常大的上传请求应该避免。
 D、限制项目在内存中所占的空间,限制最大的上传请求,并且设定临时文件的位置。
 
 可以根据具体使用用servlet来重写,具体参数配置可以统一放置到一配置文件
 

 文件的下载用servlet实现
      public void doGet(HttpServletRequest request,
                       HttpServletResponse response)
     {
         String aFilePath = null;    //要下载的文件路径
         String aFileName = null;    //要下载的文件名
         FileInputStream in = null;  //输入流
         ServletOutputStream out = null;  //输出流

 

         try
   {
          
             aFilePath = getFilePath(request);
             aFileName = getFileName(request);

             response.setContentType(getContentType(aFileName) + "; charset=UTF-8");
             response.setHeader("Content-disposition", "attachment; filename=" + aFileName);

             in = new  FileInputStream(aFilePath + aFileName); //读入文件
            out = response.getOutputStream();
            out.flush();
            int aRead = 0;
           while((aRead = in.read()) != -1 & in != null)
        {
             out.write(aRead);
         }
           out.flush();
      }
       catch(Throwable e)
     {
     log.error("FileDownload doGet() IO error!",e);
      }
         finally
         {
             try
             {
                 in.close();
                 out.close();
             }
             catch(Throwable e)
             {
              log.error("FileDownload doGet() IO close error!",e);
             }
         }
     }



参考文献:
1、用fileupload处理文件上传
作者:◇ 刘冬 发文时间:2003.07.09 15:52:43 ,http://tech.ccidnet.com/pub/disp/Article?columnID=322&articleID=53966&pageNO=1
讲得非常清楚
2、Jakarta Commons:巧用类和组件1 (2) 作者:Vikram Goyal 仙人掌工作室译 ,http://www.uml.org.cn/j2ee/j2eeh2.htm

3、Jsp如何实现网页的重定向 ,2002-05-16· ·包路跃··Yesky,http://www.yesky.com/SoftChannel/72342371945283584/20020424/1608521.shtml

4、判断文件或文件夹是否存在,作者:罗会涛,http://www.fawcette.com/china/XmlFile.aspx?ID=205

5、java.util中的Date类,By Wing, 出处:处处,http://www.linuxaid.com.cn/articles/1/1/119413536.shtml

6、计算Java日期--学习怎样创建和使用日期,作者:Robert Nielsen ,http://www.javaresearch.org/article/showarticle.jsp?column=1&thread=497

7、http://dev.csdn.net/article/67/67940.shtm

posted @ 2007-09-25 13:26 卓韦 阅读(5500) | 评论 (1)编辑 收藏

Jakarta Commons FileUpload 用户指南

本文是分享文档站长胡萝卜的作品。大家可以自由阅读、在网络上进行分发,前提是必须保留本文档的完整性。
分享文档是一家专业的Java技术网站,给中国Java 程序员提供各种Java资源如文档,工具,教程,社区交流等。
我们的官方网站是:http://chinesedocument.com
我们的官方论坛是:http://bbs.chinesedocument.com
请大家多多关注分享文档,我们还会发布更多优秀的文档!

第1章 使用FileUpload
FileUpload能以多种方式使用,这取决于你的应用需求。举个简单的例子,你可能调用一个单独的方法来解析servelt的请求,并且处理那些项目。 从另一个方面来讲,你可能想自定义FileUpload来完全控制个别项目的存贮;例如,你想流化那些内容,并存到数据库里去。
这里我们会介绍使用FileUpload的基础原则,并描述一些简单的通用的使用模式。我们会在在其它地方介绍关于FileUpload的自定义。
FileUpload依赖于一些公用的IO,因此,要确保在你继续之前,你的classpath里已经有依赖页面里提起的那些版本。


第2章 FileUpload如何工作?
一个上传请求由一系列根据RFC1867("Form-based File Upload in HTML".)编码的项目列表组成。FileUpload可以解析这样的请求,并为你的应用提供那些已上传的项目的列表。每一个这样的项目都实现了FielItem接口,我们不用管它们的底层实现。
这个页面描述了commons fileupload库的常用API。这些常用API是非常方便的途径。然而,为了最好的性能,你可能更喜欢最快的Streaming API 。
每一个文件项目有一些自己的属性,这些属性也许正是你的应用程序感兴趣的地方。例如,每个项目有个一个名字和内容类型,并且可以提供一个输入流来访问它们的数据。另一方面来看,你可能需要用不同方式来处理不同的项目,这就依赖于那些项目是否是一个正常的表单字域,也就是说,这些数据来自于一个普通的文本框或类似HTML的字域,还是一个要上传文件字段。FileItem接口提供一些方法来做这样一个决定,并且用最合适的方法访问这些数据。
FileUpload使用FileItemFactory创建一个新的文件项目。这将会给FileUpload最好的灵活性。工厂最终控制每个项目如何被创建。默认的工厂在内存或者硬盘里存储项目的数据,这依赖于项目的大小(例如,有多少字节的数据。)。不过,为了适用于你的应用,你还是可以自定义这种行为的。


第3章 servlets and portlets
从V1.1版开始,FileUpload就开始支持servlet和portlet的文件上传请求。这两种环境的用法基本上差不多,因此,文档的剩下部分都将是在servlet环境里。
如果你正在构建一个portet应用,那么下面两个差别是你在读文档时应注意的:
你在哪里引用了ServletFileUpload类,就用PortletFileUpload类来替代它。
你在哪里引用了HttpServletRequest类,就用ActionRequest类替代它。


第4章 解析请求
在你同那些上传的项目一起工作前,你需要先解析请求本身。以确保这个请求确实是一个文件上传请求。FileUpload是通过调用一个静态方法来实现的。
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
现在,我们已经准备好解析请求里的项目了。

4.1 最简单的例子
下面是一些简单的使用场景:
􀁺   上传项目只要足够小,就应该保留在内存里。
􀁺   较大的项目应该被写在硬盘的临时文件上。
􀁺   非常大的上传请求应该避免。
􀁺   限制项目在内存中所占的空间,限制最大的上传请求,并且设定临时文件的位置。
处理这个场景的请求很简单:
// Create a factory for disk-based file items
FileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List /* FileItem */ items = upload.parseRequest(request);
这就是我们所需要的全部代码了!
解析的结果就是一个项目的List,每个项目都实现了FileItem接口。我们将在下面讨论如何处理这些项目。
4.2 训练如何控制
如果你的使用场景和上面那个简单的例子很接近,但是你又需要一点点控制,那么你可以很容易地定义upload处理器或者文件项目工厂的行为。下面这个例子显示了几个配置选项。
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Set factory constraints
factory.setSizeThreshold(yourMaxMemorySize);
factory.setRepository(yourTempDirectory);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Set overall request size constraint
upload.setSizeMax(yourMaxRequestSize);
// Parse the request
List /* FileItem */ items = upload.parseRequest(request);
当然,每个配置方法是独立于其它任意一个的。但是如果你想一次性配置他们,你可以用parseRequest()的另一个重载方法,像这样:
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory(
yourMaxMemorySize, yourTempDirectory);
如果你还想使用更多的控制,比如存储项目到其它地方(如,数据库),那么你可以看FileUpload自定义介绍。


第5章 处理上传的项目
一旦解析完成,那么你会得到一个待处理的文件项目列表。很多的情况下,你会想用不同的方式来处理文件上传域和正常的表单域,因此,你可以这样做:
// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext()) {
  FileItem item = (FileItem) iter.next();
  if (item.isFormField()) {
    processFormField(item);
  } else {
    processUploadedFile(item);
  }
}
对于普通的表单域来说,你可能对项目的名称和字符型值 很感兴趣。就像你希望的那样,照下面的做:
// Process a regular form field
if (item.isFormField()) {
  String name = item.getFieldName();
  String value = item.getString();
  ...
}
对于上传文件,这里就有很多不同啦~你可能想知道更多其它的内容。下面是个例子,里面包含了不少你感兴趣的方法。
// Process a file upload
if (!item.isFormField()) {
  String fieldName = item.getFieldName();
  String fileName = item.getName();
  String contentType = item.getContentType();
  boolean isInMemory = item.isInMemory();
  long sizeInBytes = item.getSize();
  ...
}
对于上传的文件,你肯定不希望总是通过内存来访问它,除非它很小,或者你实在没有别的选择余地了。你很希望使用流来处理文件内容或者将文件保存到它的最终位置。FileUpload提供简单的方式来完成两方面的需求。
// Process a file upload
if (writeToFile) {
  File uploadedFile = new File(...);
  item.write(uploadedFile);
} else {
  InputStream uploadedStream = item.getInputStream();
  ...
  uploadedStream.close();
}
注意:在FileUpload的默认实现中wirte()方法应该值得关注,如果数据还在临时文件里没有移除,那么这个方法就会试图重命名这个文件为相应的目标文件。事实上如果重命名失败了的话,数据就仅仅被拷贝。
如果你需要访问内存中的上传数据,你可以用get()方法来获得数据的二进制数组形式。
// Process a file upload in memory
byte[] data = item.get();
...

第6章 清除资源
这一节只适用于你使用了DiskFileItem。换句话说,它只适用于你在处理上传文件之前将上传文件写入过临时文件这种情形。
像这种临时文件会被自动删除, 如果它们不再被使用(更确切地说,java.io.File的实例已经被GC掉了。 )这是由org.apache.commons.io.FileCleaner类在后台完成的,它会启动一个收割机线程。
这个收割机线程在它不再被需要时会被停止。在servlet环境里,这是通过指定一个名叫FileCleanerCleanup的servlet上下文监听器来实现的。要做到这里,在你的web.xml增加下面的代码:
<web-app>
...
<listener>
<listener-class>
org.apache.commons.fileupload.servlet.FileCleanerCleanup
</listener-class>
</listener>
...
</web-app>
不幸的是,事情到这里还没完。如果你和下面的情况一样,那么你就只需要按照上面的做,就可以清除资源了。
你使用的是commons-io 1.3或者更晚的版本。
你是从web应用的web-inf/lib里载入commons-io的,并不是从其它位置,如Tomcat的common/lib下。
如果commons-io 1.3是从你的WEB容器的classpath里载入的,那么,下面的情况可能会出现:
建议你运行两个应用,一个叫A,一个叫B。(这两个应用可能是完全一样,只不过上下文名称不一样。)这两个应用都使用了FileCleanerCleanup。现在,如果你终止应用A,B还在运行,这时,A会终止B的收割机线程。换言之,你要十分仔细地考虑是使用FileCleanerCleanup,还是不使用。

第7章 观察上传进度
如果你希望可以上传很大的文件,这时,你可能想将上传的状态告诉用户,如已经接收了多少。
观察上传进度需要通过一个处理监听器来实现。
//Create a progress listener
ProgressListener progressListener = new ProgressListener(){
  public void update(long pBytesRead, long pContentLength, int pItems) {
    System.out.println("We are currently reading item " + pItems);
    if (pContentLength == -1) {
      System.out.println("So far, " + pBytesRead + " bytes have been read.");
    } else {
      System.out.println("So far, " + pBytesRead + " of " + pContentLength
      + " bytes have been read.");
    }
  }
};
upload.setProgressListener(progressListener);
上面这个监听器是有问题的。因为它非常频繁地被调用。这会带来性能问题。一个比较好的解决办法是,减少调用。例如,如果megabytes被改变,那么就发出一个消息。
//Create a progress listener
ProgressListener progressListener = new ProgressListener(){
  private long megaBytes = -1;
  public void update(long pBytesRead, long pContentLength, int pItems) {
    long mBytes = pBytesRead / 1000000;
    if (megaBytes == mBytes) {
      return;
    }
    megaBytes = mBytes;
    System.out.println("We are currently reading item " + pItems);
    if (pContentLength == -1) {
      System.out.println("So far, " + pBytesRead + " bytes have been read.");
    } else {
      System.out.println("So far, " + pBytesRead + " of " + pContentLength
      + " bytes have been read.");
    }
  }
};

posted @ 2007-09-25 13:15 卓韦 阅读(667) | 评论 (0)编辑 收藏

2007年9月24日

     摘要: Java 文件上传 java文件上传,介绍几种常用的方法,也是经过本人亲手调试过的 1.jspsmartupload 这个组件用起来是挺方便的,不过就是只适合小文件上传,如果大文件上传的话就不行,查看了一下他的代码,m_totalBytes = m_request.getContentLength(); m_binArray = new byte[m_totalBytes];...  阅读全文

posted @ 2007-09-24 22:59 卓韦 阅读(8648) | 评论 (1)编辑 收藏

2007年9月23日

配置文件

介绍
    每个 Linux 程序都是一个可执行文件,它含有操作码列表,CPU 将执行这些操作码来完成特定的操作。例如,ls 命令是由 /bin/ls 文件提供的,该文件含有机器指令的列表,在屏幕上显示当前目录中文件的列表时需要使用这些机器指令。几乎每个程序的行为都可以通过修改其配置文件来按照您的偏好或需要去定制。

Linux 中有没有一个标准的配置文件格式?
    一句话,没有。不熟悉 Linux 的用户(一定)会感到沮丧,因为每个配置文件看起来都象是一个要迎接的新挑战。在 Linux 中,每个程序员都可以自由选择他或她喜欢的配置文件格式。可以选择的格式很多,从 /etc/shells 文件(它包含被一个换行符分开的 shell 的列表),到 Apache 的复杂的 /etc/httpd.conf 文件。

什么是系统配置文件?
    内核本身也可以看成是一个“程序”。为什么内核需要配置文件?内核需要了解系统中用户和组的列表,进而管理文件权限(即根据权限判定特定用户(UNIX_USERS)是否可以打开某个文件)。注意,这些文件不是明确地由程序读取的,而是由系统库所提供的一个函数读取,并被内核使用。例如,程序需要某个用户的(加密过的)密码时不应该打开 /etc/passwd 文件。相反,程序应该调用系统库的 getpw() 函数。这种函数也被称为系统调用。打开 /etc/passwd 文件和之后查找那个被请求的用户的密码都是由内核(通过系统库)决定的。

    除非另行指定,Red Hat Linux 系统中大多数配置文件都在 /etc 目录中。

更改配置文件
    在更改配置文件时,如果程序不是由系统管理员或内核控制的,就要确保重新启动过使用该配置的程序。普通用户通常没有启动或停止系统程序和/或守护进程的权限。

内核
    更改内核中的配置文件会立即影响到系统。例如,更改 passwd 文件以增加用户将立即使该用户变为可用。而且任何 Linux 系统的 /proc/sys 目录中都有一些内核可调参数。只有超级用户可以得到对所有这些文件的写访问权力;其它用户只有只读访问权力。此目录中文件的分类的方式和 Linux 内核源代码的分类方式一样。此目录中的每个文件都代表一个内核数据结构,这些数据结构可以被动态地修改,从而改变系统性能。
注意:在更改其中任何文件的任何值之前,您应该确保自己全面了解该文件,以避免对系统造成不可修复的损害。

/proc/sys/kernel/ 目录中的文件

文件名 描述
threads-max 内核可运行的最大任务数。
ctrl-alt-del 如果值为 1,那么顺序按下这几个键将“彻底地”重新引导系统。
sysrq 如果值为 1,Alt-SysRq 则为激活状态。
osrelease 显示操作系统的发行版版本号
ostype 显示操作系统的类型。
hostname 系统的主机名。
domainname 网络域,系统是该网络域的一部分。
modprobe 指定 modprobe 是否应该在启动时自动运行并加载必需的模块。


守护进程和系统程序
    守护进程是永远运行在后台的程序,它默默地执行自己的任务。常见的守护进程有 in.ftpd(ftp 服务器守护进程)、in.telnetd(telnet 服务器守护进程)和 syslogd(系统日志记录守护进程)。有些守护进程在运行时会严密监视配置文件,在配置文件改变时就会自动重新加载它。但是大多数守护进程并不会自动重新加载配置文件。我们需要以某种方式“告诉”这些守护进程配置文件已经被发生了改变并应该重新加载。可以通过使用服务命令重新启动服务来达到这个目的(在 Red Hat Linux 系统上)。

    例如,如果我们更改了网络配置,就需要发出:
    service network restart。

    注意:这些服务最常见的是 /etc/rc.d/init.d/* 目录中存在的脚本,在系统被引导时由 init 启动。所以,您也可以执行如下操作来重新启动服务:
        /etc/rc.d/init.d/<script-for-the-service> start | stop | status
        start、stop 和 status 是这些脚本接受的输入值,用来执行操作。
[目录]

主机

/etc/host.conf
    告诉网络域名服务器如何查找主机名。(通常是 /etc/hosts,然后就是名称服务器;可通过 netconf 对其进行更改)

/etc/hosts
    包含(本地网络中)已知主机的一个列表。如果系统的 IP 不是动态生成,就可以使用它。对于简单的主机名解析(点分表示法),在请求 DNS 或 NIS 网络名称服务器之前,/etc/hosts.conf 通常会告诉解析程序先查看这里。

/etc/hosts.allow
    请参阅 hosts_access 的联机帮助页。至少由 tcpd 读取。

/etc/hosts.deny
    请参阅 hosts_access 的联机帮助页。至少由 tcpd 读取。


[目录]

引导和登录注销

/etc/issue & /etc/issue.net
    这些文件由 mingetty(和类似的程序)读取,用来向从终端(issue)或通过 telnet 会话(issue.net)连接的用户显示一个“welcome”字符串。它们包括几行声明 Red Hat 版本号、名称和内核 ID 的信息。它们由 rc.local 使用。

/etc/redhat-release
    包括一行声明 Red Hat 版本号和名称的信息。由 rc.local 使用。

/etc/rc.d/rc
    通常在所有运行级别运行,级别作为参数传送。例如,要以图形(Graphics)模式(X-Server)引导机器,请在命令行运行下面的命令:init 5。运行级别 5 表示以图形模式引导系统。
/etc/rc.d/rc.local
    非正式的。可以从 rc、rc.sysinit 或 /etc/inittab 调用。

/etc/rc.d/rc.sysinit
    通常是所有运行级别的第一个脚本。

/etc/rc.d/rc/rcX.d
    从 rc 运行的脚本(X 表示 1 到 5 之间的任意数字)。这些目录是特定“运行级别”的目录。当系统启动时,它会识别要启动的运行级别,然后调用该运行级别的特定目录中存在的所有启动脚本。例如,系统启动时通常会在引导消息之后显示“entering run-level 3”的消息;这意味着 /etc/rc.d/rc3.d/ 目录中的所有初始化脚本都将被调用。


[目录]

文件系统

/proc
    内核提供了一个接口,用来显示一些它的数据结构,这些数据结构对于决定诸如使用的中断、初始化的设备和内存统计信息之类的系统参数可能很有用。这个接口是作为一个独立但虚拟的文件系统提供的,称为 /proc 文件系统。很多系统实用程序都使用这个文件系统中存在的值来显示系统统计信息。
    例如,/proc/modules 文件列举系统中当前加载的模块。lsmod 命令读取此信息,然后将其以人们可以看懂的格式显示出来。下面表格中指定的 mtab 文件以同样的方式读取包含当前安装的文件系统的 /proc/mount 文件。

/etc/mtab
    这将随着 /proc/mount 文件的改变而不断改变。换句话说,文件系统被安装和卸载时,改变会立即反映到此文件中。

/etc/fstab
    列举计算机当前“可以安装”的文件系统。这非常重要,因为计算机引导时将运行 mount -a 命令,该命令负责安装 fstab 的倒数第二列中带有“1”标记的每一个文件系统。

/etc/mtools.conf
    DOS 类型的文件系统上所有操作(创建目录、复制、格式化等等)的配置。


[目录]

系统管理

/etc/group
    包含有效的组名称和指定组中包括的用户。单一用户如果执行多个任务,可以存在于多个组中。例如,如果一个“用户”是“project 1”工程组的成员,同时也是管理员,那么在 group 文件中他的条目看起来就会是这样的:user: * : group-id : project1

/etc/nologin
    如果有 /etc/nologin 文件存在,login(1) 将只允许 root 用户进行访问。它将对其它用户显示此文件的内容并拒绝其登录。

/etc/passwd
    请参阅“man passwd”。它包含一些用户帐号信息,包括密码(如果未被 shadow 程序加密过)。

/etc/rpmrc
    rpm 命令配置。所有的 rpm 命令行选项都可以在这个文件中一起设置,这样,当任何 rpm 命令在该系统中运行时,所有的选项都会全局适用。

/etc/securetty
    包含设备名称,由 tty 行组成(每行一个名称,不包括前面的 /dev/),root 用户在这里被允许登录。

/etc/usertty

/etc/shadow
    包含加密后的用户帐号密码信息,还可以包括密码时效信息。包括的字段有:
        ·登录名
        ·加密后的密码
        ·从 1970 年 1 月 1 日到密码最后一次被更改的天数
        ·距密码可以更改之前的天数 
 ·距密码必须更改之前的天数
        ·密码到期前用户被警告的天数
        ·密码到期后帐户被禁用的天数
        ·从 1970 年 1 月 1 日到帐号被禁用的天数

/etc/shells
    包含系统可用的可能的“shell”的列表。

/etc/motd
    每日消息;在管理员希望向 Linux 服务器的所有用户传达某个消息时使用。


[目录]

网络

/etc/gated.conf gated 的配置。
    只能被 gated 守护进程所使用。

/etc/gated.version
    包含 gated 守护进程的版本号。

/etc/gateway
    由 routed 守护进程可选地使用。

/etc/networks
    列举从机器所连接的网络可以访问的网络名和网络地址。通过路由命令使用。允许使用网络名称。

/etc/protocols
    列举当前可用的协议。请参阅 NAG(网络管理员指南,Network Administrators Guide)和联机帮助页。C 接口是 getprotoent。绝不能更改。

/etc/resolv.conf
    在程序请求“解析”一个 IP 地址时告诉内核应该查询哪个名称服务器。

/etc/rpc
    包含 RPC 指令/规则,这些指令/规则可以在 NFS 调用、远程文件系统安装等中使用。

/etc/exports
    要导出的文件系统(NFS)和对它的权限。

/etc/services
    将网络服务名转换为端口号/协议。由 inetd、telnet、tcpdump 和一些其它程序读取。有一些 C 访问例程。

/etc/inetd.conf
    inetd 的配置文件。请参阅 inetd 联机帮助页。包含每个网络服务的条目,inetd 必须为这些网络服务控制守护进程或其它服务。注意,服务将会运行,但在 /etc/services 中将它们注释掉了,这样即使这些服务在运行也将不可用。格式为:<service_name> <sock_type> <proto> <flags> <user> <server_path> <args>

/etc/sendmail.cf
    邮件程序 sendmail 的配置文件。比较隐晦,很难理解。

/etc/sysconfig/network
    指出 NETWORKING=yes 或 no。至少由 rc.sysinit 读取。

/etc/sysconfig/network-scripts/if*
    Red Hat 网络配置脚本。


[目录]

系统命令

    系统命令要独占地控制系统,并让一切正常工作。所有如 login(完成控制台用户身份验证阶段)或 bash(提供用户和计算机之间交互)之类的程序都是系统命令。因此,和它们有关的文件也特别重要。这一类别中有下列令用户和管理员感兴趣的文件。

/etc/lilo.conf
    包含系统的缺省引导命令行参数,还有启动时使用的不同映象。您在 LILO 引导提示的时候按 Tab 键就可以看到这个列表。

/etc/logrotate.conf
    维护 /var/log 目录中的日志文件。

/etc/identd.conf
    identd 是一个服务器,它按照 RFC 1413 文档中指定的方式实现 TCP/IP 提议的标准 IDENT 用户身份识别协议。identd 的操作原理是查找特定 TCP/IP 连接并返回拥有此连接的进程的用户名。作为选择,它也可以返回其它信息,而不是用户名。请参阅 identd 联机帮助页。
/etc/ld.so.conf
    “动态链接程序”(Dynamic Linker)的配置。

/etc/inittab
    按年代来讲,这是 UNIX 中第一个配置文件。在一台 UNIX 机器打开之后启动的第一个程序是 init,它知道该启动什么,这是由于 inittab 的存在。在运行级别改变时,init 读取 inittab,然后控制主进程的启动。

/etc/termcap
    一个数据库,包含所有可能的终端类型以及这些终端的性能。


[目录]

守护进程

    守护进程是一种运行在非交互模式下的程序。一般来说,守护进程任务是和联网区域有关的:它们等待连接,以便通过连接提供服务。Linux 可以使用从 Web 服务器到 ftp 服务器的很多守护进程。

/etc/syslogd.conf
    syslogd 守护进程的配置文件。syslogd 是一种守护进程,它负责记录(写到磁盘)从其它程序发送到系统的消息。这个服务尤其常被某些守护进程所使用,这些守护进程不会有另外的方法来发出可能有问题存在的信号或向用户发送消息。

/etc/httpd.conf
    Web 服务器 Apache 的配置文件。这个文件一般不在 /etc 中。它可能在 /usr/local/httpd/conf/ 或 /etc/httpd/conf/ 中,但是要确定它的位置,您还需要检查特定的 Apache 安装信息。

/etc/conf.modules or /etc/modules.conf
    kerneld 的配置文件。有意思的是,kerneld 并不是“作为守护进程的”内核。它其实是一种在需要时负责“快速”加载附加内核模块的守护进程。


[目录]

用户程序

    在 Linux(和一般的 UNIX)中,有无数的“用户”程序。最常见的一种用户程序配置文件是 /etc/lynx.cfg。这是着名的文本浏览器 lynx 的配置文件。通过这个文件,您可以定义代理服务器、要使用的字符集等等。下面的代码样本展示了 lynx.cfg 文件的一部分,修改这部分代码可以改变 Linux 系统的代理服务器设置。缺省情况下,这些设置适用于在各自的 shell 中运行 lynx 的所有用户,除非某个用户通过指定 --cfg = "mylynx.cfg" 重设了缺省的配置文件。

/etc/lynx.cfg 中的代理服务器设置

.h1 proxy
.h2 HTTP_PROXY
.h2 HTTPS_PROXY
.h2 FTP_PROXY
.h2 GOPHER_PROXY
.h2 NEWS_PROXY
.h2 NNTP_PROXY
# Lynx version 2.2 and beyond supports the use of proxy servers that can act as
# firewall gateways and caching servers. They are preferable to the older
# gateway servers. Each protocol used by Lynx can be mapped separately using
# PROTOCOL_proxy environment variables (see Lynx Users Guide). If you have
# not set them externally, you can set them at run time via this configuration file.
# They will not override external settings. The no_proxy variable can be used
# to inhibit proxying to selected regions of the Web (see below). Note that on
http://os.rdxx.com/Linux/2005-9/13/175108935_6.shtml

posted @ 2007-09-23 20:40 卓韦 阅读(210) | 评论 (0)编辑 收藏

1. 先从网上下载jdk(jdk-1_5_0_02-linux-i586.rpm) ,推荐SUN的官方网站www.sun.com,下载后放在/home目录中,当然其它地方也行。
进入安装目录
#cd /home
#cp jdk-1_5_0_02-linux-i586.rpm /usr/local
#cd /usr/local
给所有用户添加可执行的权限
#chmod +x jdk-1_5_0_02-linux-i586.rpm.bin
#./jdk-1_5_0_02-linux-i586.rpm.bin
此时会生成文件jdk-1_5_0_02-linux-i586.rpm,同样给所有用户添加可执行的权限
#chmod +x jdk-1_5_0_02-linux-i586.rpm
安装程序
#rpm -ivh jdk-1_5_0_02-linux-i586.rpm
出现安装协议等,按<Enter>接受即可。

2.设置环境变量。
#vi /etc/profile
在最后面加入 
#set java environment
JAVA_HOME=/usr/java/jdk-1_5_0_02
CLASSPATH=.:$JAVA_HOME/lib.tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH
保存退出。

要使JDK在所有的用户中使用,可以这样:
vi /etc/profile.d/java.sh
在新的java.sh中输入以下内容: 
#set java environment
JAVA_HOME=/usr/java/jdk-1_5_0_02
CLASSPATH=.:$JAVA_HOME/lib.tools.jar
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME CLASSPATH PATH
保存退出,然后给java.sh分配权限:chmod 755 /etc/profile.d/java.sh

3.在终端使用echo命令检查环境变量设置情况。
#echo $JAVA_HOME
#echo $CLASSPATH
#echo $PATH

4.检查JDK是否安装成功。
#java -version
如果看到JVM版本及相关信息,即安装成功!


posted @ 2007-09-23 19:36 卓韦 阅读(231) | 评论 (0)编辑 收藏

2007年8月15日

select node_num,report_time from app_standard where app_id='dzyy' and report_time between '2007-1-1' and '2008-1-1' order by report_time desc

posted @ 2007-08-15 19:42 卓韦 阅读(545) | 评论 (0)编辑 收藏

2007年8月14日

     摘要: XSDL(XML Schema定义语言)由元素、属性、命名空间和XML文档种的其他节点构成的。 一、XSD中的元素   XSD文档至少要包含:schema根元素和XML模式命名空间的定义、元素定义。 1、schema根元素语法如下: <xsd:schema xmlns:xsd=“http://www.w3.org/2001/XMLSchema”&g...  阅读全文

posted @ 2007-08-14 16:06 卓韦 阅读(3564) | 评论 (0)编辑 收藏

正则表达式是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”)。模式描述在搜索文本时要匹配的一个或多个字符串。

下面是正则表达式的一些示例:

表达式 匹配
/^\s*$/ 匹配空行。
/\d{2}-\d{5}/ 验证由两位数字、一个连字符再加 5 位数字组成的 ID 号。
/<\s*(\S+)(\s[^>]*)?>[\s\S]*<\s*\/\1\s*>/ 匹配 HTML 标记。

下表包含了元字符的完整列表以及它们在正则表达式上下文中的行为:

字符 说明
\ 将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,“n”匹配字符“n”。“\n”匹配换行符。序列“\\”匹配“\”,“\(”匹配“(”。
^ 匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与“\n”或“\r”之后的位置匹配。
$ 匹配输入字符串结尾的位置。如果设置了 RegExp 对象的 Multiline 属性,$ 还会与“\n”或“\r”之前的位置匹配。
* 零次或多次匹配前面的字符或子表达式。例如,zo* 匹配“z”和“zoo”。* 等效于 {0,}。
+ 一次或多次匹配前面的字符或子表达式。例如,“zo+”与“zo”和“zoo”匹配,但与“z”不匹配。+ 等效于 {1,}。
? 零次或一次匹配前面的字符或子表达式。例如,“do(es)?”匹配“do”或“does”中的“do”。? 等效于 {0,1}。
{n} n 是非负整数。正好匹配 n 次。例如,“o{2}”与“Bob”中的“o”不匹配,但与“food”中的两个“o”匹配。
{n,} n 是非负整数。至少匹配 n 次。例如,“o{2,}”不匹配“Bob”中的“o”,而匹配“foooood”中的所有 o。'o{1,}' 等效于 'o+'。'o{0,}' 等效于 'o*'。
{n,m} mn 是非负整数,其中 n <= m。至少匹配 n 次,至多匹配 m 次。例如,“o{1,3}”匹配“fooooood”中的头三个 o。'o{0,1}' 等效于 'o?'。注意:您不能将空格插入逗号和数字之间。
? 当此字符紧随任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后时,匹配模式是“非贪心的”。“非贪心的”模式匹配搜索到的、尽可能短的字符串,而默认的“贪心的”模式匹配搜索到的、尽可能长的字符串。例如,在字符串“oooo”中,“o+?”只匹配单个“o”,而“o+”匹配所有“o”。
. 匹配除“\n”之外的任何单个字符。若要匹配包括“\n”在内的任意字符,请使用诸如“[\s\S]”之类的模式。
(pattern) 匹配 pattern 并捕获该匹配的子表达式。可以使用 $0...$9 属性从结果“匹配”集合中检索捕获的匹配。若要匹配括号字符 ( ),请使用“\(”或者“\)”。
(?:pattern) 匹配 pattern 但不捕获该匹配的子表达式,即它是一个非捕获匹配,不存储供以后使用的匹配。这对于用“或”字符 (|) 组合模式部件的情况很有用。例如,与“industry|industries”相比,“industr(?:y| ies)”是一个更加经济的表达式。
(?=pattern) 执行正向预测先行搜索的子表达式,该表达式匹配处于匹配 pattern 的字符串的起始点的字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,“Windows (?=95| 98| NT| 2000)”与“Windows 2000”中的“Windows”匹配,但不与“Windows 3.1”中的“Windows”匹配。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。
(?!pattern) 执行反向预测先行搜索的子表达式,该表达式匹配不处于匹配 pattern 的字符串的起始点的搜索字符串。它是一个非捕获匹配,即不能捕获供以后使用的匹配。例如,“Windows (?!95| 98| NT| 2000)”与“Windows 3.1”中的“Windows”匹配,但不与“Windows 2000”中的“Windows”匹配。预测先行不占用字符,即发生匹配后,下一匹配的搜索紧随上一匹配之后,而不是在组成预测先行的字符后。
x| y xy 匹配。例如,“z| food”与“z”或“food”匹配。“(z| f)ood”与“zood”或“food”匹配。
[xyz] 字符集。匹配包含的任一字符。例如,“[abc]”匹配“plain”中的“a”。
[^xyz] 反向字符集。匹配未包含的任何字符。例如,“[^abc]”匹配“plain”中的“p”。
[a-z] 字符范围。匹配指定范围内的任何字符。例如,“[a-z]”匹配“a”到“z”范围内的任何小写字母。
[^a-z] 反向范围字符。匹配不在指定的范围内的任何字符。例如,“[^a-z]”匹配任何不在“a”到“z”范围内的任何字符。
\b 匹配一个字边界,即字与空格间的位置。例如,“er\b”匹配“never”中的“er”,但不匹配“verb”中的“er”。
\B 非字边界匹配。“er\B”匹配“verb”中的“er”,但不匹配“never”中的“er”。
\cx 匹配由 x 指示的控制字符。例如,\cM 匹配一个 Control-M 或回车符。x 的值必须在 A-Z 或 a-z 之间。如果不是这样,则假定 c 就是“c”字符本身。
\d 数字字符匹配。等效于 [0-9]。
\D 非数字字符匹配。等效于 [^0-9]。
\f 换页符匹配。等效于 \x0c 和 \cL。
\n 换行符匹配。等效于 \x0a 和 \cJ。
\r 匹配一个回车符。等效于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 制表符匹配。与 \x09 和 \cI 等效。
\v 垂直制表符匹配。与 \x0b 和 \cK 等效。
\w 匹配任何字类字符,包括下划线。与“[A-Za-z0-9_]”等效。
\W 任何非字字符匹配。与“[^A-Za-z0-9_]”等效。
\xn 匹配 n,此处的 n 是一个十六进制转义码。十六进制转义码必须正好是两位数长。例如,“\x41”匹配“A”。“\x041”与“\x04”&“1”等效。允许在正则表达式中使用 ASCII 代码。
\num 匹配 num,此处的 num 是一个正整数。到捕获匹配的反向引用。例如,“(.)\1”匹配两个连续的相同字符。
\n 标识一个八进制转义码或反向引用。如果 \n 前面至少有 n 个捕获子表达式,那么 n 是反向引用。否则,如果 n 是八进制数 (0-7),那么 n 是八进制转义码。
\nm 标识一个八进制转义码或反向引用。如果 \nm 前面至少有 nm 个捕获子表达式,那么 nm 是反向引用。如果 \nm 前面至少有 n 个捕获,那么 n 是反向引用,后面跟 m。如果前面的条件均不存在,那么当 n m 是八进制数 (0-7) 时,\nm 匹配八进制转义码 nm
\nml n 是八进制数 (0-3),ml 是八进制数 (0-7) 时,匹配八进制转义码 nml
\un 匹配 n,其中 n 是以四位十六进制数表示的 Unicode 字符。例如,\u00A9 匹配版权符号 (©)。
Java正则表达式详解 :
如果你曾经用过Perl或任何其他内建正则表达式支持的语言,你一定知道用正则表达式处理文本和匹配模式是多么简单。如果你不熟悉这个术语,那么“正则表达式”(Regular Expression)就是一个字符构成的串,它定义了一个用来搜索匹配字符串的模式。
许多语言,包括Perl、PHP、Python、JavaScript和JScript,都支持用正则表达式处理文本,一些文本编辑器用正则表达式实现高级“搜索-替换”功能。那么Java又怎样呢?本文写作时,一个包含了用正则表达式进行文本处理的Java规范需求(Specification Request)已经得到认可,你可以期待在JDK的下一版本中看到它。
然而,如果现在就需要使用正则表达式,又该怎么办呢?你可以从Apache.org下载源代码开放的Jakarta-ORO库。本文接下来的内容先简要地介绍正则表达式的入门知识,然后以Jakarta-ORO API为例介绍如何使用正则表达式。
一、正则表达式基础知识
我们先从简单的开始。假设你要搜索一个包含字符“cat”的字符串,搜索用的正则表达式就是“cat”。如果搜索对大小写不敏感,单词“catalog”、“Catherine”、“sophisticated”都可以匹配。也就是说:
1.1 句点符号
假设你在玩英文拼字游戏,想要找出三个字母的单词,而且这些单词必须以“t”字母开头,以“n”字母结束。另外,假设有一本英文字典,你可以用正则表达式搜索它的全部内容。要构造出这个正则表达式,你可以使用一个通配符——句点符号“.”。这样,完整的表达式就是“t.n”,它匹配“tan”、“ten”、“tin”和“ton”,还匹配“t#n”、“tpn”甚至“t n”,还有其他许多无意义的组合。这是因为句点符号匹配所有字符,包括空格、Tab字符甚至换行符:
1.2 方括号符号
为了解决句点符号匹配范围过于广泛这一问题,你可以在方括号(“[]”)里面指定看来有意义的字符。此时,只有方括号里面指定的字符才参与匹配。也就是说,正则表达式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”。但“Toon”不匹配,因为在方括号之内你只能匹配单个字符:
1.3 “或”符号
如果除了上面匹配的所有单词之外,你还想要匹配“toon”,那么,你可以使用“|”操作符。“|”操作符的基本意义就是“或”运算。要匹配“toon”,使用“t(a|e|i|o|oo)n”正则表达式。这里不能使用方扩号,因为方括号只允许匹配单个字符;这里必须使用圆括号“()”。圆括号还可以用来分组,具体请参见后面介绍。
1.4 表示匹配次数的符号
表一显示了表示匹配次数的符号,这些符号用来确定紧靠该符号左边的符号出现的次数:

假设我们要在文本文件中搜索美国的社会安全号码。这个号码的格式是999-99-9999。用来匹配它的正则表达式如图一所示。在正则表达式中,连字符(“-”)有着特殊的意义,它表示一个范围,比如从0到9。因此,匹配社会安全号码中的连字符号时,它的前面要加上一个转义字符“\”。

图一:匹配所有123-12-1234形式的社会安全号码

假设进行搜索的时候,你希望连字符号可以出现,也可以不出现——即,999-99-9999和999999999都属于正确的格式。这时,你可以在连字符号后面加上“?”数量限定符号,如图二所示:

图二:匹配所有123-12-1234和123121234形式的社会安全号码

下面我们再来看另外一个例子。美国汽车牌照的一种格式是四个数字加上二个字母。它的正则表达式前面是数字部分“[0-9]{4}”,再加上字母部分“[A-Z]{2}”。图三显示了完整的正则表达式。

图三:匹配典型的美国汽车牌照号码,如8836KV

1.5 “否”符号
“^”符号称为“否”符号。如果用在方括号内,“^”表示不想要匹配的字符。例如,图四的正则表达式匹配所有单词,但以“X”字母开头的单词除外。

图四:匹配所有单词,但“X”开头的除外

1.6 圆括号和空白符号
假设要从格式为“June 26, 1951”的生日日期中提取出月份部分,用来匹配该日期的正则表达式可以如图五所示:

图五:匹配所有Moth DD,YYYY格式的日期

新出现的“\s”符号是空白符号,匹配所有的空白字符,包括Tab字符。如果字符串正确匹配,接下来如何提取出月份部分呢?只需在月份周围加上一个圆括号创建一个组,然后用ORO API(本文后面详细讨论)提取出它的值。修改后的正则表达式如图六所示:

图六:匹配所有Month DD,YYYY格式的日期,定义月份值为第一个组

1.7 其它符号
为简便起见,你可以使用一些为常见正则表达式创建的快捷符号。如表二所示:
表二:常用符号

例如,在前面社会安全号码的例子中,所有出现“[0-9]”的地方我们都可以使用“\d”。修改后的正则表达式如图七所示:

图七:匹配所有123-12-1234格式的社会安全号码

二、Jakarta-ORO库
有许多源代码开放的正则表达式库可供Java程序员使用,而且它们中的许多支持Perl 5兼容的正则表达式语法。我在这里选用的是Jakarta-ORO正则表达式库,它是最全面的正则表达式API之一,而且它与Perl 5正则表达式完全兼容。另外,它也是优化得最好的API之一。
Jakarta-ORO库以前叫做OROMatcher,Daniel Savarese大方地把它赠送给了Jakarta Project。你可以按照本文最后参考资源的说明下载它。
我首先将简要介绍使用Jakarta-ORO库时你必须创建和访问的对象,然后介绍如何使用Jakarta-ORO API。
▲ PatternCompiler对象
首先,创建一个Perl5Compiler类的实例,并把它赋值给PatternCompiler接口对象。Perl5Compiler是PatternCompiler接口的一个实现,允许你把正则表达式编译成用来匹配的Pattern对象。
▲ Pattern对象
要把正则表达式编译成Pattern对象,调用compiler对象的compile()方法,并在调用参数中指定正则表达式。例如,你可以按照下面这种方式编译正则表达式“t[aeio]n”:
默认情况下,编译器创建一个大小写敏感的模式(pattern)。因此,上面代码编译得到的模式只匹配“tin”、“tan”、 “ten”和“ton”,但不匹配“Tin”和“taN”。要创建一个大小写不敏感的模式,你应该在调用编译器的时候指定一个额外的参数:
创建好Pattern对象之后,你就可以通过PatternMatcher类用该Pattern对象进行模式匹配。
▲ PatternMatcher对象
PatternMatcher对象根据Pattern对象和字符串进行匹配检查。你要实例化一个Perl5Matcher类并把结果赋值给PatternMatcher接口。Perl5Matcher类是PatternMatcher接口的一个实现,它根据Perl 5正则表达式语法进行模式匹配:
使用PatternMatcher对象,你可以用多个方法进行匹配操作,这些方法的第一个参数都是需要根据正则表达式进行匹配的字符串:
· boolean matches(String input, Pattern pattern):当输入字符串和正则表达式要精确匹配时使用。换句话说,正则表达式必须完整地描述输入字符串。
· boolean matchesPrefix(String input, Pattern pattern):当正则表达式匹配输入字符串起始部分时使用。
· boolean contains(String input, Pattern pattern):当正则表达式要匹配输入字符串的一部分时使用(即,它必须是一个子串)。
另外,在上面三个方法调用中,你还可以用PatternMatcherInput对象作为参数替代String对象;这时,你可以从字符串中最后一次匹配的位置开始继续进行匹配。当字符串可能有多个子串匹配给定的正则表达式时,用PatternMatcherInput对象作为参数就很有用了。用PatternMatcherInput对象作为参数替代String时,上述三个方法的语法如下:
· boolean matches(PatternMatcherInput input, Pattern pattern)
· boolean matchesPrefix(PatternMatcherInput input, Pattern pattern)
· boolean contains(PatternMatcherInput input, Pattern pattern)
三、应用实例
下面我们来看看Jakarta-ORO库的一些应用实例。
3.1 日志文件处理
任务:分析一个Web服务器日志文件,确定每一个用户花在网站上的时间。在典型的BEA WebLogic日志文件中,日志记录的格式如下:
分析这个日志记录,可以发现,要从这个日志文件提取的内容有两项:IP地址和页面访问时间。你可以用分组符号(圆括号)从日志记录提取出IP地址和时间标记。
首先我们来看看IP地址。IP地址有4个字节构成,每一个字节的值在0到255之间,各个字节通过一个句点分隔。因此,IP地址中的每一个字节有至少一个、最多三个数字。图八显示了为IP地址编写的正则表达式:

图八:匹配IP地址

IP地址中的句点字符必须进行转义处理(前面加上“\”),因为IP地址中的句点具有它本来的含义,而不是采用正则表达式语法中的特殊含义。句点在正则表达式中的特殊含义本文前面已经介绍。
日志记录的时间部分由一对方括号包围。你可以按照如下思路提取出方括号里面的所有内容:首先搜索起始方括号字符(“[”),提取出所有不超过结束方括号字符(“]”)的内容,向前寻找直至找到结束方括号字符。图九显示了这部分的正则表达式。

图九:匹配至少一个字符,直至找到“]”

现在,把上述两个正则表达式加上分组符号(圆括号)后合并成单个表达式,这样就可以从日志记录提取出IP地址和时间。注意,为了匹配“- -”(但不提取它),正则表达式中间加入了“\s-\s-\s”。完整的正则表达式如图十所示。

图十:匹配IP地址和时间标记

现在正则表达式已经编写完毕,接下来可以编写使用正则表达式库的Java代码了。
为使用Jakarta-ORO库,首先创建正则表达式字符串和待分析的日志记录字符串:
这里使用的正则表达式与图十的正则表达式差不多完全相同,但有一点例外:在Java中,你必须对每一个向前的斜杠(“\”)进行转义处理。图十不是Java的表示形式,所以我们要在每个“\”前面加上一个“\”以免出现编译错误。遗憾的是,转义处理过程很容易出现错误,所以应该小心谨慎。你可以首先输入未经转义处理的正则表达式,然后从左到右依次把每一个“\”替换成“\\”。如果要复检,你可以试着把它输出到屏幕上。
初始化字符串之后,实例化PatternCompiler对象,用PatternCompiler编译正则表达式创建一个Pattern对象:
现在,创建PatternMatcher对象,调用PatternMatcher接口的contain()方法检查匹配情况:
接下来,利用PatternMatcher接口返回的MatchResult对象,输出匹配的组。由于logEntry字符串包含匹配的内容,你可以看到类如下面的输出:
3.2 HTML处理实例一
下面一个任务是分析HTML页面内FONT标记的所有属性。HTML页面内典型的FONT标记如下所示:
程序将按照如下形式,输出每一个FONT标记的属性:
在这种情况下,我建议你使用两个正则表达式。第一个如图十一所示,它从字体标记提取出“"face="Arial, Serif" size="+2" color="red"”。

图十一:匹配FONT标记的所有属性

第二个正则表达式如图十二所示,它把各个属性分割成名字-值对。

图十二:匹配单个属性,并把它分割成名字-值对

分割结果为:
现在我们来看看完成这个任务的Java代码。首先创建两个正则表达式字符串,用Perl5Compiler把它们编译成Pattern对象。编译正则表达式的时候,指定Perl5Compiler.CASE_INSENSITIVE_MASK选项,使得匹配操作不区分大小写。
接下来,创建一个执行匹配操作的Perl5Matcher对象。
假设有一个String类型的变量html,它代表了HTML文件中的一行内容。如果html字符串包含FONT标记,匹配器将返回true。此时,你可以用匹配器对象返回的MatchResult对象获得第一个组,它包含了FONT的所有属性:
接下来创建一个PatternMatcherInput对象。这个对象允许你从最后一次匹配的位置开始继续进行匹配操作,因此,它很适合于提取FONT标记内属性的名字-值对。创建PatternMatcherInput对象,以参数形式传入待匹配的字符串。然后,用匹配器实例提取出每一个FONT的属性。这通过指定PatternMatcherInput对象(而不是字符串对象)为参数,反复地调用PatternMatcher对象的contains()方法完成。PatternMatcherInput对象之中的每一次迭代将把它内部的指针向前移动,下一次检测将从前一次匹配位置的后面开始。
本例的输出结果如下:
3.3 HTML处理实例二
下面我们来看看另一个处理HTML的例子。这一次,我们假定Web服务器从widgets.acme.com移到了newserver.acme.com。现在你要修改一些页面中的链接:
执行这个搜索的正则表达式如图十三所示:

图十三:匹配修改前的链接

如果能够匹配这个正则表达式,你可以用下面的内容替换图十三的链接:
注意#字符的后面加上了$1。Perl正则表达式语法用$1、$2等表示已经匹配且提取出来的组。图十三的表达式把所有作为一个组匹配和提取出来的内容附加到链接的后面。
现在,返回Java。就象前面我们所做的那样,你必须创建测试字符串,创建把正则表达式编译到Pattern对象所必需的对象,以及创建一个PatternMatcher对象:
接下来,用com.oroinc.text.regex包Util类的substitute()静态方法进行替换,输出结果字符串:
Util.substitute()方法的语法如下:
这个调用的前两个参数是以前创建的PatternMatcher和Pattern对象。第三个参数是一个Substiution对象,它决定了替换操作如何进行。本例使用的是Perl5Substitution对象,它能够进行Perl5风格的替换。第四个参数是想要进行替换操作的字符串,最后一个参数允许指定是否替换模式的所有匹配子串(Util.SUBSTITUTE_ALL),或只替换指定的次数。
【结束语】在这篇文章中,我为你介绍了正则表达式的强大功能。只要正确运用,正则表达式能够在字符串提取和文本修改中起到很大的作用。另外,我还介绍了如何在Java程序中通过Jakarta-ORO库利用正则表达式。至于最终采用老式的字符串处理方式(使用StringTokenizer,charAt,和substring),还是采用正则表达式,这就有待你自己决定了。

posted @ 2007-08-14 14:41 卓韦 阅读(2216) | 评论 (0)编辑 收藏

XMLBeans是Bea公司的一个项目,用于访问和处理数据和文档。使用XMLBeans可以让您用面向对象的观点来对待和处理xml数据和文档,同时又可以忠实于该xml数据对应的xml结构和schema。本文中作者简单的介绍了XMLBeans,并且给出了一个简单的例子,详细的演示了如何配置XMLBeans使它正常运行的全部过程。

 

XMLBeans来自于Bea,是使用java技术访问和处理XML数据和文档技术的一次突破性进展。第一次,开发者可以用自己熟悉的、方便的、面向对象的视图来看待XML数据,同时又可以访问该数据对应的结构和schema。                                 ――来自于Bea的关于XMLBeans的介绍

XMLBeansBea公司针对XML处理的一个项目,现在已经提供免费下载和使用,目前的最新版本是1.0

1 为什么使用XMLBeans

XMLBeans之前,我们访问xml数据和文档有两种选择:

1. 使用DOMSAX来访问XML数据和文档的内容

2. 使用JAXB等技术将XML映射为java

不管你使用哪一种,你都无法完整的访问该XML数据和对象的丰富内容和Schema信息。产生的原因是因为java数据模型和XML之间不匹配造成的,所以应用中你要不就选择了可扩展性,要不就只能选择系统的强壮性。

随着XMLBeans的出现,我们不需要再采取这种折衷的措施了。XMLBeans提供了更多的特性来访问XML数据和文档:

1.   XMLBeans是基于标记流,因此可以轻松的使用指针在xml数据和文档之间导航。指针接口适用于所有xml数据和文档。

2.   如果你的xml数据和文档有一个schema的话,XMLBeans将给您生成这些XML数据和文档的java类“视图”(也就是访问这些XML数据和文档的java代码)。

3.   开发者可以使用这些java代码轻松的读/写xml数据和文档,而且被强制的执行xml schema中规定的一些约束。

4.   java类“视图”都能够忠实的表述原始xml数据和文档的内容,因为java类“视图”都是基于受保护的、最基本的xml表现。

所以使用XMLBeans来访问xml 数据和文档的好处是显而易见的:

1.   完全使用面向对象的观点来看待和处理数据和文档

2.   开发者不再需要编写大量的代码来访问XML数据和文档

3.   可以使用schema中规定的对于数据的约束条件,而不需要自己去编写实现这些约束的代码

4.   不需要解析所有的xml数据和文档而仅仅是为了访问其中的某个数据项

关于XMLBeans更详细的情况请大家访问http://dev2dev.bea.com/technologies/xmlbeans/

2 环境和工具准备

XMLBeans中的大量工作使用了Ant工具,所以再开始工作之前请下载Ant工具并使它正常运行。

XMLBeansjava实现请大家到bea的网站上下载:http://dev2dev.bea.com/technologies/xmlbeans/index.jsp

在执行过程中,还需要用访问xmldom组件,也就是xml-apis.jar文件,可到http://xml.apache.org/xerces2-j/index.html下载。附件中的test-XMLBeans.rar文件中也有这个jar文件。

3 第一个例子

3.1    实例说明

我们这里使用一个订单的例子,他的实例文档如下:

<po:purchase-order xmlns:po=" http://vivianj.go.nease.net/easypo ">

    <po:customer>

  <po:name>Gladys Kravitz</po:name>

  <po:address>Anytown, PA</po:address>

    </po:customer>

    <po:date>2003-01-07T14:16:00-05:00</po:date>

    <po:line-item>

  <po:description>Burnham's Celestial Handbook, Vol 1</po:description>

  <po:per-unit-ounces>5</po:per-unit-ounces>

  <po:price>21.79</po:price>

  <po:quantity>2</po:quantity>

    </po:line-item>

    <po:line-item>

  <po:description>Burnham's Celestial Handbook, Vol 2</po:description>

  <po:per-unit-ounces>5</po:per-unit-ounces>

  <po:price>19.89</po:price>

  <po:quantity>2</po:quantity>

    </po:line-item>

<po:shipper>

  <po:name>ZipShip</po:name>

  <po:per-ounce-rate>0.74</po:per-ounce-rate>

    </po:shipper>

</po:purchase-order>

我们使用下面的schema来描述这个实例文档:

<xs:schema

   xmlns:xs="http://www.w3.org/2001/XMLSchema"

   xmlns:po="http://vivianj.go.nease.net/easypo"

   targetNamespace="http://vivianj.go.nease.net/easypo"

   elementFormDefault="qualified">

  <xs:element name="purchase-order">

    <xs:complexType>

      <xs:sequence>

  <xs:element name="customer" type="po:customer"/>

  <xs:element name="date" type="xs:dateTime"/>

  <xs:element name="line-item" type="po:line-item" minOccurs="0" maxOccurs="unbounded"/>

  <xs:element name="shipper" type="po:shipper" minOccurs="0" maxOccurs="1"/>

      </xs:sequence>

    </xs:complexType>

  </xs:element>

  <xs:complexType name="customer">

    <xs:sequence>

      <xs:element name="name" type="xs:string"/>

      <xs:element name="address" type="xs:string"/>

    </xs:sequence>

    <xs:attribute name="age" type="xs:int"/>

  </xs:complexType>

  <xs:complexType name="line-item">

    <xs:sequence>

      <xs:element name="description" type="xs:string"/>

      <xs:element name="per-unit-ounces" type="xs:decimal"/>

      <xs:element name="price" type="xs:decimal"/>

      <xs:element name="quantity" type="xs:integer"/>

    </xs:sequence>

  </xs:complexType>

  <xs:complexType name="shipper">

    <xs:sequence>

      <xs:element name="name" type="xs:string"/>

      <xs:element name="per-ounce-rate" type="xs:decimal"/>

    </xs:sequence>

  </xs:complexType>

</xs:schema>

现在,要访问的xml数据已经确定了,而且已经用schema来描述他了,剩下的就是使用XMLBeans来辅助生成访问XML数据的java代码了,下面的章节将详细的介绍这部分内容

3.2    ant辅助生成访问XML数据的java代码

3.2.1      外部jar文件

在使用XMLBeans生成访问XML数据的java代码时,我们需要用到xbean.jar文件,下载的XMLBeans里面有这个文件。

3.2.2      增加的taskdef

编译脚本执行时候必须增加一个XMLBeantaskdef,内容如下:

<taskdef name="xmlbean" classname="com.bea.xbean.tool.XMLBean" classpath="path/to/xbean.jar"/>

3.2.3      xmlbean

使用xmlbean标签来生成访问xml数据的java代码,简单的例子如下:

<xmlbean schema="schemas" destfile="Schemas.jar"/>

<xmlbean schema="schemaseasypo.xsd" destfile="Schemas.jar" srcgendir="." >

第一个例子表示为schemas下面所有的*.xsd文件生成访问代码,将所有的代码编译好后放入Schemas.jar文件中。

第二个例子表示为schemas下面所有的easypo.xsd文件生成访问代码,将所有的代码编译好后放入Schemas.jar文件中,而且将生成的。Java文件放在当前目录下。

其中的参数简单的说明如下:

xmlbean 标签表示这是要生成指定schema文件的访问代码。

Schema  属性表示要生成访问代码的xsd文件的范围,可以是一个目录,也可以

是一个文件或者使用fileset进行定义。

Destfile  属性定义了被生成的代码编译后将放在那个文件中。

Rcgendir 属性则表示生成的。Java文件将放在那个目录中。

Xmlbean标签支持的其它参数和相关的说明请参考XMLBeans的帮助文档,这里不作过多的说明。

3.2.4      实际的build.xml

<project name="MyProject" default="compile" basedir=".">

<property name="src" value="."/>

<property name="build" value="build"/>

<property name="dist"  value="dist"/>

<property name="classpath" value="./xkit/lib/xbean.jar "/>

<target name="init">

    <!-- Create the build directory structure used by compile -->

    <mkdir dir="${build}"/>

</target>

<target name="compile" depends="init">

    <!-- Compile the java code from ${src} into ${build} -->

    <taskdef name="xmlbean" classname="com.bea.xbean.tool.XMLBean" classpath="${classpath}"/>

    <xmlbean schema="schemas/easypo.xsd" classpath="${classpath}" destfile="easypo.jar" srcgendir="${src}"/>

  </target>

</project>

3.2.5      生成jar文件

现在你可以进入build.xml文件所在的目录,执行ant f build.xml来生成所有访问该easypo.xml的代码。

执行完以后,这个目录下面会多出一个Schemas.jar文件,他包含了所有被生成和编译了的、访问xml文档的.class文件。目录下面会多出一个net目录,他的子目录下包含了所有被生成的.java文件.实际的jar文件构成请大家参考作者提供的Schemas.jar文件.

4 测试一下

4.1    测试代码

好了,现在我们来写个例子,测试一下是否可以成功的访问xml数据.完整的代码请参看

//解析xml实例文档,他的参数poFile是一个file类型的参数

//所以需要我们将3.1的实例文档保存为一个.xml文档

PurchaseOrderDocument poDoc =

      PurchaseOrderDocument.Factory.parse(poFile);

//创建一个访问该xml实例文档的接口PurchaseOrder

/**[让作者感到很意外的是,bea提供的例子代码中这段的定义是这样的:

*PurchaseOrder po = poDoc.getPurchaseOrder();

*也就是说PurchaseOrder这个接口应该是一个单独的类,但是作者查看XMLBeans

*最后生成的.java文件中,这个PurchaseOrder却是作为PurchaseOrderDocument的一

*个内部类出现的

*/

PurchaseOrderDocument.PurchaseOrder po = poDoc.getPurchaseOrder();

//直接过去其中的所有lineitem子元素的所有内容,他返回一个lineitem对象的数组.

  LineItem[] lineitems = po.getLineItemArray();

  System.out.println("Purchase order has " + lineitems.length + " line items.");

  double totalAmount = 0.0;

  int numberOfItems = 0;

//直接使用对应的get方法来获取对应属性的值

  for (int j = 0; j < lineitems.length; j++)

  {

      System.out.println(" Line item: " + j);

      System.out.println(

    "   Description: " + lineitems[j].getDescription());

      System.out.println("   Quantity: " + lineitems[j].getQuantity());

      System.out.println("   Price: " + lineitems[j].getPrice());

      numberOfItems += lineitems[j].getQuantity().intValue();

      totalAmount += lineitems[j].getPrice().doubleValue() * lineitems[j].getQuantity().doubleValue();

  }

  System.out.println("Total items: " + numberOfItems);

  System.out.println("Total amount: " + totalAmount);

4.2    测试结果

运行这段代码,应该在控制台打印如下信息:

Purchase order has 3 line items.

 Line item 0

   Description: Burnham's Celestial Handbook, Vol 1

   Quantity: 2

   Price: 21.79

 Line item 1

   Description: Burnham's Celestial Handbook, Vol 2

   Quantity: 2

   Price: 19.89

Total items: 4

Total amount: 41.68

5 总结

XMLBeansBea公司的一个公开源代码项目,以Schema为基础建立的、访问xml的一种解决方法,提供了访问和处理xml数据和文档时既可以完全的访问xml的内容、又不丢失xmlschema信息的强大功能。使用XMLBeans可以让您用面向对象的观点来对待和处理xml数据和文档,同时又可以忠实于该xml数据对应的xml结构和schema

本文中作者简单的介绍了XMLBeans,并且给出了一个简单的例子,详细的演示了如何配置XMLBeans,如何使用他的ant扩展辅助生成访问xmljava代码,如何编写客户端来测试该段代码是否成功执行的全过程。希望能够让大家掌握如何使用XMLBeans来简化各自的开发工作、提高自己的开发速度。XMLBeans的高级应用将在接下来的文章中介绍。

参考资料:

1. ANT的帮助 http://ant.apache.org/

2. XMLBeans的帮助 http://dev2dev.bea.com/technologies/xmlbeans/

工具下载:

1. ANT工具下载 http://archive.apache.org/dist/ant/binaries/

2. XMLBeans下载  http://dev2dev.bea.com/technologies/xmlbeans/

作者的所有工作文件: test-XMLBeans.rar

作者信息:

姓名: 肖菁

联系方式: 0731-6665772,jing.xiao@chinacreator.com

简介: 作者目前是湖南省长沙铁道学院科创计算机系统集成有限公司软件中心软件工程师,IBM developerworksBEA dev2dev撰稿人,主要研究J2EE编程技术、Web Service技术以及他们在websphereweblogicapache平台上的实现,拥有IBM Developing With Websphere Studio证书。欢迎大家访问作者的个人网站: vivianj.go.nease.net

posted @ 2007-08-14 10:36 卓韦 阅读(685) | 评论 (0)编辑 收藏