﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-碧螺春-文章分类-java&amp;jsp</title><link>http://www.blogjava.net/yuyi/category/389.html</link><description>-----------------MDA之路</description><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 02:44:13 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 02:44:13 GMT</pubDate><ttl>60</ttl><item><title>java 收集</title><link>http://www.blogjava.net/yuyi/articles/36986.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Thu, 23 Mar 2006 01:46:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/36986.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/36986.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/36986.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/36986.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/36986.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JSP内建对象								J2EE — 作者: LiuYi @ 2005-09-28, 13:28 																				① out - javax.servlet.jsp.jspWriter								   out对象用于把结果输出到网页上。														方法：1. void clear() ;   清除输出缓冲...&nbsp;&nbsp;<a href='http://www.blogjava.net/yuyi/articles/36986.html'>阅读全文</a><img src ="http://www.blogjava.net/yuyi/aggbug/36986.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2006-03-23 09:46 <a href="http://www.blogjava.net/yuyi/articles/36986.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Oracle数据库性能优化技术</title><link>http://www.blogjava.net/yuyi/articles/5731.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Wed, 08 Jun 2005 06:14:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/5731.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/5731.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/5731.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/5731.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/5731.html</trackback:ping><description><![CDATA[摘要： Oracle数据库是当前应用最广泛的大型数据库之一，而其性优化直接关系到系统的运行效率。本文以数据库性能优化的基本原则为出发点，阐述了在数据库设计阶段如何避免竞争和如何优化数据访问，在数据库运行阶段如何从操作系统和数据库实例级别上调整内存和I/O来达到数据库性能优化的各种技术。<BR><BR>　　关键词：Oracle数据库；性能优化；内存；I/O<BR><BR>　　<B>1. 引言</B><BR><BR>　　随着网络应用和电子商务的不断发展，各个站点的访问量越来越大，数据库规模也随之不断的扩大，数据库系统的性能问题就越来越突出，因此，如何对数据库进行调优至关重要：如何使用有限的计算机系统资源为更多的用户服务？如何保证用户的响应速度和服务质量？这些问题都属于服务器性能优化的范畴。<BR><BR>　　作为全球第一大数据库厂商，Oracle数据库在国内外获得了诸多成功应用，据统计，全球93%的上市.COM公司、65家"财富全球100强"企业不约而同地采用Oracle数据库来开展电子商务。我国很多企业、政府单位及电子商务网站也采用了Oracle作为数据库服务器。Oracle数据库服务器是高度可优化的软件产品，经常性的调整可以优化应用系统的性能，防止出现系统瓶颈。<BR><BR>　　数据库性能优化的基本原则就是：通过尽可能少的磁盘访问获得所需要的数据。要评价数据库的性能，需要在数据库调节前后比较其评价指标：响应时间和吞吐量之间的权衡、数据库的可用性、数据库的命中率以及内存的使用效率，以此来衡量调节措施的效果和指导调整的方向。 <BR><BR>　　对Oracle数据库进行性能调整时，应当按照一定的顺序进行，因为系统在前面步骤中进行的调整可以避免后面的一些不必要调整或者代价很大的调整。一般来说可以从两个阶段入手：<BR><BR>　　1、设计阶段：对其逻辑结构和物理结构进行优化设计，使之在满足需求条件的情况下,系统性能达到最佳，系统开销达到最小；<BR><BR>　　2、数据库运行阶段：采取操作系统级、数据库级的一些优化措施来使系统性能最佳； 
<P>　　<B>2. 在系统设计开发阶段调整数据库</B><BR><BR>　　为了充分利用Oracle数据库的功能特性，在设计信息系统时，数据库设计人员需要根据业务情况（如访问量或客户端数量）和现有资源状况（如数据库服务器的配置）考虑系统结构和数据库的逻辑结构的设计：<BR><BR>　　2.1调整应用程序结构设计。<BR><BR>　　即应用程序采用的是传统的C/S两层体系结构，还是B/W/D三层体系结构。不同的应用程序体系结构要求的数据库资源是不同的。<BR><BR>　　2.2恰当使用分区、索引及存档功能。<BR><BR>　　如果某种业务的数据量增长非常快，可以考虑存放该业务的数据库表是否使用Oracle数据库的分区功能；对于经常访问的数据库表是否需要建立索引；对于经常访问但是当业务流程完成后不再变动的数据可采用放入历史档案的方法来实现应用系统中访问尽可能少的数据量。<BR><BR>　　2.3恰当编写访问数据的SQL语句。<BR><BR>　　良好的SQL语句可以被数据库重复使用而减少分析时间；恰当的使用索引可使访问的数据块大大减少从而减少响应时间。应用程序的执行最终将归结为数据库中的SQL语句执行，因此SQL语句的执行效率决定了Oracle数据库的性能。Oracle公司推荐使用Oracle语句优化器（Oracle Optimizer）和行锁管理器（row-level manager）来调整优化SQL语句。<BR><BR>　　2.4调整硬盘I/O<BR><BR>　　这一步是在信息系统开发之前完成的。数据库管理员可以将组成同一个表空间的数据文件放在不同的硬盘上，做到硬盘之间I/O负载均衡。在磁盘比较富裕的情况下还应该遵循以下原则：<BR></P>
<P>　　 将表和索引分开；<BR><BR>　　 创造用户表空间，与系统表空间（system）分开磁盘；<BR><BR>　　 创建表和索引时指定不同的表空间；<BR><BR>　　 创建回滚段专用的表空间，防止空间竞争影响事务的完成；<BR><BR>　　 创建临时表空间用于排序操作，尽可能的防止数据库碎片存在于多个表空间中。<BR><BR>　　2.5确定数据块大小和存储参数。<BR><BR>　　由于数据库的块大小在数据库创建以后就不能在修改（除非重建数据库），因此为了减少数据链接和行迁移，又提高磁盘空间的利用率，在设计数据库时要确定合适的数据块大小和存储参数。通常我们是根据样例数据确定数据块大小，而根据业务现状和未来发展趋势确定存储参数。<BR><BR><STRONG>3. 在数据库运行阶段调整数据库<BR><BR></STRONG>　　数据库运行阶段调整数据库包括两个方面：操作系统级的调整；数据库级的调整。<BR><BR>　　3.1 操作系统级的调整<BR><BR>　　实施操作系统级调整的主要目的是减少内存交换，减少分页，使SGA(System Globle Area)可留驻内存。<BR><BR>　　3.1.1减少内存交换<BR><BR>　　内存交换（swapping）可能会造成很大的内存开销，应将它最小化。运行在Solaris Unix操作系统上的Oracle数据库，可利用vmstat或sar命令来检查交换，查看到系统级内存和硬盘I/O的使用情况，调整unix数据缓冲池的大小、每个进程所能使用的内存大小等参数。<BR></P>
<P></P>
<P>　　 vmstat命令<BR><BR>　　它报告Solaris上的进程、虚拟内存、磁盘、分页和CPU的活动情况。下面命令将显示系统每5秒钟做的事情的概要：<BR>% vmstat 5 <BR><BR>　　 sar命令<BR><BR>　　用于监控交换、分页、磁盘和CPU活动。下面命令用于每10秒显示10次分页活动的概要：<BR>% sar -p 10 10<BR><BR>　　若系统内存交换较多，且需要节省内存，可采用以下措施：<BR><BR>　　1） 避免运行不必要的系统daemon进程或应用程序进程；<BR><BR>　　2） 在不明显影响数据块命中率的前提下减少数据库缓冲区的数量，以释放一些内存；<BR><BR>　　3） 减少UNIX文件缓冲区的数量（特别是在使用裸设备时）。<BR><BR>　　3.1.2控制分页<BR><BR>　　少量的内存分页不会太显著地影响系统的性能，因为应用程序不必全部放在内存中。但是分页过多将会造成系统性能下降。为了检测过多的分页，可在快速响应或空闲期间运行测量，并与响应迟缓时的测量进行比较。可通过以下办法来解决：<BR><BR>　　 使用vmstat或sar -p监控分页；</P>
<P>　　　 安装更多的内存；<BR><BR>　　　 将一些工作移到另一系统中；<BR><BR>　　　 配置系统核心使用更少的内存；<BR><BR>　　　 保持SGA在单个共享内存段中。<BR><BR>　　3.1.3使SGA(System Globle Area)留驻内存<BR><BR>　　SGA是对数据库数据进行快速访问的一个系统全局区，若SGA本身需要频繁地进行释放、分配，则不可能达到快速访问数据的目的，因此，要求SGA驻留内存。这时，我们可以重新配置UNIX核心，调整一些操作系统参数以达到增加共享内存的目的。<BR><BR>　　3.2 数据库级的调整<BR><BR>　　每一个Oracle实例都是由一组Oracle后台进程和SGA的一个内存区组成的。这组后台进程会自动的读写数据库的数据文件，因此，数据库性能可以被这些因素所影响：SGA各部分的分配是否合理，使用效率是否正常；I/O和锁竞争是否较多。<BR><BR>　　3.2.1 SGA的分配及使用效率<BR><BR>　　分配给每个实例的内存，即SGA的使用效率如何，会大大影响数据库系统的性能。SGA由下列部分组成：共享池、数据块缓冲区、重做日志缓冲区、大池组成。<BR><BR>　　l 共享池（Shared pool）<BR><BR>　　共享池存放库缓存（存储共享SQL和PL/SQL区）和数据字典缓存（数据库对象信息）以及会话期间信息（对于MTS）。由于这些信息是应用程序需要经常访问的，因此这些信息需要保持高的命中率。可以通过以下语句来确认共享池数据的命中率：<BR><BR>　　库缓存：<BR><BR>select gethitratio from v$librarycache 应大于90%<BR>select sum(reloads)/sum(pins) from v$librarycache 应小于1%<BR></P>
<P>　　数据字典缓存：<BR><BR>select sum(getmisses)/sum(gets) from v$rowcache 应小于15%<BR><BR>　　由于程序设计人员的水平参差不齐，可能存在大的匿名块，这会导致SQL不能重用，因此需要找出大的匿名块以转换为存储过程达到重用：<BR><BR>select * from v$sqlarea where command_type=47 and length(sql_text)&gt;500<BR><BR>　　而对于一些应用系统非常频繁使用的SQL对象如存储过程、函数、包等，可以通过钉在内存中的方式来防止由于共享池太小被移出：<BR><BR>exec dbms_shared_pool.keep(对象名)<BR><BR>　　 数据块缓冲区（Db block buffer）：<BR><BR>　　数据块缓冲区存放用户所经常访问的数据文件的数据块内容以及用户修改的数据内容。数据库把数据文件里的内容读到内存中，下次需要时直接从内存中读取，从而减少了磁盘的I/O和响应时间。当然，一般只在比较小的数据表（如常用代码表）才缓存到内存中。<BR><BR>　　由于数据快缓冲区中不可能存放所有的数据，因此可使用LRU算法来确定移出哪些数据块，但又尽量保证有较高的数据命中率。<BR><BR>　　查看数据块命中率的SQL语句为：<BR><BR>select 1-(phy.value/(cur.value+con.value)) from v$sysstat cur,v$sysstat con,v$sysstat phy<BR>where cur.name='db block gets' and con.name='consistent gets'<BR>and phy.name='physical gets'<BR><BR>　　如果这个命中率小于0.85，就要考虑为数据块缓冲区分配更多的内存了。<BR><BR>　　 重做日志缓冲区（Log buffer）：<BR><BR>　　重做日志缓冲区存放从用户内存区复制来的每个DML或DDL语句的重做条目。如果这个缓冲区分配太小会导致没有足够的空间来放重做条目而等待。<BR><BR>　　3.2.2 I/O和资源竞争<BR><BR>　　由于有众多的进程要写数据文件，因此需要通过I/O调整来解决I/O瓶颈问题。如果在设计阶段有效地考虑了表空间的合理分配，就能有效地在一定程度上减少I/O竞争。在数据库运行时，由于数据的动态增长，原来分配给表或索引的空间已经用完，Oracle会自动分配空间给这些数据库对象。而这个动态分配会对系统性能有所影响，所以要求：<BR><BR>　　 避免动态空间管理<BR><BR>　　 表空间的本地化管理，以减少与数据字典表空间的磁盘竞争。<BR><BR>　　在系统设计和试运行阶段数据量相对较小，效率低下的SQL可能并不会影响系统响应时间，但当系统数据量增长到一定程度时，需要在系统运行时监控并找出是哪些SQL不能有效使用索引或缺少索引，并进行相应调整：建立索引；修改SQL写法。<BR><BR>　　另外，在Oracle中，需要采用一些机制来保证数据库对象在使用期间的稳定性和数据的一致性，如使用锁存器(latch)、锁(lock)等。因此争用和这些机制相关的资源会影响数据库的性能。为了减少这种资源竞争，可以通过调整数据库的相关初始化参数（如db_block_lru_latches、dml_locks）来减少资源的争用，优化数据库性能。</P>
<P>　　<B>4. 一些常用的性能优化手段和工具</B><BR><BR>　　Oracle数据库系统提供了一些工具和脚本来获取数据库的性能指标和优化的方法。如使用utlbstat.sql和utlestat.sql脚本获取一段时间内数据库的内存、磁盘I/O等的情况；使用动态性能视图和数据字典视图来获取命中率和系统等待事件等信息。当然，也可以使用Oracle Enterprise Manager图形化工具来监控。</P>
<P>　　<B>5. 结束语</B><BR><BR>　　Oracle数据库的性能调整相当重要，但难度也较大。数据库管理员需要综合运用上面介绍的规律，在数据库建立时，就能根据应用的需要合理设计分配表空间以及存储参数、内存使用初始化参数，对以后的数据库性能有很大的益处。只有认真分析Oracle运行过程当中出现的各种性能问题，才能保证Oracle数据库高效可靠地运行。还需要指出的是：数据库的性能调整是一个系统工程，涉及的方面很多，不能仅仅根据一个时间点的情况就断定数据库运行性能的好与坏。如何有效地进行调整，数据库管理员需要经过反反复复的过程。这些都需要在大量的实践工作中不断地积累经验，从而更好地进行数据库的调优。</P>
<SCRIPT>zmbbs=1;</SCRIPT><img src ="http://www.blogjava.net/yuyi/aggbug/5731.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-06-08 14:14 <a href="http://www.blogjava.net/yuyi/articles/5731.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>sax解析xml文档-jdom解析文档 </title><link>http://www.blogjava.net/yuyi/articles/5603.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Mon, 06 Jun 2005 06:33:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/5603.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/5603.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/5603.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/5603.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/5603.html</trackback:ping><description><![CDATA[<DIV class=postText>
<P>sax解析<BR>**********************************************************************************<BR>package test;</P>
<P>import javax.xml.parsers.*;<BR>import org.xml.sax.*;<BR>import org.xml.sax.helpers.*;<BR>import java.io.*;</P>
<P>public class SaxTest extends DefaultHandler {<BR><BR>// 重载DefaultHandler类的方法<BR>// 以拦截SAX事件通知。<BR>//<BR>// 关于所有有效事件，见org.xml.sax.ContentHandler<BR>//<BR>&nbsp;&nbsp;&nbsp; public void startDocument() throws SAXException {<BR>//System.out.println( "SAX Event: START DOCUMENT" );<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public void endDocument() throws SAXException {<BR>//System.out.println( "SAX Event: END DOCUMENT" );<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public void startElement(String namespaceURI,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String localName,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String qName,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Attributes attr) throws SAXException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("&lt;" + localName);</P>
<P>// 如果有属性，我们也一并打印出来．．．<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; attr.getLength(); i++) {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print(" " + attr.getLocalName(i) + "='" +attr.getValue(i)+"'");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("&gt;");<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public void endElement(String namespaceURI,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String localName,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String qName) throws SAXException {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("</" ? + localName>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public void characters(char[] ch, int start, int length) throws<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXException {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OutputStreamWriter outw = new OutputStreamWriter(System.out);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outw.write(ch, start, length);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; outw.flush();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; public static void main(String[] argv) {</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Example1 SAX Events:");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {</P>
<P>// SAXParserFactory spFactory = SAXParserFactory.newInstance();<BR>// SAXParser sParser = spFactory.newSAXParser();</P>
<P><BR>// 建立SAX 2解析器．．．<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XMLReader xr = XMLReaderFactory.createXMLReader(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "org.apache.xerces.parsers.SAXParser");</P>
<P>// 安装ContentHandler．．．<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xr.setContentHandler(new SaxTest());</P>
<P>// 解析文件．．．<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xr.parse(new InputSource(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new FileReader("c:\\DeviceTable.xml")));</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR><BR><BR>JDOM解析<BR>***********************************************************************************<BR>package test;</P>
<P>import org.jdom.Document;<BR>import org.jdom.Element;<BR>import org.jdom.input.SAXBuilder;<BR>import org.jdom.output.Format;<BR>import org.jdom.output.XMLOutputter;<BR>import java.util.List;<BR>import java.util.*;</P>
<P>&nbsp;</P>
<P>/**<BR>&nbsp;* @author kingwong<BR>&nbsp;*<BR>&nbsp;* TODO To change the template for this generated type comment go to<BR>&nbsp;* Window - Preferences - Java - Code Style - Code Templates<BR>&nbsp;*/<BR>public class TestJDOM2 {<BR>&nbsp;public static void main(String[] args){<BR>&nbsp;SAXBuilder sb = new SAXBuilder();<BR>&nbsp;&nbsp;&nbsp; try<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp; Document doc = sb.build("c:\\DeviceTable.xml");<BR>&nbsp; Element root = doc.getRootElement();<BR>&nbsp; List list=root.getChildren();<BR>&nbsp; getchildren(list);<BR>&nbsp; </P>
<P>&nbsp; String str1 = root.getAttributeValue("comment");<BR>&nbsp; System.out.println("Root Element's comment attribute is : " + str1);<BR>//&nbsp; String str2 = root.getChild("NeCode").getAttributeValue("sss");<BR>//&nbsp; System.out.println("NeCode Element's sss attribute is : " + str2);<BR>//&nbsp; String str3 = root.getChildText("name");<BR>//&nbsp; System.out.println("name Element's content is :" + str3);<BR>//&nbsp; String str4 = root.getChild("contact").getChildText("telephone");<BR>//&nbsp; System.out.println("contact Element's telephone subelement content is : " + str4 + "\n");<BR>//&nbsp; Element inputElement = root.getChild("contact");<BR>//&nbsp; inputElement.addContent(new Element("email").setAttribute("value","<A href="mailto:wanghua@cyberobject.com"><FONT color=#000080>wanghua@cyberobject.com</FONT></A>"));</P>
<P>&nbsp; XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());<BR>//&nbsp;&nbsp;&nbsp;&nbsp; String outStr = xmlOut.outputString(root);</P>
<P>//&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(outStr);<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; catch(Exception e)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
<P>private static void getchildren(List list) {<BR>&nbsp;&nbsp;&nbsp; Iterator iter = list.iterator();<BR>&nbsp;&nbsp;&nbsp; while (iter.hasNext()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element item = (Element) iter.next();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("***&lt;"+item.getName()+"&gt;"+item.getValue()+"</"+ITEM.GETNAME()+">");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(item.getChildren().size()!=0){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getchildren(item.getChildren());<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }else{<BR>//&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("###"+item.getName()+"没有子节点！！");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>}</P></DIV><img src ="http://www.blogjava.net/yuyi/aggbug/5603.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-06-06 14:33 <a href="http://www.blogjava.net/yuyi/articles/5603.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java加密技术(转载)</title><link>http://www.blogjava.net/yuyi/articles/4425.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Tue, 17 May 2005 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/4425.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/4425.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/4425.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/4425.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/4425.html</trackback:ping><description><![CDATA[<P><STRONG>第1章 基础知识</STRONG></P>
<P>1.1. 单钥密码体制 <BR>单钥密码体制是一种传统的加密算法，是指信息的发送方和接收方共同使用同一把密钥进行加解密。</P>
<P>通常,使用的加密算法 比较简便高效,密钥简短，加解密速度快，破译极其困难。但是加密的安全性依靠密钥保管的安全性,在公开的计算机网络上安全地传送和保管密钥是一个严峻的问题，并且如果在多用户的情况下密钥的保管安全性也是一个问题。</P>
<P>单钥密码体制的代表是美国的DES</P>
<P>1.2. 消息摘要 <BR>一个消息摘要就是一个数据块的数字指纹。即对一个任意长度的一个数据块进行计算，产生一个唯一指印（对于SHA1是产生一个20字节的二进制数组）。</P>
<P>消息摘要有两个基本属性： </P>
<P>两个不同的报文难以生成相同的摘要 <BR>难以对指定的摘要生成一个报文，而由该报文反推算出该指定的摘要<BR>代表：美国国家标准技术研究所的SHA1和麻省理工学院Ronald Rivest提出的MD5</P>
<P>1.3. Diffie-Hellman密钥一致协议 <BR>密钥一致协议是由公开密钥密码体制的奠基人Diffie和Hellman所提出的一种思想。</P>
<P>先决条件,允许两名用户在公开媒体上交换信息以生成"一致"的,可以共享的密钥</P>
<P>代表：指数密钥一致协议(Exponential Key Agreement Protocol)</P>
<P>1.4. 非对称算法与公钥体系 <BR>1976年，Dittie和Hellman为解决密钥管理问题，在他们的奠基性的工作"密码学的新方向"一文中，提出一种密钥交换协议，允许在不安全的媒体上通过通讯双方交换信息，安全地传送秘密密钥。在此新思想的基础上，很快出现了非对称密钥密码体制，即公钥密码体制。在公钥体制中，加密密钥不同于解密密钥，加密密钥公之于众，谁都可以使用；解密密钥只有解密人自己知道。它们分别称为公开密钥（Public key）和秘密密钥（Private key）。 </P>
<P>迄今为止的所有公钥密码体系中，RSA系统是最著名、最多使用的一种。RSA公开密钥密码系统是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。RSA的取名就是来自于这三位发明者的姓的第一个字母</P>
<P>1.5. 数字签名 <BR>所谓数字签名就是信息发送者用其私钥对从所传报文中提取出的特征数据（或称数字指纹）进行RSA算法操作，以保证发信人无法抵赖曾发过该信息（即不可抵赖性），同时也确保信息报文在经签名后末被篡改（即完整性）。当信息接收者收到报文后，就可以用发送者的公钥对数字签名进行验证。　 </P>
<P>在数字签名中有重要作用的数字指纹是通过一类特殊的散列函数（HASH函数）生成的，对这些HASH函数的特殊要求是： </P>
<P>接受的输入报文数据没有长度限制； <BR>对任何输入报文数据生成固定长度的摘要（数字指纹）输出 <BR>从报文能方便地算出摘要； <BR>难以对指定的摘要生成一个报文，而由该报文反推算出该指定的摘要； <BR>两个不同的报文难以生成相同的摘要</P>
<P>代表：DSA</P>
<P><STRONG>第2章 在JAVA中的实现</STRONG></P>
<P>2.1. 相关 <BR>Diffie-Hellman密钥一致协议和DES程序需要JCE工具库的支持,可以到 <A href="http://java.sun.com/security/index.html">http://java.sun.com/security/index.html</A> 下载JCE,并进行安装。简易安装把 jce1.2.1\lib 下的所有内容复制到 %java_home%\lib\ext下,如果没有ext目录自行建立,再把jce1_2_1.jar和sunjce_provider.jar添加到CLASSPATH内,更详细说明请看相应用户手册</P>
<P>2.2. 消息摘要MD5和SHA的使用 <BR>使用方法:</P>
<P>首先用生成一个MessageDigest类,确定计算方法</P>
<P>java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");</P>
<P>添加要进行计算摘要的信息</P>
<P>alga.update(myinfo.getBytes());</P>
<P>计算出摘要</P>
<P>byte[] digesta=alga.digest();</P>
<P>发送给其他人你的信息和摘要</P>
<P>其他人用相同的方法初始化,添加信息,最后进行比较摘要是否相同</P>
<P>algb.isEqual(digesta,algb.digest())</P>
<P>相关AIP</P>
<P>java.security.MessageDigest 类</P>
<P>static getInstance(String algorithm)</P>
<P>返回一个MessageDigest对象,它实现指定的算法</P>
<P>参数:算法名,如 SHA-1 或MD5</P>
<P>void update (byte input)</P>
<P>void update (byte[] input)</P>
<P>void update(byte[] input, int offset, int len)</P>
<P>添加要进行计算摘要的信息</P>
<P>byte[] digest()</P>
<P>完成计算,返回计算得到的摘要(对于MD5是16位,SHA是20位)</P>
<P>void reset()</P>
<P>复位</P>
<P>static boolean isEqual(byte[] digesta, byte[] digestb)</P>
<P>比效两个摘要是否相同</P>
<P>代码： <BR>import java.security.*;<BR>public class myDigest {<BR>public static void main(String[] args) {</P>
<P>myDigest my=new myDigest();<BR>my.testDigest();</P>
<P>}<BR>public void testDigest()<BR>{<BR>try {<BR>String myinfo="我的测试信息";</P>
<P>//java.security.MessageDigest alg=java.security.MessageDigest.getInstance("MD5");<BR>java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");<BR>alga.update(myinfo.getBytes());<BR>byte[] digesta=alga.digest();<BR>System.out.println("本信息摘要是:"+byte2hex(digesta));<BR>//通过某中方式传给其他人你的信息(myinfo)和摘要(digesta) 对方可以判断是否更改或传输正常<BR>java.security.MessageDigest algb=java.security.MessageDigest.getInstance("SHA-1");<BR>algb.update(myinfo.getBytes());<BR>if (algb.isEqual(digesta,algb.digest())) {<BR>System.out.println("信息检查正常");<BR>}<BR>else<BR>{<BR>System.out.println("摘要不相同");<BR>}</P>
<P>}<BR>catch (java.security.NoSuchAlgorithmException ex) {<BR>System.out.println("非法摘要算法");<BR>}</P>
<P>}<BR>public String byte2hex(byte[] b) //二行制转字符串<BR>{<BR>String hs="";<BR>String stmp="";<BR>for (int n=0;n {<BR>stmp=(java.lang.Integer.toHexString(b[n] &amp; 0XFF));<BR>if (stmp.length()==1) hs=hs+"0"+stmp;<BR>else hs=hs+stmp;<BR>if (n }<BR>return hs.toUpperCase();<BR>}</P>
<P>}</P>
<P>&nbsp;</P>
<P>2.3. 数字签名DSA</P>
<P>对于一个用户来讲首先要生成他的密钥对,并且分别保存 <BR>生成一个KeyPairGenerator实例 <BR>java.security.KeyPairGenerator keygen=java.security.KeyPairGenerator.getInstance("DSA");<BR>如果设定随机产生器就用如相代码初始化<BR>SecureRandom secrand=new SecureRandom(); </P>
<P>secrand.setSeed("tttt".getBytes()); //初始化随机产生器<BR>keygen.initialize(512,secrand); //初始化密钥生成器<BR>否则<BR>keygen.initialize(512);<BR>生成密钥公钥pubkey和私钥prikey<BR>KeyPair keys=keygen.generateKeyPair(); //生成密钥组<BR>PublicKey pubkey=keys.getPublic();<BR>PrivateKey prikey=keys.getPrivate();<BR>分别保存在myprikey.dat和mypubkey.dat中,以便下次不在生成<BR>(生成密钥对的时间比较长<BR>java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));<BR>out.writeObject(prikey);<BR>out.close();<BR>out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));<BR>out.writeObject(pubkey);<BR>out.close();</P>
<P>&nbsp;</P>
<P><BR>用他私人密钥(prikey)对他所确认的信息(info)进行数字签名产生一个签名数组 <BR>从文件中读入私人密钥(prikey) <BR>java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));<BR>PrivateKey myprikey=(PrivateKey)in.readObject();<BR>in.close();<BR>初始一个Signature对象,并用私钥对信息签名<BR>java.security.Signature signet=java.security.Signature.getInstance("DSA");<BR>signet.initSign(myprikey);<BR>signet.update(myinfo.getBytes());<BR>byte[] signed=signet.sign();<BR>把信息和签名保存在一个文件中(myinfo.dat)<BR>java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));<BR>out.writeObject(myinfo);<BR>out.writeObject(signed);<BR>out.close();<BR>把他的公钥的信息及签名发给其它用户</P>
<P>&nbsp;</P>
<P><BR>其他用户用他的公共密钥(pubkey)和签名(signed)和信息(info)进行验证是否由他签名的信息 <BR>读入公钥<BR>java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat")); <BR>PublicKey pubkey=(PublicKey)in.readObject(); <BR>in.close();</P>
<P>读入签名和信息<BR>in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat")); <BR>String info=(String)in.readObject(); <BR>byte[] signed=(byte[])in.readObject(); <BR>in.close();</P>
<P>初始一个Signature对象,并用公钥和签名进行验证<BR>java.security.Signature signetcheck=java.security.Signature.getInstance("DSA"); <BR>signetcheck.initVerify(pubkey); <BR>signetcheck.update(info.getBytes()); <BR>if (signetcheck.verify(signed)) { System.out.println("签名正常");}</P>
<P>对于密钥的保存本文是用对象流的方式保存和传送的,也可可以用编码的方式保存.注意要<BR>import java.security.spec.* <BR>import java.security.*</P>
<P>具休说明如下</P>
<P>public key是用X.509编码的,例码如下: <BR>byte[] bobEncodedPubKey=mypublic.getEncoded(); //生成编码<BR>//传送二进制编码<BR>//以下代码转换编码为相应key对象<BR>X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);<BR>KeyFactory keyFactory = KeyFactory.getInstance("DSA");<BR>PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);</P>
<P>&nbsp;</P>
<P>对于Private key是用PKCS#8编码,例码如下: <BR>byte[] bPKCS=myprikey.getEncoded();<BR>//传送二进制编码<BR>//以下代码转换编码为相应key对象<BR>PKCS8EncodedKeySpec priPKCS8=new PKCS8EncodedKeySpec(bPKCS);<BR>KeyFactory keyf=KeyFactory.getInstance("DSA");<BR>PrivateKey otherprikey=keyf.generatePrivate(priPKCS8);</P>
<P>&nbsp;</P>
<P><BR>常用API <BR>java.security.KeyPairGenerator 密钥生成器类 <BR>public static KeyPairGenerator getInstance(String algorithm) throws NoSuchAlgorithmException <BR>以指定的算法返回一个KeyPairGenerator 对象 <BR>参数: algorithm 算法名.如:"DSA","RSA"</P>
<P>public void initialize(int keysize)</P>
<P><BR>以指定的长度初始化KeyPairGenerator对象,如果没有初始化系统以1024长度默认设置</P>
<P><BR>参数:keysize 算法位长.其范围必须在 512 到 1024 之间，且必须为 64 的倍数</P>
<P>public void initialize(int keysize, SecureRandom random)<BR>以指定的长度初始化和随机发生器初始化KeyPairGenerator对象<BR>参数:keysize 算法位长.其范围必须在 512 到 1024 之间，且必须为 64 的倍数<BR>random 一个随机位的来源(对于initialize(int keysize)使用了默认随机器</P>
<P>public abstract KeyPair generateKeyPair()<BR>产生新密钥对</P>
<P>java.security.KeyPair 密钥对类<BR>public PrivateKey getPrivate()<BR>返回私钥</P>
<P>public PublicKey getPublic()<BR>返回公钥</P>
<P>java.security.Signature 签名类<BR>public static Signature getInstance(String algorithm) throws NoSuchAlgorithmException<BR>返回一个指定算法的Signature对象<BR>参数 algorithm 如:"DSA"</P>
<P>public final void initSign(PrivateKey privateKey)<BR>throws InvalidKeyException<BR>用指定的私钥初始化<BR>参数rivateKey 所进行签名时用的私钥</P>
<P>public final void update(byte data)<BR>throws SignatureException<BR>public final void update(byte[] data)<BR>throws SignatureException<BR>public final void update(byte[] data, int off, int len)<BR>throws SignatureException </P>
<P>添加要签名的信息</P>
<P>public final byte[] sign()<BR>throws SignatureException<BR>返回签名的数组,前提是initSign和update</P>
<P>public final void initVerify(PublicKey publicKey)<BR>throws InvalidKeyException<BR>用指定的公钥初始化<BR>参数ublicKey 验证时用的公钥</P>
<P>public final boolean verify(byte[] signature)<BR>throws SignatureException<BR>验证签名是否有效,前提是已经initVerify初始化<BR>参数: signature 签名数组 <BR>*/<BR>import java.security.*;<BR>import java.security.spec.*;<BR>public class testdsa {<BR>public static void main(String[] args) throws java.security.NoSuchAlgorithmException,java.lang.Exception {<BR>testdsa my=new testdsa();<BR>my.run();<BR>}<BR>public void run()<BR>{</P>
<P>//数字签名生成密钥<BR>//第一步生成密钥对,如果已经生成过,本过程就可以跳过,对用户来讲myprikey.dat要保存在本地<BR>//而mypubkey.dat给发布给其它用户<BR>if ((new java.io.File("myprikey.dat")).exists()==false) {<BR>if (generatekey()==false) {<BR>System.out.println("生成密钥对败");<BR>return;<BR>};<BR>}<BR>//第二步,此用户<BR>//从文件中读入私钥,对一个字符串进行签名后保存在一个文件(myinfo.dat)中<BR>//并且再把myinfo.dat发送出去<BR>//为了方便数字签名也放进了myifno.dat文件中,当然也可分别发送<BR>try {<BR>java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));<BR>PrivateKey myprikey=(PrivateKey)in.readObject();<BR>in.close();</P>
<P>// java.security.spec.X509EncodedKeySpec pubX509=new java.security.spec.X509EncodedKeySpec(bX509);</P>
<P>//java.security.spec.X509EncodedKeySpec pubkeyEncode=java.security.spec.X509EncodedKeySpec<BR>String myinfo="这是我的信息"; //要签名的信息<BR>//用私钥对信息生成数字签名<BR>java.security.Signature signet=java.security.Signature.getInstance("DSA");<BR>signet.initSign(myprikey);<BR>signet.update(myinfo.getBytes());<BR>byte[] signed=signet.sign(); //对信息的数字签名<BR>System.out.println("signed(签名内容)="+byte2hex(signed));<BR>//把信息和数字签名保存在一个文件中<BR>java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));<BR>out.writeObject(myinfo);<BR>out.writeObject(signed);<BR>out.close();<BR>System.out.println("签名并生成文件成功");<BR>}<BR>catch (java.lang.Exception e) {<BR>e.printStackTrace();<BR>System.out.println("签名并生成文件失败");<BR>};</P>
<P>//第三步<BR>//其他人通过公共方式得到此户的公钥和文件<BR>//其他人用此户的公钥,对文件进行检查,如果成功说明是此用户发布的信息.<BR>//<BR>try {</P>
<P>java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));<BR>PublicKey pubkey=(PublicKey)in.readObject();<BR>in.close();<BR>System.out.println(pubkey.getFormat());</P>
<P>in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));<BR>String info=(String)in.readObject();<BR>byte[] signed=(byte[])in.readObject();<BR>in.close();</P>
<P>java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");<BR>signetcheck.initVerify(pubkey);<BR>signetcheck.update(info.getBytes());<BR>if (signetcheck.verify(signed)) {<BR>System.out.println("info="+info);<BR>System.out.println("签名正常");<BR>}<BR>else System.out.println("非签名正常");<BR>}<BR>catch (java.lang.Exception e) {e.printStackTrace();};</P>
<P><BR>}</P>
<P>//生成一对文件myprikey.dat和mypubkey.dat---私钥和公钥,<BR>//公钥要用户发送(文件,网络等方法)给其它用户,私钥保存在本地<BR>public boolean generatekey()<BR>{<BR>try {<BR>java.security.KeyPairGenerator keygen=java.security.KeyPairGenerator.getInstance("DSA");<BR>// SecureRandom secrand=new SecureRandom();<BR>// secrand.setSeed("tttt".getBytes()); //初始化随机产生器<BR>// keygen.initialize(576,secrand); //初始化密钥生成器<BR>keygen.initialize(512);<BR>KeyPair keys=keygen.genKeyPair();<BR>// KeyPair keys=keygen.generateKeyPair(); //生成密钥组<BR>PublicKey pubkey=keys.getPublic();<BR>PrivateKey prikey=keys.getPrivate();</P>
<P>java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));<BR>out.writeObject(prikey);<BR>out.close();<BR>System.out.println("写入对象 prikeys ok");<BR>out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));<BR>out.writeObject(pubkey);<BR>out.close();<BR>System.out.println("写入对象 pubkeys ok");<BR>System.out.println("生成密钥对成功");<BR>return true;<BR>}<BR>catch (java.lang.Exception e) {<BR>e.printStackTrace();<BR>System.out.println("生成密钥对失败");</P>
<P>return false;<BR>};</P>
<P>}</P>
<P>public String byte2hex(byte[] b)<BR>{<BR>String hs="";<BR>String stmp="";<BR>for (int n=0;n {<BR>stmp=(java.lang.Integer.toHexString(b[n] &amp; 0XFF));<BR>if (stmp.length()==1) hs=hs+"0"+stmp;<BR>else hs=hs+stmp;<BR>if (n }<BR>return hs.toUpperCase();<BR>}</P>
<P>}</P>
<P>&nbsp;</P>
<P>2.4. DESede/DES对称算法 <BR>首先生成密钥,并保存(这里并没的保存的代码,可参考DSA中的方法)</P>
<P>KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);</P>
<P>SecretKey deskey = keygen.generateKey();</P>
<P>用密钥加密明文(myinfo),生成密文(cipherByte)</P>
<P>Cipher c1 = Cipher.getInstance(Algorithm);</P>
<P>c1.init(Cipher.ENCRYPT_MODE,deskey);</P>
<P>byte[] cipherByte=c1.doFinal(myinfo.getBytes());</P>
<P>传送密文和密钥,本文没有相应代码可参考DSA</P>
<P>.............</P>
<P>用密钥解密密文</P>
<P>c1 = Cipher.getInstance(Algorithm);</P>
<P>c1.init(Cipher.DECRYPT_MODE,deskey);</P>
<P>byte[] clearByte=c1.doFinal(cipherByte);</P>
<P>相对来说对称密钥的使用是很简单的,对于JCE来讲支技DES,DESede,Blowfish三种加密术</P>
<P>对于密钥的保存各传送可使用对象流或者用二进制编码,相关参考代码如下 <BR>SecretKey deskey = keygen.generateKey();<BR>byte[] desEncode=deskey.getEncoded();<BR>javax.crypto.spec.SecretKeySpec destmp=new javax.crypto.spec.SecretKeySpec(desEncode,Algorithm);<BR>SecretKey mydeskey=destmp;</P>
<P>&nbsp;</P>
<P>相关API</P>
<P>KeyGenerator 在DSA中已经说明,在添加JCE后在instance进可以如下参数</P>
<P>DES,DESede,Blowfish,HmacMD5,HmacSHA1</P>
<P>javax.crypto.Cipher 加/解密器 public static final Cipher getInstance(java.lang.String transformation)<BR>throws java.security.NoSuchAlgorithmException,<BR>NoSuchPaddingException<BR>返回一个指定方法的Cipher对象</P>
<P>参数:transformation 方法名(可用 DES,DESede,Blowfish)</P>
<P>public final void init(int opmode, java.security.Key key)<BR>throws java.security.InvalidKeyException</P>
<P>用指定的密钥和模式初始化Cipher对象</P>
<P>参数pmode 方式(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)</P>
<P>key 密钥</P>
<P><BR>public final byte[] doFinal(byte[] input)<BR>throws java.lang.IllegalStateException,<BR>IllegalBlockSizeException,<BR>BadPaddingException</P>
<P>&nbsp;</P>
<P><BR>对input内的串,进行编码处理,返回处理后二进制串,是返回解密文还是加解文由init时的opmode决定</P>
<P>注意:本方法的执行前如果有update,是对updat和本次input全部处理,否则是本inout的内容</P>
<P>/*<BR>安全程序 DESede/DES测试<BR>*/<BR>import java.security.*;<BR>import javax.crypto.*;<BR>public class testdes {<BR>public static void main(String[] args){<BR>testdes my=new testdes();<BR>my.run();<BR>}<BR>public void run() {<BR>//添加新安全算法,如果用JCE就要把它添加进去<BR>Security.addProvider(new com.sun.crypto.provider.SunJCE());<BR>String Algorithm="DES"; //定义 加密算法,可用 DES,DESede,Blowfish<BR>String myinfo="要加密的信息";<BR>try {<BR>//生成密钥<BR>KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);<BR>SecretKey deskey = keygen.generateKey();</P>
<P>//加密<BR>System.out.println("加密前的二进串:"+byte2hex(myinfo.getBytes()));<BR>System.out.println("加密前的信息:"+myinfo);<BR>Cipher c1 = Cipher.getInstance(Algorithm);<BR>c1.init(Cipher.ENCRYPT_MODE,deskey);<BR>byte[] cipherByte=c1.doFinal(myinfo.getBytes());<BR>System.out.println("加密后的二进串:"+byte2hex(cipherByte));<BR>//解密<BR>c1 = Cipher.getInstance(Algorithm);<BR>c1.init(Cipher.DECRYPT_MODE,deskey);<BR>byte[] clearByte=c1.doFinal(cipherByte);<BR>System.out.println("解密后的二进串:"+byte2hex(clearByte));<BR>System.out.println("解密后的信息:"+(new String(clearByte)));</P>
<P>}<BR>catch (java.security.NoSuchAlgorithmException e1) {e1.printStackTrace();}<BR>catch (javax.crypto.NoSuchPaddingException e2) {e2.printStackTrace();}<BR>catch (java.lang.Exception e3) {e3.printStackTrace();}<BR>}<BR>public String byte2hex(byte[] b) //二行制转字符串<BR>{<BR>String hs="";<BR>String stmp="";<BR>for (int n=0;n {<BR>stmp=(java.lang.Integer.toHexString(b[n] &amp; 0XFF));<BR>if (stmp.length()==1) hs=hs+"0"+stmp;<BR>else hs=hs+stmp;<BR>if (n }<BR>return hs.toUpperCase();<BR>}</P>
<P>}</P>
<P>&nbsp;</P>
<P>2.5. Diffie-Hellman密钥一致协议 <BR>公开密钥密码体制的奠基人Diffie和Hellman所提出的 "指数密钥一致协议"(Exponential Key Agreement Protocol),该协议不要求别的安全性 先决条件,允许两名用户在公开媒体上交换信息以生成"一致"的,可以共享的密钥。在JCE的中实现用户alice生成DH类型的密钥对,如果长度用1024生成的时间请,推荐第一次生成后保存DHParameterSpec,以便下次使用直接初始化.使其速度加快 </P>
<P>System.out.println("ALICE: 产生 DH 对 ...");<BR>KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");<BR>aliceKpairGen.initialize(512);<BR>KeyPair aliceKpair = aliceKpairGen.generateKeyPair();</P>
<P>&nbsp;</P>
<P>alice生成公钥发送组bob byte[] alicePubKeyEnc = aliceKpair.getPublic().getEncoded();</P>
<P>&nbsp;</P>
<P>bob从alice发送来的公钥中读出DH密钥对的初始参数生成bob的DH密钥对</P>
<P>注意这一步一定要做,要保证每个用户用相同的初始参数生成的 <BR>DHParameterSpec dhParamSpec = ((DHPublicKey)alicePubKey).getParams();<BR>KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");<BR>bobKpairGen.initialize(dhParamSpec);<BR>KeyPair bobKpair = bobKpairGen.generateKeyPair();</P>
<P>&nbsp;</P>
<P>bob根据alice的公钥生成本地的DES密钥<BR>KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");<BR>bobKeyAgree.init(bobKpair.getPrivate());<BR>bobKeyAgree.doPhase(alicePubKey, true);<BR>SecretKey bobDesKey = bobKeyAgree.generateSecret("DES");</P>
<P>&nbsp;</P>
<P>bob已经生成了他的DES密钥,他现把他的公钥发给alice,<BR>byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded();</P>
<P>&nbsp;</P>
<P>alice根据bob的公钥生成本地的DES密钥<BR>,,,,,,解码<BR>KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");<BR>aliceKeyAgree.init(aliceKpair.getPrivate());<BR>aliceKeyAgree.doPhase(bobPubKey, true);<BR>SecretKey aliceDesKey = aliceKeyAgree.generateSecret("DES");</P>
<P>&nbsp;</P>
<P>bob和alice能过这个过程就生成了相同的DES密钥,在这种基础就可进行安全能信</P>
<P>常用API</P>
<P>java.security.KeyPairGenerator 密钥生成器类<BR>public static KeyPairGenerator getInstance(String algorithm)<BR>throws NoSuchAlgorithmException<BR>以指定的算法返回一个KeyPairGenerator 对象<BR>参数: algorithm 算法名.如:原来是DSA,现在添加了 DiffieHellman(DH)</P>
<P>public void initialize(int keysize)<BR>以指定的长度初始化KeyPairGenerator对象,如果没有初始化系统以1024长度默认设置<BR>参数:keysize 算法位长.其范围必须在 512 到 1024 之间，且必须为 64 的倍数<BR>注意:如果用1024生长的时间很长,最好生成一次后就保存,下次就不用生成了</P>
<P>public void initialize(AlgorithmParameterSpec params)<BR>throws InvalidAlgorithmParameterException<BR>以指定参数初始化</P>
<P>javax.crypto.interfaces.DHPublicKey<BR>public DHParameterSpec getParams()<BR>返回<BR>java.security.KeyFactory</P>
<P>public static KeyFactory getInstance(String algorithm)<BR>throws NoSuchAlgorithmException<BR>以指定的算法返回一个KeyFactory<BR>参数: algorithm 算法名SH,DH</P>
<P>public final PublicKey generatePublic(KeySpec keySpec)<BR>throws InvalidKeySpecException<BR>根据指定的key说明,返回一个PublicKey对象</P>
<P>java.security.spec.X509EncodedKeySpec<BR>public X509EncodedKeySpec(byte[] encodedKey)<BR>根据指定的二进制编码的字串生成一个key的说明<BR>参数:encodedKey 二进制编码的字串(一般能过PublicKey.getEncoded()生成)<BR>javax.crypto.KeyAgreement 密码一至类</P>
<P>public static final KeyAgreement getInstance(java.lang.String algorithm)<BR>throws java.security.NoSuchAlgorithmException<BR>返回一个指定算法的KeyAgreement对象<BR>参数:algorithm 算法名,现在只能是DiffieHellman(DH)</P>
<P>public final void init(java.security.Key key)<BR>throws java.security.InvalidKeyException<BR>用指定的私钥初始化<BR>参数:key 一个私钥</P>
<P>public final java.security.Key doPhase(java.security.Key key,<BR>boolean lastPhase)<BR>throws java.security.InvalidKeyException,<BR>java.lang.IllegalStateException<BR>用指定的公钥进行定位,lastPhase确定这是否是最后一个公钥,对于两个用户的<BR>情况下就可以多次定次,最后确定<BR>参数:key 公钥<BR>lastPhase 是否最后公钥</P>
<P>public final SecretKey generateSecret(java.lang.String algorithm)<BR>throws java.lang.IllegalStateException,<BR>java.security.NoSuchAlgorithmException,<BR>java.security.InvalidKeyException<BR>根据指定的算法生成密钥<BR>参数:algorithm 加密算法(可用 DES,DESede,Blowfish)</P>
<P><BR>*/<BR>import java.io.*;<BR>import java.math.BigInteger;<BR>import java.security.*;<BR>import java.security.spec.*;<BR>import java.security.interfaces.*;<BR>import javax.crypto.*;<BR>import javax.crypto.spec.*;<BR>import javax.crypto.interfaces.*;<BR>import com.sun.crypto.provider.SunJCE;</P>
<P>public class testDHKey {</P>
<P><BR>public static void main(String argv[]) {<BR>try {<BR>testDHKey my= new testDHKey();<BR>my.run();<BR>} catch (Exception e) {<BR>System.err.println(e);</P>
<P>}<BR>}</P>
<P>private void run() throws Exception {<BR>Security.addProvider(new com.sun.crypto.provider.SunJCE());</P>
<P>System.out.println("ALICE: 产生 DH 对 ...");<BR>KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");<BR>aliceKpairGen.initialize(512);<BR>KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); //生成时间长 </P>
<P>// 张三(Alice)生成公共密钥 alicePubKeyEnc 并发送给李四(Bob) ,<BR>//比如用文件方式,socket.....<BR>byte[] alicePubKeyEnc = aliceKpair.getPublic().getEncoded();</P>
<P>//bob接收到alice的编码后的公钥,将其解码<BR>KeyFactory bobKeyFac = KeyFactory.getInstance("DH");<BR>X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec (alicePubKeyEnc);<BR>PublicKey alicePubKey = bobKeyFac.generatePublic(x509KeySpec);<BR>System.out.println("alice公钥bob解码成功");<BR>// bob必须用相同的参数初始化的他的DH KEY对,所以要从Alice发给他的公开密钥,<BR>//中读出参数,再用这个参数初始化他的 DH key对</P>
<P>//从alicePubKye中取alice初始化时用的参数<BR>DHParameterSpec dhParamSpec = ((DHPublicKey)alicePubKey).getParams();<BR>KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");<BR>bobKpairGen.initialize(dhParamSpec);<BR>KeyPair bobKpair = bobKpairGen.generateKeyPair();<BR>System.out.println("BOB: 生成 DH key 对成功");<BR>KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");<BR>bobKeyAgree.init(bobKpair.getPrivate());<BR>System.out.println("BOB: 初始化本地key成功");<BR>//李四(bob) 生成本地的密钥 bobDesKey<BR>bobKeyAgree.doPhase(alicePubKey, true);<BR>SecretKey bobDesKey = bobKeyAgree.generateSecret("DES");<BR>System.out.println("BOB: 用alice的公钥定位本地key,生成本地DES密钥成功");<BR>// Bob生成公共密钥 bobPubKeyEnc 并发送给Alice,<BR>//比如用文件方式,socket.....,使其生成本地密钥<BR>byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded();<BR>System.out.println("BOB向ALICE发送公钥");</P>
<P>// alice接收到 bobPubKeyEnc后生成bobPubKey<BR>// 再进行定位,使aliceKeyAgree定位在bobPubKey<BR>KeyFactory aliceKeyFac = KeyFactory.getInstance("DH");<BR>x509KeySpec = new X509EncodedKeySpec(bobPubKeyEnc);<BR>PublicKey bobPubKey = aliceKeyFac.generatePublic(x509KeySpec);<BR>System.out.println("ALICE接收BOB公钥并解码成功");<BR>;<BR>KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");<BR>aliceKeyAgree.init(aliceKpair.getPrivate());<BR>System.out.println("ALICE: 初始化本地key成功");</P>
<P>aliceKeyAgree.doPhase(bobPubKey, true);<BR>// 张三(alice) 生成本地的密钥 aliceDesKey<BR>SecretKey aliceDesKey = aliceKeyAgree.generateSecret("DES");<BR>System.out.println("ALICE: 用bob的公钥定位本地key,并生成本地DES密钥");</P>
<P>if (aliceDesKey.equals(bobDesKey)) System.out.println("张三和李四的密钥相同");<BR>//现在张三和李四的本地的deskey是相同的所以,完全可以进行发送加密,接收后解密,达到<BR>//安全通道的的目的</P>
<P>/*<BR>* bob用bobDesKey密钥加密信息<BR>*/<BR>Cipher bobCipher = Cipher.getInstance("DES");<BR>bobCipher.init(Cipher.ENCRYPT_MODE, bobDesKey);<BR>String bobinfo= "这是李四的机密信息";<BR>System.out.println("李四加密前原文:"+bobinfo);<BR>byte[] cleartext =bobinfo.getBytes();<BR>byte[] ciphertext = bobCipher.doFinal(cleartext);</P>
<P>/*<BR>* alice用aliceDesKey密钥解密<BR>*/<BR>Cipher aliceCipher = Cipher.getInstance("DES");<BR>aliceCipher.init(Cipher.DECRYPT_MODE, aliceDesKey);<BR>byte[] recovered = aliceCipher.doFinal(ciphertext);<BR>System.out.println("alice解密bob的信息:"+(new String(recovered)));<BR>if (!java.util.Arrays.equals(cleartext, recovered))<BR>throw new Exception("解密后与原文信息不同");<BR>System.out.println("解密后相同");</P>
<P>}</P>
<P>}</P>
<P>&nbsp;</P>
<P><STRONG>第3章 小结 </STRONG></P>
<P><STRONG><BR></STRONG>在加密术中生成密钥对时，密钥对的当然是越长越好，但费时也越多，请从中从实际出发选取合适的长度，大部分例码中的密钥是每次运行就从新生成，在实际的情况中是生成后在一段时间保存在文件中，再次运行直接从文件中读入，从而加快速度。当然定时更新和加强密钥保管的安全性也是必须的。<BR></P><img src ="http://www.blogjava.net/yuyi/aggbug/4425.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-05-17 16:58 <a href="http://www.blogjava.net/yuyi/articles/4425.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>计算Java日期－－学习怎样创建和使用日期 </title><link>http://www.blogjava.net/yuyi/articles/3295.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Thu, 14 Apr 2005 10:36:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/3295.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/3295.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/3295.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/3295.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/3295.html</trackback:ping><description><![CDATA[<DIV class=postText>
<H3><FONT color=#a52a2a>概要</FONT></H3><BR><FONT color=#a52a2a>&nbsp;&nbsp;&nbsp;&nbsp;不管你是处理财务交易还是计划着下一步的行动，你都要知道怎样在Java中建立，使用和显示日期。这需要你简单的查阅一下相应类的API参考：一个日期可以创建3个相关类的对象。这篇文章告诉你你想要知道的内容。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;Java统计从1970年1月1日起的毫秒的数量表示日期。也就是说，例如，1970年1月2日，是在1月1日后的86，400，000毫秒。同样的，1969年12月31日是在1970年1月1日前86，400，000毫秒。Java的Date类使用long类型纪录这些毫秒值.因为long是有符号整数，所以日期可以在1970年1月1日之前，也可以在这之后。Long类型表示的最大正值和最大负值可以轻松的表示290，000，000年的时间，这适合大多数人的时间要求。<BR></FONT>
<H3><FONT color=#a52a2a>Date&nbsp;类</FONT></H3><BR><FONT color=#a52a2a>&nbsp;&nbsp;&nbsp;Date类可以在java.util包中找到，用一个long类型的值表示一个指定的时刻。它的一个有用的构造函数是Date(),它创建一个表示创建时刻的对象。getTime()方法返回Date对象的long值。在下面的程序中，我使用Date()构造函数创建一个表示程序运行时刻的对象，并且利用getTime()方法找到这个日期代表的毫秒数量：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;Now&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;now&nbsp;=&nbsp;<B>new</B>&nbsp;Date();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>long</B>&nbsp;nowLong&nbsp;=&nbsp;now.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Value&nbsp;is&nbsp;"&nbsp;+&nbsp;nowLong);<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>当我运行这个程序后，我得到972,568,255,150.快速确认一下这个数字，起码在一个合理的范围：它不到31年，这个数值相对1970年1月1日到我写这篇文章的时间来说，是合理的。计算机是这个毫秒值表示时间，人们可不愿意说"&nbsp;我将在996,321,998,34见到你。"幸运的是，Java提供了一个转换Date对象到字符串的途径，表示成传统的形式。我们在下一节讨论DateFormat类，它直观的建立日期字符串。&nbsp;<BR>DateFormat类<BR>&nbsp;DateFormat类的一个目标是建立一个人们能够识别的字符串。然而，因为语言的差别，不是所有的人希望看到严格的相同格式的日期。法国人更喜欢看到"25&nbsp;decembre&nbsp;2000,",但是美国人习惯看到"December&nbsp;25,2000."所以一个DateFormat的实例创建以后，这个对象包含了日期的显示格式的信息。如果使用用户电脑区域设置缺省的格式，你可以象下面那样，创建DateFormat对象，使用getDateInstance()方法：<BR><BR>DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance();&nbsp;&nbsp;&nbsp;<BR><BR>DateFormat类在java.text包中可以找到。<BR></FONT>
<H3><FONT color=#a52a2a>转换成字符串</FONT></H3><BR><FONT color=#a52a2a>你可以使用format()方法转换Date对象为一个字符串。下面的示例程序说明了这个问题：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;NowString&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;now&nbsp;=&nbsp;<B>new</B>&nbsp;Date();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;df.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Today&nbsp;is&nbsp;"&nbsp;+&nbsp;s);<BR>&nbsp;&nbsp;&nbsp;}<BR>}&nbsp;&nbsp;<BR><BR>在上面的代码中，展示了没有参数，使用缺省格式的getDateInstance()方法。Java还提供了几个选择日期格式，你可以通过使用重载的getDateInstance(int&nbsp;style)获得。出于方便的原因，DateFormat提供了几种预置的常量，你可以使用这些常量参数。下面是几个SHORT,&nbsp;MEDIUM,&nbsp;LONG,&nbsp;和FULL类型的示例：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;StyleDemo&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;now&nbsp;=&nbsp;<B>new</B>&nbsp;Date();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;&nbsp;DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df1&nbsp;=&nbsp;DateFormat.getDateInstance(DateFormat.SHORT);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df2&nbsp;=&nbsp;DateFormat.getDateInstance(DateFormat.MEDIUM);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df3&nbsp;=&nbsp;DateFormat.getDateInstance(DateFormat.LONG);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df4&nbsp;=&nbsp;DateFormat.getDateInstance(DateFormat.FULL);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;&nbsp;df.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s1&nbsp;=&nbsp;df1.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s2&nbsp;=&nbsp;df2.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s3&nbsp;=&nbsp;df3.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s4&nbsp;=&nbsp;df4.format(now);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("(Default)&nbsp;Today&nbsp;is&nbsp;"&nbsp;+&nbsp;s);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("(SHORT)&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;"&nbsp;+&nbsp;s1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("(MEDIUM)&nbsp;&nbsp;Today&nbsp;is&nbsp;"&nbsp;+&nbsp;s2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("(LONG)&nbsp;&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;"&nbsp;+&nbsp;s3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("(FULL)&nbsp;&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;"&nbsp;+&nbsp;s4);<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>程序输出如下：<BR><BR>(Default)&nbsp;Today&nbsp;is&nbsp;Nov&nbsp;8,&nbsp;2000<BR>(SHORT)&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;11/8/00<BR>(MEDIUM)&nbsp;&nbsp;Today&nbsp;is&nbsp;Nov&nbsp;8,&nbsp;2000<BR>(LONG)&nbsp;&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;November&nbsp;8,&nbsp;2000<BR>(FULL)&nbsp;&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;Wednesday,&nbsp;November&nbsp;8,&nbsp;2000<BR><BR>同样的程序，在我的电脑上使用缺省设置运行后，改变区域设置为瑞典，输出如下：<BR><BR>(Default)&nbsp;Today&nbsp;is&nbsp;2000-nov-08<BR>(SHORT)&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;2000-11-08<BR>(MEDIUM)&nbsp;&nbsp;Today&nbsp;is&nbsp;2000-nov-08<BR>(LONG)&nbsp;&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;den&nbsp;8&nbsp;november&nbsp;2000<BR>(FULL)&nbsp;&nbsp;&nbsp;&nbsp;Today&nbsp;is&nbsp;den&nbsp;8&nbsp;november&nbsp;2000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;<BR>从这里，你能看到，瑞典的月份不是大写的（虽然November还是november）.还有，LONG和FULL版本在瑞典语中是一样的，但是美国英语却不同。另外，有趣的是，瑞典语单词的星期三,onsdag，没有包含在FULL日期里，英语却包括。&nbsp;<BR>注意你能够使用getDateInstance()方法改变DateFormat实例的语种；但是，在上面的例子中，是通过改变Windows98的控制面板的区域设置做到的。不同的地方的区域设置不同，结果就不同，这样有好处，也有不足，Java程序员应该了解这些。一个好处是Java程序员可以只写一行代码就可以显示日期，而且世界不同地区的电脑运行同样的程序会有不用的日期格式。&nbsp;但是这也是一个缺点，当程序员希望显示同一种格式的时--这也有可取之处，举例来说，在程序中混合输出文本和日期，如果文本是英文，我们就不希望日期格式是其他的格式，象德文或是西班牙文。如果程序员依靠日期格式编程，日期格式将根据运行程序所在电脑的区域设置不用而不同。&nbsp;<BR></FONT>
<H3><FONT color=#a52a2a>解析字符串</FONT></H3><BR><FONT color=#a52a2a>&nbsp;通过parse()方法，DateFormat能够以一个字符串创立一个Date对象。这个方法能抛出ParseException异常，所以你必须使用适当的异常处理技术。下面的例子程序通过字符串创建Date对象：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;ParseExample&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ds&nbsp;=&nbsp;"November&nbsp;1,&nbsp;2000";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>try</B>&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;d&nbsp;=&nbsp;df.parse(ds);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>catch</B>(ParseException&nbsp;e)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Unable&nbsp;to&nbsp;parse&nbsp;"&nbsp;+&nbsp;ds);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>在创建一个任意的日期时parse()方法很有用。我将通过另一种方法创建一个任意得日期。同时，你将看到怎样进行基本日期计算，例如计算90天后的另一天。你可以使用GregorianCalendar类来完成这个任务。&nbsp;<BR>GregorianCalendar类<BR>&nbsp;创建一个代表任意日期的一个途径使用GregorianCalendar类的构造函数，它包含在java.util包中：<BR><BR>GregorianCalendar(<B>int</B>&nbsp;year,&nbsp;<B>int</B>&nbsp;month,&nbsp;<B>int</B>&nbsp;date)&nbsp;<BR><BR>注意月份的表示，一月是0，二月是1，以此类推，是12月是11。因为大多数人习惯于使用单词而不是使用数字来表示月份，这样程序也许更易读，父类Calendar使用常量来表示月份：JANUARY,&nbsp;FEBRUARY,等等。所以，创建Wilbur&nbsp;和&nbsp;Orville制造第一架动力飞机的日期（December&nbsp;17,&nbsp;1903），你可以使用：<BR><BR>GregorianCalendar&nbsp;firstFlight&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(1903,&nbsp;Calendar.DECEMBER,&nbsp;17);&nbsp;<BR>&nbsp;<BR>出于清楚的考虑，你应该使用前面的形式。但是，你也应该学习怎样阅读下面的短格式。下面的例子同样表示December&nbsp;17,1903（记住，在短格式中，11表示December）<BR><BR>GregorianCalendar&nbsp;firstFlight&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(1903,&nbsp;11,&nbsp;17);&nbsp;&nbsp;&nbsp;<BR><BR>在上一节中，你学习了转换Date对象到字符串。这里，你可以做同样的事情；但是首先，你需要将GregorianCalendar对象转换到Date。要做到这一点，你可以使用getTime()方法，从它得父类Calendar继承而来。GetTime()方法返回GregorianCalendar相应的Date对象。你能够创建GregorianCalendar对象，转换到Date对象，得到和输出相应的字符串这样一个过程。下面是例子：&nbsp;<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;Flight&nbsp;{<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar&nbsp;firstFlight&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(1903,&nbsp;Calendar.DECEMBER,&nbsp;17);&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;d&nbsp;=&nbsp;firstFlight.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;df.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("First&nbsp;flight&nbsp;was&nbsp;"&nbsp;+&nbsp;s);<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>有时候创建一个代表当前时刻的GregorianCalendar类的实例是很有用的。你可以简单的使用没有参数的GregorianCalendar构造函数，象这样：<BR><BR>GregorianCalendar&nbsp;thisday&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar();<BR><BR>一个输出今天日期的例子程序，使用GregorianCalendar对象：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>class</B>&nbsp;Today&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar&nbsp;thisday&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar();&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;d&nbsp;=&nbsp;thisday.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;df.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Today&nbsp;is&nbsp;"&nbsp;+&nbsp;s);<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>注意到，Date()构造函数和GregorianCalendar()构造函数很类似：都创建一个对象，条件简单，代表今天。<BR></FONT>
<H3><FONT color=#a52a2a>日期处理</FONT></H3><BR><FONT color=#a52a2a>GregorianCalendar类提供处理日期的方法。一个有用的方法是add().使用add()方法，你能够增加象年，月数，天数到日期对象中。要使用add()方法，你必须提供要增加的字段，要增加的数量。一些有用的字段是DATE,&nbsp;MONTH,&nbsp;YEAR,&nbsp;和&nbsp;WEEK_OF_YEAR。下面的程序使用add()方法计算未来80天的一个日期。在Jules的&lt;环球80天&gt;是一个重要的数字，使用这个程序可以计算Phileas&nbsp;Fogg从出发的那一天1872年10月2日后80天的日期：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;World&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar&nbsp;worldTour&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(1872,&nbsp;Calendar.OCTOBER,&nbsp;2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;worldTour.add(GregorianCalendar.DATE,&nbsp;80);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;d&nbsp;=&nbsp;worldTour.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;df.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("80&nbsp;day&nbsp;trip&nbsp;will&nbsp;end&nbsp;"&nbsp;+&nbsp;s);<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>这个例子是想象的，但在一个日期上增加天数是一个普遍的操作：影碟可以租3天，图书馆可以借书21天，商店经常需要将购买的物品在30天内卖出。下面的程序演示了使用年计算：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;Mortgage&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar&nbsp;mortgage&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(1997,&nbsp;Calendar.MAY,&nbsp;18);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mortgage.add(Calendar.YEAR,&nbsp;15);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;d&nbsp;=&nbsp;mortgage.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s&nbsp;=&nbsp;df.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("15&nbsp;year&nbsp;mortgage&nbsp;amortized&nbsp;on&nbsp;"&nbsp;+&nbsp;s);&nbsp;&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;add()一个重要的副作用是它改变的原来的日期。有时候，拥有原始日期和修改后的日期很重要。不幸的是，你不能简单的创建一个GregorianCalendar对象，设置它和原来的相等（equal）。原因是两个变量指向同一个Date()对象地址。如果Date对象改变，两个变量就指向改变后的日期对象。代替这种做法，应该创建一个新对象。下面的程序示范了这种做法：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;ThreeDates&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar&nbsp;gc1&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(2000,&nbsp;Calendar.JANUARY,&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar&nbsp;gc2&nbsp;=&nbsp;gc1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar&nbsp;gc3&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(2000,&nbsp;Calendar.JANUARY,&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<I>//Three&nbsp;dates&nbsp;all&nbsp;equal&nbsp;to&nbsp;January&nbsp;1,&nbsp;2000</I><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gc1.add(Calendar.YEAR,&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file:<I>//gc1&nbsp;and&nbsp;gc2&nbsp;are&nbsp;changed</I><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;d1&nbsp;=&nbsp;gc1.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;d2&nbsp;=&nbsp;gc2.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;d3&nbsp;=&nbsp;gc3.getTime();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s1&nbsp;=&nbsp;df.format(d1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s2&nbsp;=&nbsp;df.format(d2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;s3&nbsp;=&nbsp;df.format(d3);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("gc1&nbsp;is&nbsp;"&nbsp;+&nbsp;s1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("gc2&nbsp;is&nbsp;"&nbsp;+&nbsp;s2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("gc3&nbsp;is&nbsp;"&nbsp;+&nbsp;s3);<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;程序运行后，gc1和gc2被变成2001年（因为两个对象指向同一个Date，而Date已经被改变了）。对象gc3指向一个单独的Date，它没有被改变。<BR>计算复习日期<BR>在这节，你将看到一个依据现实世界的例子。这个详细的程序计算过去一个具体的日期。例如，你阅读这篇文章，你想要记住一个印象深刻的知识点。如果你没有照片一样的记忆力，你就要定期的复习这些新资料，这将帮助你记住它。关于复习系统，Kurt&nbsp;Hanks&nbsp;和&nbsp;Gerreld&nbsp;L.&nbsp;Pulsipher在他们的&lt;&nbsp;Five&nbsp;Secrets&nbsp;to&nbsp;Personal&nbsp;Productivity个人能力的5个秘密&gt;中有讨论，建议看过第一眼后马上回顾一下，然后是1天后，1个星期后，1个月后，3个月后，1年后。我的这篇文章，你要马上回顾一下，从现在算起，再就是明天，然后是1个星期，1个月，3个月，1年后。我们的程序将计算这些日期。<BR>这个程序非常有用的，它将是PIM(Personal&nbsp;Information&nbsp;Manager个人信息管理器)的一个组成部分，并将确定复习时间。在下面的程序中，getDates()方法对一个返回日期数组（复习日期）的电子软件很有用。另外，你可以返回单独的一个日期，使用getFirstDay(),getOneDay(),getOneWeek(),getOnMonth()和getOneYear().当时间范围超出这个PIM的ReviewDates的计算范围时ReviewDates类演示了怎样计算时间段。现在，你可以容易的修改它用来处理你需要的时间段，象图书馆借书，录影带租赁和抵押计算。首先，ReviewDates类显示在下面：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><B>import</B>&nbsp;java.text.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;ReviewDates&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>private</B>&nbsp;GregorianCalendar&nbsp;firstDay,&nbsp;oneDay,&nbsp;oneWeek,&nbsp;oneMonth,&nbsp;oneQuarter,&nbsp;oneYear;<BR>&nbsp;&nbsp;&nbsp;<B>final</B>&nbsp;<B>int</B>&nbsp;dateArraySize&nbsp;=&nbsp;6;<BR><BR>&nbsp;&nbsp;&nbsp;ReviewDates(GregorianCalendar&nbsp;gcDate)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>int</B>&nbsp;year&nbsp;=&nbsp;gcDate.get(GregorianCalendar.YEAR);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>int</B>&nbsp;month&nbsp;=&nbsp;gcDate.get(GregorianCalendar.MONTH);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>int</B>&nbsp;date&nbsp;=&nbsp;gcDate.get(GregorianCalendar.DATE);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;firstDay&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(year,&nbsp;month,&nbsp;date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneDay&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(year,&nbsp;month,&nbsp;date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneWeek&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(year,&nbsp;month,&nbsp;date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneMonth&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(year,&nbsp;month,&nbsp;date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneQuarter&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(year,&nbsp;month,&nbsp;date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneYear&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(year,&nbsp;month,&nbsp;date);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneDay.add(GregorianCalendar.DATE,&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneWeek.add(GregorianCalendar.DATE,&nbsp;7);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneMonth.add(GregorianCalendar.MONTH,&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneQuarter.add(GregorianCalendar.MONTH,&nbsp;3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;oneYear.add(GregorianCalendar.YEAR,&nbsp;1);<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;ReviewDates()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>this</B>(<B>new</B>&nbsp;GregorianCalendar());<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>void</B>&nbsp;listDates()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DateFormat&nbsp;df&nbsp;=&nbsp;DateFormat.getDateInstance(DateFormat.LONG);&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;startDate&nbsp;=&nbsp;firstDay.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;date1&nbsp;=&nbsp;oneDay.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;date2&nbsp;=&nbsp;oneWeek.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;date3&nbsp;=&nbsp;oneMonth.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;date4&nbsp;=&nbsp;oneQuarter.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date&nbsp;date5&nbsp;=&nbsp;oneYear.getTime();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ss&nbsp;=&nbsp;&nbsp;df.format(startDate);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ss1&nbsp;=&nbsp;df.format(date1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ss2&nbsp;=&nbsp;df.format(date2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ss3&nbsp;=&nbsp;df.format(date3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ss4&nbsp;=&nbsp;df.format(date4);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;ss5&nbsp;=&nbsp;df.format(date5);<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Start&nbsp;date&nbsp;is&nbsp;"&nbsp;+&nbsp;ss);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Following&nbsp;review&nbsp;dates&nbsp;are:");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ss1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ss2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ss3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ss4);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ss5);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println();<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;GregorianCalendar[]&nbsp;getDates()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar[]&nbsp;memoryDates&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar[dateArraySize];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memoryDates[0]&nbsp;=&nbsp;firstDay;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memoryDates[1]&nbsp;=&nbsp;oneDay;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memoryDates[2]&nbsp;=&nbsp;oneWeek;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memoryDates[3]&nbsp;=&nbsp;oneMonth;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memoryDates[4]&nbsp;=&nbsp;oneQuarter;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;memoryDates[5]&nbsp;=&nbsp;oneYear;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>return</B>&nbsp;memoryDates;<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;GregorianCalendar&nbsp;getFirstDay()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>return</B>&nbsp;<B>this</B>.firstDay;<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;GregorianCalendar&nbsp;getOneDay()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>return</B>&nbsp;<B>this</B>.oneDay;<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;GregorianCalendar&nbsp;getOneWeek()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>return</B>&nbsp;<B>this</B>.oneWeek;<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;GregorianCalendar&nbsp;getOneMonth()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>return</B>&nbsp;<B>this</B>.oneMonth;<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;GregorianCalendar&nbsp;getOneQuarter()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>return</B>&nbsp;<B>this</B>.oneQuarter;<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;GregorianCalendar&nbsp;getOneYear()&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<B>return</B>&nbsp;<B>this</B>.oneYear;<BR>&nbsp;&nbsp;&nbsp;}<BR>}&nbsp;<BR><BR>下面是使用ReviewDates类列出复习日期的例子程序：<BR><BR><B>import</B>&nbsp;java.util.*;<BR><BR><B>public</B>&nbsp;<B>class</B>&nbsp;ShowDates&nbsp;{<BR>&nbsp;&nbsp;&nbsp;<B>public</B>&nbsp;<B>static</B>&nbsp;<B>void</B>&nbsp;main(String[]&nbsp;args)&nbsp;{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReviewDates&nbsp;rd&nbsp;=&nbsp;<B>new</B>&nbsp;ReviewDates();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rd.listDates();<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GregorianCalendar&nbsp;gc&nbsp;=&nbsp;<B>new</B>&nbsp;GregorianCalendar(2001,&nbsp;Calendar.JANUARY,&nbsp;15);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReviewDates&nbsp;jan15&nbsp;=&nbsp;<B>new</B>&nbsp;ReviewDates(gc);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jan15.listDates();<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR><BR></FONT>
<H4><FONT color=#a52a2a>总结</FONT></H4><BR><FONT color=#a52a2a>&nbsp;这篇文章介绍了关于日期处理的3个重要的类：Date,DateFormat,GregorianCalendar.这些类让你创建日期，转换成字符串，和计算日期基本元素。处理Java中的日期问题，这篇文章只是冰山一角。可是，我在这里介绍的类和方法不仅仅是你学习高级技术的跳板，这些类和方法本身就可以处理很多通常的日期相关的任务<BR></FONT></DIV><img src ="http://www.blogjava.net/yuyi/aggbug/3295.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-04-14 18:36 <a href="http://www.blogjava.net/yuyi/articles/3295.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WTC介绍</title><link>http://www.blogjava.net/yuyi/articles/1875.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Wed, 09 Mar 2005 06:30:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/1875.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/1875.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/1875.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/1875.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/1875.html</trackback:ping><description><![CDATA[<SPAN id=post1 style="FONT-SIZE: 12px; COLOR: #000000"><FONT size=3>BEA公司的TUXEDO，WEBLOGIC作为最优秀的中间件产品,在银行、电信、金融等行业广泛使用，通常采用TUXEDO实现系统的核心业务，用WEBLOGIC做为系统扩展到INTERNET的平台，实现电子商务，由WEBLOGIC调用TUXEDO上的服务，所以TUXEDO与WEBLOGIC之间的互连经常遇到。 <FONT color=#ffffff>egT^</FONT><BR>下面通过一个例子介绍TUXEDO与WEBLOGIC通过WTC进行连接的配置方法。 <FONT color=#ffffff>R</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　q?csm,</FONT><BR>WEBLOGIC与TUXEDO的互连有两中方式，通过JOLT或通过WTC(WEBLOGIC TUXEDO CONNECTOR)。它们都是BEA的产品，WTC不仅能让WEBLOGIC调用TUXEDO中的SERVICE，而且能让TUXEDO调用WEBLOGIC中的EJB;而JOLT只能让WEBLOGIC调用TUXEDO. 但JOLT可以使TUXEDO与WEBSPERE等其他应用 <FONT color=#ffffff>LLpe0</FONT><BR>服务器相连，而WTC只能用于WEBLOGIC与TUXEDO之间进行互连。 <FONT color=#ffffff>:whK</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　/),&amp;p</FONT><BR>一、WTC说明 <FONT color=#ffffff>~</FONT><BR>(1)WEBLOIGIC5.1无法通过WTC与TUXEDO连接. <FONT color=#ffffff>H,\</FONT><BR>(2)WEBLOGIC6.0与TUXEDO连接时,要安装WTC软件包. <FONT color=#ffffff>FCU;</FONT><BR>(3)WTC已集成在在EBLOGIC6.1中,只要配置一下就可以了,不用单独安装WTC软件包. <FONT color=#ffffff>{@B6$9</FONT><BR>(4)目前WTC只支持TUXEDO6.5,TUXEDO8.0两个版本,不支持TUXEDO7.1版本. <FONT color=#ffffff>U</FONT><BR>(5)目前WTC有两个版本, Windows版本支持2000/NT,UNIX为统一版本. <FONT color=#ffffff>7r</FONT><BR>(6)WTC可从http://commerce.bea.com/downloads/tuxedo.jsp下载,目前的版本为1.0. <FONT color=#ffffff>?</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　)kNlr`</FONT><BR>二、WTC安装过程 <FONT color=#ffffff>nwhk</FONT><BR>(1) WEBLOGIC与TUXEDO必须先安装好. <FONT color=#ffffff>.dGv</FONT><BR>(2)WTC要求在JAVA环境下安装，可在命令行下，运行weblogic主目录下config/EXAMPLE/setEnv.sh(NT/2000下为setenv.cmd)配置JAVA环境 <FONT color=#ffffff>^KXG/.</FONT><BR>(3)在DOS命令行下执行安装程序WTC_10_win.exe。按提示操作就可以. <FONT color=#ffffff>S=</FONT><BR>注意:如果在WINDOW下安装，到COPY文件那一步时，不会执行，但提示安装成功，实际是假的。所以应在DOS命令行下安装. <FONT color=#ffffff>b_#</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　k4F</FONT><BR>三、WTC配置说明 <FONT color=#ffffff>MxP?</FONT><BR>TUXEDO与WEBLOGIC之间通过DOMAIN方式实现互相调用，在这个例子中有两个DOMAIN：TUXEDO所在的DOMAIN名为TDOM1， WEBLOGIC所在的 DOMAIN名为TDOM2。TDOM1上有TOUPPER它是一个TUXEDO SERVEICE，TDOM2上有TOLOWER它是一个EJB， <FONT color=#ffffff>h12%</FONT><BR>下面以WTC安装带的例子simpapp(在WTC安装目录的examples/wtc/atmi/simpapp下)说明配置过程: <FONT color=#ffffff>K</FONT><BR>TUXEO版本: TUXEDO65 <FONT color=#ffffff>_CvUrJ</FONT><BR>WEBLOGIC版本: WEBLOGIC6.0 <FONT color=#ffffff>]`[ri</FONT><BR>TUXEO安装目录: D:\TUXEDO65 <FONT color=#ffffff>Ww^cV'</FONT><BR>WEBLOGIC安装目录: D:\WEBLOGIC <FONT color=#ffffff>{_y</FONT><BR>操作系统: WIN2000 <FONT color=#ffffff>N|</FONT><BR>例子目录: D:\SIMPAPP(把WTC安装目录的examples/wtc/atmi/simpapp目录COPY到D:\SIMPAPP) <FONT color=#ffffff>cX6#</FONT><BR>服务器名: DEMOSERVER <FONT color=#ffffff>6_</FONT><BR>WTC安装目录: D:\WEBLOGIC\WTC1.0 <FONT color=#ffffff>n</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　NSU3$%</FONT><BR>四、TUXEDO要做的配置 <FONT color=#ffffff>#s</FONT><BR>(1)修改D:\SIMPAPP\SETENV.CMD为: <FONT color=#ffffff>om</FONT><BR>set TUXDIR=d:\tuxedo65 <FONT color=#ffffff>CBkf9</FONT><BR>set WSNADDR=//DEMOSERVER:8888 <FONT color=#ffffff>A-&lt;}T+</FONT><BR>set APPDIR=d:\simpapp <FONT color=#ffffff>*FYw5!</FONT><BR>set PATH=%TUXDIR%\bin;%APPDIR%;%PATH% <FONT color=#ffffff>@~p/*</FONT><BR>set TUXCONFIG=%APPDIR%\tuxconfig <FONT color=#ffffff>Us9</FONT><BR>set BDMCONFIG=%APPDIR%/dbmconfig <FONT color=#ffffff>Me</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　o/</FONT><BR>(2)修改D:\SIMPAPP\UBBDOMAIN为: <FONT color=#ffffff>\t6AMI</FONT><BR>*RESOURCES <FONT color=#ffffff>*4-TZ</FONT><BR>IPCKEY 123456 <FONT color=#ffffff>8&gt;f=</FONT><BR>DOMAINID simpapp <FONT color=#ffffff>n`Fpw</FONT><BR>MASTER simple <FONT color=#ffffff>_8</FONT><BR>MAXACCESSERS 10 <FONT color=#ffffff>(}</FONT><BR>MAXSERVERS 5 <FONT color=#ffffff>c,AC8E</FONT><BR>MAXSERVICES 10 <FONT color=#ffffff>;5</FONT><BR>MODEL SHM <FONT color=#ffffff>3</FONT><BR>LDBAL N <FONT color=#ffffff>Ed1&lt;</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　:0-J</FONT><BR>*MACHINES <FONT color=#ffffff>LpBCe</FONT><BR>DEMOSERVER LMID=simple <FONT color=#ffffff>L^dO'g</FONT><BR>APPDIR="d:\simpapp" <FONT color=#ffffff>)!lN</FONT><BR>TUXCONFIG="d:\simpapp\tuxconfig" <FONT color=#ffffff>2h'{U6</FONT><BR>TUXDIR="d:\tuxedo65" <FONT color=#ffffff>JbDP</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　z|K0</FONT><BR>*GROUPS <FONT color=#ffffff>Y^'!</FONT><BR>GROUP1 <FONT color=#ffffff>e</FONT><BR>LMID=simple GRPNO=1 OPENINFO=NONE <FONT color=#ffffff>f</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　#z&gt;</FONT><BR>*SERVERS <FONT color=#ffffff>oz&lt;3)f</FONT><BR>DEFAULT: <FONT color=#ffffff>S</FONT><BR>CLOPT="-A" <FONT color=#ffffff>a#FUJ</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　! )-w</FONT><BR>simpserv SRVGRP=GROUP1 SRVID=1 <FONT color=#ffffff>~..PWQ</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　aXE-t</FONT><BR>*SERVICES <FONT color=#ffffff>";mQ2</FONT><BR>TOUPPER <FONT color=#ffffff>\`u</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　la~4</FONT><BR>(3)修改D:\SIMPAPP\DOM1CONFIG: <FONT color=#ffffff>UC/~</FONT><BR>修改dom1config，加入TLOG的路径和AUDITLOG的路径。然后修改TDOM1的NWADDR="IP:PORT"为TUXEDO的IP和端口，TDOM2的 <FONT color=#ffffff>Y^&gt;A8</FONT><BR>NWADDR="IP:PORT"为WEBLOGIC的IP和端口。 <FONT color=#ffffff>]p!Z{</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　nn'!0</FONT><BR>*DM_RESOURCES <FONT color=#ffffff>n</FONT><BR>VERSION=U22 <FONT color=#ffffff>_)".$</FONT><BR>*DM_LOCAL_DOMAINS <FONT color=#ffffff>C-</FONT><BR>TDOM1 GWGRP=GROUP2 <FONT color=#ffffff>)(^_&amp;</FONT><BR>TYPE=TDOMAIN <FONT color=#ffffff>Sp</FONT><BR>DOMAINID="TDOM1" <FONT color=#ffffff>@dJ^0</FONT><BR>BLOCKTIME=20 &nbsp;<FONT color=#ffffff>5Q~-L</FONT><BR>MAXDATALEN=56 &nbsp;<FONT color=#ffffff>i</FONT><BR>MAXRDOM=89 &nbsp;<FONT color=#ffffff>e~;u!</FONT><BR>TLOG="d:\simpapp\TLOG" <FONT color=#ffffff>F&amp;</FONT><BR>AUDITLOG="d:\simpapp\AUDITLOG" <FONT color=#ffffff>EC3/2z</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　1JJ@S&amp;</FONT><BR>*DM_REMOTE_DOMAINS <FONT color=#ffffff>5i~</FONT><BR>TDOM2 TYPE=TDOMAIN <FONT color=#ffffff>{0Xb:Q</FONT><BR>DOMAINID="TDOM2" <FONT color=#ffffff>x.</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　SL7</FONT><BR>*DM_TDOMAIN <FONT color=#ffffff>ZD#</FONT><BR>TDOM1 NWADDR="//DEMOSERVER:9998" <FONT color=#ffffff>84}</FONT><BR>TDOM2 NWADDR="//DEMOSERVER:9999" <FONT color=#ffffff>0|</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　[</FONT><BR>*DM_REMOTE_SERVICES <FONT color=#ffffff>B</FONT><BR>TOLOWER RDOM="TDOM2" <FONT color=#ffffff>#h_`</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　qVeMeW</FONT><BR>(4) tmloadcf -y ubbdomain <FONT color=#ffffff>X1</FONT><BR>(5) mloadcf -y dom1config <FONT color=#ffffff>6</FONT><BR>(6)buildserver -o simpserv -f simpserv.c -s TOUPPER <FONT color=#ffffff>6zw&gt;sA</FONT><BR>(7)将examples/wtc/atmi/simpapp/simpserv下的tolower.c 拷贝到D:\SIMPAPP，并执行buildclinet -v -f tolower.c -o tolower <FONT color=#ffffff>w;01Y</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　M</FONT><BR>五、WEBLOGIC要做的配置 <FONT color=#ffffff>Z9&amp;^i</FONT><BR>(1)修改weblogic目录下config/examples/setExamplesEnv.cmd及startExamplesServer.cmd,在CLASSPATH中加入： <FONT color=#ffffff>3z*5.</FONT><BR>d:\weblogic\wtc1.0\lib/jatmi.jar。执行setExamplesEnv.cmd <FONT color=#ffffff>}H`6g]</FONT><BR>(2)修改bdmconfig.xml &nbsp;<FONT color=#ffffff>m:</FONT><BR>修改&lt;!DOCTYPE&gt;中的:[WTC installation directory]\weblogic\wtc\gwt\wtc_config_1_0.dtd(WLS60) <FONT color=#ffffff>S</FONT><BR>修改TDOM1和TDOM2的NWADDR和TUXEDO中的dom1config中的一致 <FONT color=#ffffff>;</FONT><BR>如果tuxedo为6.5版本则在&lt;T_DM_LOCAL_TDOMAIN AccessPoint="TDOM2"&gt;中加入&lt;Interoperate&gt;Yes&lt;/Interoperate&gt;如果为TUXEOD8.0则不需要。 <FONT color=#ffffff>X</FONT><BR>(3)修改后的bdmconfig.xml内容如下： <FONT color=#ffffff>rB}</FONT><BR>&lt;?xml version="1.0"?&gt; <FONT color=#ffffff>0</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　EIMS,Q</FONT><BR>&lt;!DOCTYPE BDMCONFIG SYSTEM "file:D:\weblogic\wtc1.0\weblogic\wtc\gwt\wtc_config_1_0.dtd"&gt; <FONT color=#ffffff>GnPm|&gt;</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　m</FONT><BR>&lt;!--Java and XML--&gt; <FONT color=#ffffff>H</FONT><BR>&lt;WTC_CONFIG&gt; <FONT color=#ffffff>5:d-DP</FONT><BR>&lt;BDMCONFIG&gt; <FONT color=#ffffff>^</FONT><BR>&lt;T_DM_LOCAL_TDOMAIN AccessPoint="TDOM2"&gt; <FONT color=#ffffff>0wh</FONT><BR>&lt;WlsClusterName&gt;Coolio&lt;/WlsClusterName&gt; <FONT color=#ffffff>d0a</FONT><BR>&lt;AccessPointId&gt;TDOM2&lt;/AccessPointId&gt; <FONT color=#ffffff>oa</FONT><BR>&lt;Type&gt;TDOMAIN&lt;/Type&gt; <FONT color=#ffffff>Ou&amp;+m</FONT><BR>&lt;Security&gt;NONE&lt;/Security&gt; <FONT color=#ffffff>xEetD5</FONT><BR>&lt;ConnectionPolicy&gt;ON_DEMAND&lt;/ConnectionPolicy&gt; <FONT color=#ffffff>@\58</FONT><BR>&lt;BlockTime&gt;30&lt;/BlockTime&gt; <FONT color=#ffffff>b][B&amp;</FONT><BR>&lt;NWAddr&gt;//DEMOSERVER:9999&lt;/NWAddr&gt; <FONT color=#ffffff>r&amp;58d</FONT><BR>&lt;!-- Example address: //mydomain.acme.com:9999 --&gt; <FONT color=#ffffff>!&lt;D0Z</FONT><BR>&lt;Interoperate&gt;Yes&lt;/Interoperate&gt; <FONT color=#ffffff>6p384</FONT><BR>&lt;/T_DM_LOCAL_TDOMAIN&gt; <FONT color=#ffffff>|</FONT><BR>&lt;T_DM_REMOTE_TDOMAIN AccessPoint="TDOM1"&gt; <FONT color=#ffffff>OPj</FONT><BR>&lt;LocalAccessPoint&gt;TDOM2&lt;/LocalAccessPoint&gt; <FONT color=#ffffff>psQY/</FONT><BR>&lt;AccessPointId&gt;TDOM1&lt;/AccessPointId&gt; <FONT color=#ffffff>[</FONT><BR>&lt;Type&gt;TDOMAIN&lt;/Type&gt; <FONT color=#ffffff>vZ-</FONT><BR>&lt;NWAddr&gt;//DEMOSERVER:9998&lt;/NWAddr&gt; <FONT color=#ffffff>Q </FONT><BR>&lt;!-- Example address: //mydomain.acme.com:9998 --&gt; <FONT color=#ffffff>4]QCoZ</FONT><BR>&lt;/T_DM_REMOTE_TDOMAIN&gt; <FONT color=#ffffff>R!QI</FONT><BR>&lt;T_DM_EXPORT ResourceName="TOLOWER" <FONT color=#ffffff>AILhgP</FONT><BR>LocalAccessPoint="TDOM2"&gt; <FONT color=#ffffff>Qp</FONT><BR>&lt;EJBName&gt;tuxedo.services.TOLOWERHome&lt;/EJBName&gt; <FONT color=#ffffff>+F</FONT><BR>&lt;/T_DM_EXPORT&gt; <FONT color=#ffffff>6cM^4?</FONT><BR>&lt;T_DM_IMPORT <FONT color=#ffffff>[\(Mx</FONT><BR>ResourceName="TOUPPER" <FONT color=#ffffff>Ecv&gt;</FONT><BR>LocalAccessPoint="TDOM2" <FONT color=#ffffff>X:</FONT><BR>RemoteAccessPointList="TDOM1"&gt; <FONT color=#ffffff>f</FONT><BR>&lt;TranTime&gt;600&lt;/TranTime&gt; <FONT color=#ffffff>`Uo$</FONT><BR>&lt;/T_DM_IMPORT&gt; <FONT color=#ffffff>LS{</FONT><BR>&lt;/BDMCONFIG&gt; <FONT color=#ffffff>v0W2#L</FONT><BR>&lt;/WTC_CONFIG&gt; <FONT color=#ffffff>&lt;AvNA</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　Yxc</FONT><BR>(4)执行java weblogic.wtc.gwt.WTCValidateCF bdmconfig.xml监测xml是否正确。 <FONT color=#ffffff>;4</FONT><BR>(5)在D:\SIMPAPP下执行build命令,然后在D:\weblogic\wtc1.0\examples\simpserv下执行build命令 <FONT color=#ffffff>0N4|_m</FONT><BR>(6)启动welogic &nbsp;<FONT color=#ffffff>|K2g</FONT><BR>(7)察看wtc_tolower.jar、wtc_toupper.jar是否deploy成功 <FONT color=#ffffff>axv</FONT><BR>(8)建立一个WEBLOGIC StartUp Class: <FONT color=#ffffff>]^&lt;yx</FONT><BR>classname为 weblogic.wtc.gwt.WTCStartup 参数为BDMCONFIG=D:\SIMPAPP\bdmconfig.xml,并设置其TARGET为EXAMPLESERVER <FONT color=#ffffff>!MM%!8</FONT><BR>(9)建立一个WEBLOGIC ShutDown Class: <FONT color=#ffffff>Qq3?&gt;v</FONT><BR>classname为weblogic.wtc.gwt.WTCShutdown,并设置其TARGET为EXAMPLESERVER <FONT color=#ffffff>Gc~X!i</FONT><BR>(10)重新启动weblogic,并注意WEBLOGIC的启动日志看StartUp Class启动过程是否成功,失败会报错,成功没有提示信息 <FONT color=#ffffff>+91(g*</FONT><BR>如果失败没有检查config.xml中是否为 <FONT color=#ffffff>X&lt;E'q2</FONT><BR>&lt;StartupClass Arguments="BDMCONFIG=d:\wtc_load4\examples\simpapp\bdmconfig.xml" ClassName="weblogic.wtc1.0.gwt.WTCStartup" FailureIsFatal="false" Name="MyWTCStartup Class" Targets="myserver"/&gt; <FONT color=#ffffff>@</FONT><BR>&lt;ShutdownClass Arguments="" ClassName="weblogic.wtc1.0.gwt.WTCShutdown" Name="MyWTCShutdown Class"/&gt; <FONT color=#ffffff>H5@</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　}w_bU</FONT><BR>六、启动tuxedo <FONT color=#ffffff>=~</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　Ck8(5G</FONT><BR>七、运行例子 <FONT color=#ffffff>'w(M,a</FONT><BR>在d:/simpapp下执行run.cmd,这是WEBLOGIC 做CLIENT端调用Toupper ejb，由Toupper ejb调用TUXEDO的SERVICE：TOUPPER <FONT color=#ffffff>z</FONT><BR>在d:/simpapp下执行run.cmd，这是TUXEDO做CLIENT端调用WEBLOGIC中的Tolower ejb， <FONT color=#ffffff>&lt;o5*LD</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　F</FONT><BR>八、如果是WEBLOGIC6.1 <FONT color=#ffffff>d6F]</FONT><BR>TUXEDO的配置不变 <FONT color=#ffffff>\93O2</FONT><BR>WEBLOGIC中从(2)开始配置.其中:DMCONFIG.XML中的,因为WEBLOGIC6.1中找不到wtc_config_1_0.dtd,可从WEBLOGIC6.1拷贝一个到WEBLOGIC6.1的安装目录下: <FONT color=#ffffff>&amp;</FONT><BR>如D:\WEBLOGIC6.1,并在DMCONFIG.XML指定它的路径 <FONT color=#ffffff>82{</FONT><BR>&lt;!DOCTYPE BDMCONFIG SYSTEM "file:D:\weblogic6.1\wtc_config_1_0.dtd"&gt; <FONT color=#ffffff>I7]GE</FONT><BR><FONT color=#ffffff>©WhiteLand -- Welcome WhiteLand　　Kb871</FONT><BR>九、失败处理 <FONT color=#ffffff>]/PL</FONT><BR>如果失败,可设置weblogic.wtc.gwt.WTCStartup的跟踪选项，即把它的参数设置为： BDMCONFIG=D:\simpapp\bdmconfig.xml,TraceLevel=20000 <FONT color=#ffffff>am:+7U</FONT><BR>并请查看WEBLOGIC,TUXEDO的日志.做相应的处理。</FONT></SPAN><img src ="http://www.blogjava.net/yuyi/aggbug/1875.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-03-09 14:30 <a href="http://www.blogjava.net/yuyi/articles/1875.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java日期时间处理</title><link>http://www.blogjava.net/yuyi/articles/1815.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Tue, 08 Mar 2005 03:17:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/1815.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/1815.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/1815.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/1815.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/1815.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Java统计从1970年1月1日起的毫秒的数量表示日期。也就是说，例如，1970年1月2日，是在1月1日后的86，400，000毫秒。同样的，1969年12月31日是在1970年1月1日前86，400，000毫秒。Java的Date类使用long类型纪录这些毫秒值.因为long是有符号整数，所以日期可以在1970年1月1日之前，也可以在这之后。Long类型表示的最大正值和最大负值可以轻松的表示29...&nbsp;&nbsp;<a href='http://www.blogjava.net/yuyi/articles/1815.html'>阅读全文</a><img src ="http://www.blogjava.net/yuyi/aggbug/1815.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-03-08 11:17 <a href="http://www.blogjava.net/yuyi/articles/1815.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jspSmartUpload</title><link>http://www.blogjava.net/yuyi/articles/949.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Thu, 03 Feb 2005 03:28:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/949.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/949.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/949.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/949.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/949.html</trackback:ping><description><![CDATA[<DIV>一、安装篇 <BR><BR>　　jspSmartUpload是由<A href="http://www.jspsmart.com网站开发的一个可免费使用的全功能的文件上传下载组件，适于嵌入执行上传下载操作的jsp文件中。该组件有以下几个特点：/" target=_blank><FONT color=#000000>http://www.jspsmart.com网站开发的一...幸韵录父鎏氐悖?/a&gt; <BR><BR>1、使用简单。在JSP文件中仅仅书写三五行JAVA代码就可以搞定文件的上传或下载，方便。 <BR><BR>2、能全程控制上传。利用jspSmartUpload组件提供的对象及其操作方法，可以获得全部上传文件的信息（包括文件名，大小，类型，扩展名，文件数据等），方便存取。 <BR><BR>3、能对上传的文件在大小、类型等方面做出限制。如此可以滤掉不符合要求的文件。 <BR><BR>4、下载灵活。仅写两行代码，就能把Web服务器变成文件服务器。不管文件在Web服务器的目录下或在其它任何目录下，都可以利用jspSmartUpload进行下载。 <BR><BR>5、能将文件上传到数据库中，也能将数据库中的数据下载下来。这种功能针对的是MYSQL数据库，因为不具有通用性，所以本文不准备举例介绍这种用法。 <BR><BR>　　jspSmartUpload组件可以从</FONT><A href="http://www.jspsmart.com网站上自由下载，压缩包的名字是jspsmartupload.zip。下载后，用winzip或winrar将其解压到tomcat的webapps目录下（本文以tomcat服务器为例进行介绍）。解压后，将webapps/jspsmartupload目录下的子目录Web-inf名字改为全大写的WEB-INF，这样一改jspSmartUpload类才能使用。因为Tomcat对文件名大小写敏感，它要求Web应用程序相关的类所在目录为WEB-INF，且必须是大写。接着重新启动Tomcat，这样就可以在JSP文件中使用jspSmartUpload组件了。" target=_blank><FONT color=#000000>http://www.jspsmart.com网站上自由下载，压缩包的名字是jspsmartupload.zip。下载后，用winzip或winrar将其解压到tomcat的webapps目录下（本文以tomcat服务器为例进行介绍）。解压后，将webapps/jspsmartupload目录下的子目录Web-inf名字改为全大写的WEB-INF，这样一改jspSmartUpload类才能使用。因为Tomcat对文件名大小写敏感，它要求Web应用程序相关的类所在目录为WEB-INF，且必须是大写。接着重新启动Tomcat，这样就可以在JSP文件中使用jspSmartUpload组件了。</FONT></A> <BR><BR>　　注意，按上述方法安装后，只有webapps/jspsmartupload目录下的程序可以使用jspSmartUpload组件，如果想让Tomcat服务器的所有Web应用程序都能用它，必须做如下工作： <BR><BR>1．进入命令行状态，将目录切换到Tomcat的webapps/jspsmartupload/WEB-INF目录下。 <BR><BR>2．运行JAR打包命令：jar cvf jspSmartUpload.jar com <BR><BR>（也可以打开资源管理器，切换到当前目录，用WinZip将com目录下的所有文件压缩成jspSmartUpload.zip，然后将jspSmartUpload.zip换名为jspSmartUpload.jar文件即可。） <BR><BR>3．将jspSmartUpload.jar拷贝到Tomcat的shared/lib目录下。</DIV>
<DIV>
<DIV>二、相关类说明篇 <BR><BR>㈠ File类 <BR><BR>　　这个类包装了一个上传文件的所有信息。通过它，可以得到上传文件的文件名、文件大小、扩展名、文件数据等信息。 <BR><BR>　　File类主要提供以下方法： <BR><BR>1、saveAs作用：将文件换名另存。 <BR><BR>原型： <BR><BR>public void saveAs(java.lang.String destFilePathName) <BR><BR>或 <BR><BR>public void saveAs(java.lang.String destFilePathName, int optionSaveAs) <BR><BR>其中，destFilePathName是另存的文件名，optionSaveAs是另存的选项，该选项有三个值，分别是SAVEAS_PHYSICAL,SAVEAS_VIRTUAL，SAVEAS_AUTO。SAVEAS_PHYSICAL表明以操作系统的根目录为文件根目录另存文件，SAVEAS_VIRTUAL表明以Web应用程序的根目录为文件根目录另存文件，SAVEAS_AUTO则表示让组件决定，当Web应用程序的根目录存在另存文件的目录时，它会选择SAVEAS_VIRTUAL，否则会选择SAVEAS_PHYSICAL。 <BR><BR>例如，saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)执行后若Web服务器安装在C盘，则另存的文件名实际是c:\upload\sample.zip。而saveAs("/upload/sample.zip",SAVEAS_VIRTUAL)执行后若Web应用程序的根目录是webapps/jspsmartupload，则另存的文件名实际是webapps/jspsmartupload/upload/sample.zip。saveAs("/upload/sample.zip",SAVEAS_AUTO)执行时若Web应用程序根目录下存在upload目录，则其效果同saveAs("/upload/sample.zip",SAVEAS_VIRTUAL)，否则同saveAs("/upload/sample.zip",SAVEAS_PHYSICAL)。 <BR><BR>建议：对于Web程序的开发来说，最好使用SAVEAS_VIRTUAL，以便移植。 <BR><BR>2、isMissing <BR><BR>作用：这个方法用于判断用户是否选择了文件，也即对应的表单项是否有值。选择了文件时，它返回false。未选文件时，它返回true。 <BR><BR>原型：public boolean isMissing() <BR><BR>3、getFieldName <BR><BR>作用：取HTML表单中对应于此上传文件的表单项的名字。 <BR><BR>原型：public String getFieldName() <BR><BR>4、getFileName <BR><BR>作用：取文件名（不含目录信息） <BR><BR>原型：public String getFileName() <BR><BR>5、getFilePathName <BR><BR>作用：取文件全名（带目录） <BR><BR>原型：public String getFilePathName <BR><BR>6、getFileExt <BR><BR>作用：取文件扩展名（后缀） <BR><BR>原型：public String getFileExt() <BR><BR>7、getSize <BR><BR>作用：取文件长度（以字节计） <BR><BR>原型：public int getSize() <BR><BR>8、getBinaryData <BR><BR>作用：取文件数据中指定位移处的一个字节，用于检测文件等处理。 <BR><BR>原型：public byte getBinaryData(int index)。其中，index表示位移，其值在0到getSize()-1之间。 <BR><BR>㈡ Files类 <BR><BR>　　这个类表示所有上传文件的集合，通过它可以得到上传文件的数目、大小等信息。有以下方法： <BR><BR>1、getCount <BR><BR>作用：取得上传文件的数目。 <BR><BR>原型：public int getCount() <BR><BR>2、getFile <BR><BR>作用：取得指定位移处的文件对象File（这是com.jspsmart.upload.File，不是java.io.File，注意区分）。 <BR><BR>原型：public File getFile(int index)。其中，index为指定位移，其值在0到getCount()-1之间。 <BR><BR>3、getSize <BR><BR>作用：取得上传文件的总长度，可用于限制一次性上传的数据量大小。 <BR><BR>原型：public long getSize() <BR><BR>4、getCollection <BR><BR>作用：将所有上传文件对象以Collection的形式返回，以便其它应用程序引用，浏览上传文件信息。 <BR><BR>原型：public Collection getCollection() <BR><BR>5、getEnumeration <BR><BR>作用：将所有上传文件对象以Enumeration（枚举）的形式返回，以便其它应用程序浏览上传文件信息。 <BR><BR>原型：public Enumeration getEnumeration() <BR><BR>㈢ Request类 <BR><BR>　　这个类的功能等同于JSP内置的对象request。只所以提供这个类，是因为对于文件上传表单，通过request对象无法获得表单项的值，必须通过jspSmartUpload组件提供的Request对象来获取。该类提供如下方法： <BR><BR>1、getParameter <BR><BR>作用：获取指定参数之值。当参数不存在时，返回值为null。 <BR><BR>原型：public String getParameter(String name)。其中，name为参数的名字。 <BR><BR>2、getParameterValues <BR><BR>作用：当一个参数可以有多个值时，用此方法来取其值。它返回的是一个字符串数组。当参数不存在时，返回值为null。 <BR><BR>原型：public String[] getParameterValues(String name)。其中，name为参数的名字。 <BR><BR>3、getParameterNames <BR><BR>作用：取得Request对象中所有参数的名字，用于遍历所有参数。它返回的是一个枚举型的对象。 <BR><BR>原型：public Enumeration getParameterNames()</DIV>
<DIV>
<DIV>㈣ SmartUpload类这个类完成上传下载工作。 <BR><BR>A．上传与下载共用的方法： <BR><BR>只有一个：initialize。 <BR><BR>作用：执行上传下载的初始化工作，必须第一个执行。 <BR><BR>原型：有多个，主要使用下面这个： <BR><BR>public final void initialize(javax.servlet.jsp.PageContext pageContext) <BR><BR>其中，pageContext为JSP页面内置对象（页面上下文）。 <BR><BR>B．上传文件使用的方法： <BR><BR>1、upload <BR><BR>作用：上传文件数据。对于上传操作，第一步执行initialize方法，第二步就要执行这个方法。 <BR><BR>原型：public void upload() <BR><BR>2、save <BR><BR>作用：将全部上传文件保存到指定目录下，并返回保存的文件个数。 <BR><BR>原型：public int save(String destPathName) <BR><BR>和public int save(String destPathName,int option) <BR><BR>其中，destPathName为文件保存目录，option为保存选项，它有三个值，分别是SAVE_PHYSICAL,SAVE_VIRTUAL和SAVE_AUTO。（同File类的saveAs方法的选项之值类似）SAVE_PHYSICAL指示组件将文件保存到以操作系统根目录为文件根目录的目录下，SAVE_VIRTUAL指示组件将文件保存到以Web应用程序根目录为文件根目录的目录下，而SAVE_AUTO则表示由组件自动选择。 <BR><BR>注：save(destPathName)作用等同于save(destPathName,SAVE_AUTO)。 <BR><BR>3、getSize <BR><BR>作用：取上传文件数据的总长度 <BR><BR>原型：public int getSize() <BR><BR>4、getFiles <BR><BR>作用：取全部上传文件，以Files对象形式返回，可以利用Files类的操作方法来获得上传文件的数目等信息。 <BR><BR>原型：public Files getFiles() <BR><BR>5、getRequest <BR><BR>作用：取得Request对象，以便由此对象获得上传表单参数之值。 <BR><BR>原型：public Request getRequest() <BR><BR>6、setAllowedFilesList <BR><BR>作用：设定允许上传带有指定扩展名的文件，当上传过程中有文件名不允许时，组件将抛出异常。 <BR><BR>原型：public void setAllowedFilesList(String allowedFilesList) <BR><BR>其中，allowedFilesList为允许上传的文件扩展名列表，各个扩展名之间以逗号分隔。如果想允许上传那些没有扩展名的文件，可以用两个逗号表示。例如：setAllowedFilesList("doc,txt,,")将允许上传带doc和txt扩展名的文件以及没有扩展名的文件。 <BR><BR>7、setDeniedFilesList <BR><BR>作用：用于限制上传那些带有指定扩展名的文件。若有文件扩展名被限制，则上传时组件将抛出异常。 <BR><BR>原型：public void setDeniedFilesList(String deniedFilesList) <BR><BR>其中，deniedFilesList为禁止上传的文件扩展名列表，各个扩展名之间以逗号分隔。如果想禁止上传那些没有扩展名的文件，可以用两个逗号来表示。例如：setDeniedFilesList("exe,bat,,")将禁止上传带exe和bat扩展名的文件以及没有扩展名的文件。 <BR><BR>8、setMaxFileSize <BR><BR>作用：设定每个文件允许上传的最大长度。 <BR><BR>原型：public void setMaxFileSize(long maxFileSize) <BR><BR>其中，maxFileSize为为每个文件允许上传的最大长度，当文件超出此长度时，将不被上传。 <BR><BR>9、setTotalMaxFileSize <BR><BR>作用：设定允许上传的文件的总长度，用于限制一次性上传的数据量大小。 <BR><BR>原型：public void setTotalMaxFileSize(long totalMaxFileSize) <BR><BR>其中，totalMaxFileSize为允许上传的文件的总长度。</DIV>
<DIV>
<DIV><B>jsp 上传图片并生成缩位图或者加水印</B><BR>有些网站　　动网，　上传图片后加给加上自己的字（是在图片上加的）<BR><BR>　请问在JSP里如何实现？？<BR>//添加水印,filePath 源图片路径， watermark 水印图片路径<BR>public static boolean createMark(String filePath,String watermark) {<BR>ImageIcon imgIcon=new ImageIcon(filePath);<BR>Image theImg =imgIcon.getImage();<BR>ImageIcon waterIcon=new ImageIcon(watermark);<BR>Image waterImg =waterIcon.getImage();<BR>int width=theImg.getWidth(null);<BR>int height= theImg.getHeight(null);<BR>BufferedImage bimage = new BufferedImage(width,height, BufferedImage.TYPE_INT_RGB); <BR>Graphics2D g=bimage.createGraphics( );<BR>g.setColor(Color.red);<BR>g.setBackground(Color.white);<BR>g.drawImage(theImg, 0, 0, null );<BR>g.drawImage(waterImg, 100, 100, null );<BR>g.drawString("12233",10,10); //添加文字<BR>g.dispose();<BR>try{<BR>FileOutputStream out=new FileOutputStream(filePath);<BR>JPEGImageEncoder encoder =JPEGCodec.createJPEGEncoder(out); <BR>JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage); <BR>param.setQuality(50f, true); <BR>encoder.encode(bimage, param); <BR>out.close();<BR>}catch(Exception e){ return false; }<BR>return true;<BR>}<BR><BR>/////////////////范例////////////////////<BR>package package;<BR><BR>import java.io.*;<BR>import javax.servlet.ServletException;<BR>import javax.servlet.ServletInputStream;<BR>import javax.servlet.http.HttpServletRequest;<BR><BR>public class upload<BR>{<BR><BR>private static String newline = "\n";<BR>private String uploadDirectory;<BR>private String ContentType;<BR>private String CharacterEncoding;<BR><BR>public upload()<BR>{<BR>uploadDirectory = ".";<BR>ContentType = "";<BR>CharacterEncoding = "";<BR>}<BR><BR>private String getFileName(String s)<BR>{<BR>int i = s.lastIndexOf("\\");<BR>if(i &lt; 0 || i &gt;= s.length() - 1)<BR>{<BR>i = s.lastIndexOf("/");<BR>if(i &lt; 0 || i &gt;= s.length() - 1)<BR>return s;<BR>}<BR>return s.substring(i + 1);<BR>}<BR><BR>public void setUploadDirectory(String s)<BR>{<BR>uploadDirectory = s;<BR>}<BR><BR>public void setContentType(String s)<BR>{<BR>ContentType = s;<BR>int i;<BR>if((i = ContentType.indexOf("boundary=")) != -1)<BR>{<BR>ContentType = ContentType.substring(i + 9);<BR>ContentType = "--" + ContentType;<BR>}<BR>}<BR><BR>public void setCharacterEncoding(String s)<BR>{<BR>CharacterEncoding = s;<BR>}<BR><BR>public String uploadFile(HttpServletRequest httpservletrequest)<BR>throws ServletException, IOException<BR>{<BR>String s = null;<BR>setCharacterEncoding(httpservletrequest.getCharacterEncoding());<BR>setContentType(httpservletrequest.getContentType());<BR>s = uploadFile(httpservletrequest.getInputStream());<BR>return s;<BR>}<BR><BR>public String uploadFile(ServletInputStream servletinputstream)<BR>throws ServletException, IOException<BR>{<BR>String s = null;<BR>String s1 = null;<BR>byte abyte0[] = new byte[4096];<BR>byte abyte1[] = new byte[4096];<BR>int ai[] = new int[1];<BR>int ai1[] = new int[1];<BR>String s2;<BR>while((s2 = readLine(abyte0, ai, servletinputstream, CharacterEncoding)) != null) <BR>{<BR>int i = s2.indexOf("filename=");<BR>if(i &gt;= 0)<BR>{<BR>s2 = s2.substring(i + 10);<BR>if((i = s2.indexOf("\"")) &gt; 0)<BR>s2 = s2.substring(0, i);<BR>break;<BR>}<BR>}<BR>s1 = s2;<BR>if(s1 != null &amp;&amp; !s1.equals("\""))<BR>{<BR>s1 = getFileName(s1);<BR>String s3 = readLine(abyte0, ai, servletinputstream, CharacterEncoding);<BR>if(s3.indexOf("Content-Type") &gt;= 0)<BR>readLine(abyte0, ai, servletinputstream, CharacterEncoding);<BR>File file = new File(uploadDirectory, s1);<BR>FileOutputStream fileoutputstream = new FileOutputStream(file);<BR>while((s3 = readLine(abyte0, ai, servletinputstream, CharacterEncoding)) != null) <BR>{<BR>if(s3.indexOf(ContentType) == 0 &amp;&amp; abyte0[0] == 45)<BR>break;<BR>if(s != null)<BR>{<BR>fileoutputstream.write(abyte1, 0, ai1[0]);<BR>fileoutputstream.flush();<BR>}<BR>s = readLine(abyte1, ai1, servletinputstream, CharacterEncoding);<BR>if(s == null || s.indexOf(ContentType) == 0 &amp;&amp; abyte1[0] == 45)<BR>break;<BR>fileoutputstream.write(abyte0, 0, ai[0]);<BR>fileoutputstream.flush();<BR>}<BR>byte byte0;<BR>if(newline.length() == 1)<BR>byte0 = 2;<BR>else<BR>byte0 = 1;<BR>if(s != null &amp;&amp; abyte1[0] != 45 &amp;&amp; ai1[0] &gt; newline.length() * byte0)<BR>fileoutputstream.write(abyte1, 0, ai1[0] - newline.length() * byte0);<BR>if(s3 != null &amp;&amp; abyte0[0] != 45 &amp;&amp; ai[0] &gt; newline.length() * byte0)<BR>fileoutputstream.write(abyte0, 0, ai[0] - newline.length() * byte0);<BR>fileoutputstream.close();<BR>}<BR>return s1;<BR>}<BR><BR>private String readLine(byte abyte0[], int ai[], ServletInputStream servletinputstream, String s)<BR>{<BR>ai[0] = servletinputstream.readLine(abyte0, 0, abyte0.length);<BR>if(ai[0] == -1)<BR>return null;<BR>break MISSING_BLOCK_LABEL_27;<BR>Object obj;<BR>obj;<BR>return null;<BR>if(s == null)<BR>return new String(abyte0, 0, ai[0]);<BR>return new String(abyte0, 0, ai[0], s);<BR>obj;<BR>return null;<BR>}<BR><BR>}<BR><BR><BR>JSP页：<BR><BR>&lt;%@page contentType="text/html;charset=gb2312" import="package.upload"%&gt; <BR>&lt;%<BR>String Dir = "c:\dir\upload"; <BR>String fn="";<BR>upload upload = new upload(); <BR>upload.setUploadDirectory(Dir); <BR>fn=upload.uploadFile(request); <BR>%&gt;</DIV>
<DIV>
<DIV><B>随机图片名称</B><BR>&lt;%<BR>mySmartUpload.initialize(pageContext); <BR>mySmartUpload.service(request,response); <BR>mySmartUpload.upload(); <BR>String fn=mySmartUpload.getFiles().getFile(0).getFileName();<BR>mySmartUpload.save("upload/"); //文件保存的目录为upload<BR>out.println("已经成功上传了文件，请查看&lt;a href=upload/"+fn+"&gt;这里&lt;/a&gt;");<BR>%&gt;<BR>上面的程序可以上传图片，不过只能上传gif或者JPG图片。<BR>而且保存图片在upload文件夹下面，要想GIF或Jpg图片的名称变为年+月+日+随机数.gif或年+月+日+随机数.jpg<BR>只允许上传jpg或gif图片，在客户端用javaScript控制要好些。<BR>变图片名称可用如下代码：自己看看就明白了。:<BR>//得到实际路径<BR><BR>String realPath = this.masRequest.getRequest().getRealPath("/"); <BR>String userPhotoPath = realPath + "images\\UserPhoto\\";<BR>userPhotoPath = MasString.replace(userPhotoPath,"\\","\\\\");<BR>if (!file.getFileName().trim().equals(""))<BR>{<BR>//根据系统时间生成文件名<BR>Date nowTime = new Date();<BR>emp_Photo = userPhotoPath + String.valueOf(nowTime.getTime()) +"."+ file.getFileExt();<BR>file.saveAs(emp_Photo);<BR>System.out.println("file.saveAs() = " + "OK!!!");<BR>}</DIV><!-- / message --><!-- sig --></DIV><!-- / message --><!-- sig --></DIV><!-- / message --><!-- sig --></DIV><!-- / message --><!-- sig --></DIV><!-- / message --><!-- sig --><img src ="http://www.blogjava.net/yuyi/aggbug/949.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-02-03 11:28 <a href="http://www.blogjava.net/yuyi/articles/949.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在JSP中使用JavaMail</title><link>http://www.blogjava.net/yuyi/articles/947.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Thu, 03 Feb 2005 03:20:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/947.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/947.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/947.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/947.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/947.html</trackback:ping><description><![CDATA[<P>你希望在jsp中建立一个邮件发送收取工具吗？下面将介绍的就是在jsp中建立一个邮件发送收取工具。在这篇文章中你可以了解到JavaMail API的一些要点以及如何在JSP中使用它。本文中还包括了在JSP中使用JavaMail的实例。JavaMail是JSP应用软件中相当强大的API。 <BR><BR>阅读这篇文章需要对JSP、JavaBeans和JavaMail有一定的初步了解。当然，有关于JavaMail的知识你可以通过阅读这篇文章来获得。如果你对于以上三项一无所知，但你所使用的服务器支持JSP和JavaMail的话，你可以仅仅通过复制/粘贴来使用它们。 <BR><BR><BR>什么是JavaMail <BR><BR><BR>JavaMail是Sun发布的用来处理email的API。它可以方便地执行一些常用的邮件传输。 <BR><BR><BR>虽然JavaMail是Sun的API之一，但它目前还没有被加在标准的java开发工具包中（Java Development Kit），这就意味着你在使用前必须另外下载JavaMail文件。除此以外，你还需要有Sun的JavaBeans Activation Framework （JAF）。JavaBeans Activation Framework的运行很复杂，在这里简单的说就是JavaMail的运行必须得依赖于它的支持。在Windows 2000下使用需要指定这些文件的路径，在其它的操作系统上也类似。 <BR><BR><BR>接下来要讲解的是这篇指南的最难理解的部分。 <BR><BR><BR>这篇指南包括三部分：HTML表格、关于JavaMail、JavaMail和JSP的结合。 <BR><BR><BR>第一部分：HTML表格 <BR><BR><BR>第一部分提供了一个最基本的基于HTML的email发送收取程序的例子。第二部分则讲述JavaMail的工作原理。第三部分则介绍将JavaMail加入JSP，创建一个基本的email发送收取程序。 <BR><BR><BR>划分组件 <BR><BR><BR>JSP最重要的特性是能将整个网页划分成一些细小的组件。这里使用的组件包括： <BR><BR><BR>●一个用来将email的信息发送给JSP的HTML表格； <BR><BR><BR>●一个JSP页面用来处理和发送信件。 <BR><BR><BR>第一步，就是创建一个HTML表格用来给JSP页面发送信息。你可以将以下的HTML代码复制到你的电脑上： <BR><BR><BR>用来发送email的HTML源代码 <BR><BR><BR>&lt;HTML&gt; <BR><BR>&lt;BODY&gt; <BR><BR>&lt;FORM action="sendmail.jsp" method="post"&gt; <BR><BR>&lt;TABLE align="center"&gt; <BR><BR>&lt;TR&gt; <BR><BR>&lt;TD width="50%"&gt; <BR><BR>To:&lt;BR&gt;&lt;INPUT name="to" size="25"&gt; <BR><BR>&lt;/TD&gt; <BR><BR>&lt;TD width="50%"&gt; <BR><BR>From:&lt;BR&gt;&lt;INPUT name="from" size="25"&gt; <BR><BR>&lt;/TD&gt; <BR><BR>&lt;/TR&gt; <BR><BR>&lt;TR&gt; <BR><BR>&lt;TD colspan="2"&gt; <BR><BR>Subject:&lt;BR&gt;&lt;INPUT name="subject" size="50"&gt; <BR><BR>&lt;/TD&gt; <BR><BR>&lt;/TR&gt; <BR><BR>&lt;TR&gt; <BR><BR>&lt;TD colspan="2"&gt; <BR><BR>&lt;P&gt;Message:&lt;BR&gt;&lt;TEXTAREA name="text" rows=25 cols=85&gt;&lt;/TEXTAREA&gt;&lt;/P&gt; <BR><BR>&lt;/TD&gt; <BR><BR>&lt;/TR&gt; <BR><BR>&lt;/TABLE&gt; <BR><BR>&lt;INPUT type="submit" name="cb_submit" value=" Send "&gt; <BR><BR>&lt;INPUT type="reset" name="cb_reset" value=" Clear "&gt; <BR><BR>&lt;/FORM&gt; <BR><BR>&lt;/BODY&gt; <BR><BR>&lt;/HTML&gt; <BR><BR>以上这段程序将创建一个包含email基本信息（例如：收件地址、发送地址、主题和内容）的文件。当然你可以根据你自己的需要来决定这个文件包含那些信息。 <BR><BR><BR>这个HTML文件的使用有两点要求：第一点是生成的文件必须发送给接下来将介绍的程序使用。在这个例子中就是sendmail.jsp，但在你使用时，必须用这个文件在系统里的URL来代替它；第二点是必须有空间来允许用户发送email。 <BR><BR><BR>第二部分将对JavaMail的特征进行一些分析，为在第三部分创建JSP程序作准备。所以接下来我们将学习JavaMail。 <BR><BR><BR>第二部分：关于JavaMail <BR><BR>文档的使用 <BR><BR><BR>下载的JavaMail API中带的文档是很有用的。你可以在JavaMail下的/docs/javadocs/index.html找到它。第二部分主要将分析邮件程序的组件。你可以通过阅读文档来获得更多这方面的信息。 <BR><BR><BR>组件发送邮件需要使用JavaMail，它使对邮件的操作变得简单易用。</P>
<P>属性对象 <BR><BR><BR>JavaMail需要创建一个格式为"mail.smtp.host"的文件用来发送信息。 <BR><BR><BR>Properties props = new Properties (); <BR><BR><BR>props.put("mail.smtp.host", "smtp.jspinsider.com"); 对话对象 <BR><BR><BR>所有的基于JavaMail的程序都至少需要一个或全部的对话目标。 <BR><BR><BR>Session sendMailSession; <BR><BR><BR>sendMailSession = Session.getInstance(props, null); <BR><BR><BR>传输 <BR><BR><BR>邮件的传输只有送出或受到两种状态。JavaMail将这两种不同状态描述为传输和储存。传输将送出邮件，而储存将收取邮件。 <BR><BR><BR>Transport transport; <BR><BR><BR>transport = sendMailSession.getTransport("smtp"); <BR><BR><BR>使用JavaMail能为我们节约大量的时间。JavaMail能代替所有的SMTP的工作。 <BR><BR><BR>注意：JavaMail并不能完全的支持所有的邮件发送收取工作。它目前仅支持IMAP、SMTP和POP3，除此以外你只有等待新的JavaMail版本或自己开发协议。 <BR><BR><BR>信息对象 <BR><BR><BR>信息对象将把你所发送的邮件真实的反映出来。 <BR><BR><BR>Message newMessage = new MimeMessage(sendMailSession); <BR><BR><BR>这就是我们所需要的全部四个对象。下一步将是如何将对象加入到JSP中。 <BR><BR><BR>第三部分：JavaMail和JSP的结合 <BR><BR><BR>创建JSP <BR><BR>下面我们将开始将他们结合在一起。最重要的一点是要确认根据页面指示分类。还要记得在邮件上标注java.util.date。 <BR><BR><BR>&lt;%@ page <BR><BR>import= " javax.mail.*, javax.mail.internet.*, javax.activation.*, java.util.*" <BR><BR>%&gt; <BR><BR>其次，创建邮件发送的确认信息。确认信息可以是任意的，一般常用"你的邮件已经发送出去了（Your mail has been sent）。" <BR><BR><BR>信息是如何创建和发送的 <BR><BR><BR>我们在第二部分里已经讨论过信息对象的创建。我们下面将对信息进行操作。这就和设置信息对象的属性一样简单。你可以通过下面的程序来实现这项操作。 <BR><BR><BR>newMessage.setFrom(new InternetAddress(request.getParameter("from"))); <BR><BR><BR>newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("to"))); <BR><BR><BR>newMessage.setSubject(request.getParameter("subject")); <BR><BR><BR>newMessage.setSentDate(new Date()); <BR><BR><BR>newMessage.setText(request.getParameter("text")); <BR><BR><BR>现在将开始发送信息。通过JavaMail来实现它非常简单。 <BR><BR><BR>transport.send(newMessage); <BR><BR><BR>将所有的组件结合在一起 <BR><BR><BR>现在所有的组件都已经齐全了。现在将它们都放在JSP里面。要注意每一个错误信息，并将它反馈给用户。代码如下，你可以通过复制它们直接使用： <BR><BR><BR>Sample JSP email Utility Using JavaMail <BR><BR>&lt;%@ page <BR><BR>import=" javax.mail.*, javax.mail.internet.*, javax.activation.*,java.util.*" <BR><BR>%&gt; <BR><BR>&lt;html&gt; <BR><BR>&lt;head&gt; <BR><BR>&lt;TITLE&gt;JSP meets JavaMail, what a sweet combo.&lt;/TITLE&gt; <BR><BR>&lt;/HEAD&gt; <BR><BR>&lt;BODY&gt; <BR><BR>&lt;% <BR><BR>try{ <BR><BR>Properties props = new Properties(); <BR><BR>Session sendMailSession; <BR><BR>Store store; <BR><BR>Transport transport; <BR><BR>sendMailSession = Session.getInstance(props, null); <BR><BR>props.put("mail.smtp.host", "smtp.jspinsider.com"); <BR><BR>Message newMessage = new MimeMessage(sendMailSession); <BR><BR>newMessage.setFrom(new InternetAddress(request.getParameter("from"))); <BR><BR>newMessage.setRecipient(Message.RecipientType.TO, new InternetAddress(request.getParameter("to"))); <BR><BR>newMessage.setSubject(request.getParameter("subject")); <BR><BR>newMessage.setSentDate(new Date()); <BR><BR>newMessage.setText(request.getParameter("text")); <BR><BR>transport = sendMailSession.getTransport("smtp"); <BR><BR>transport.send(newMessage); <BR><BR>%&gt; <BR><BR>&lt;P&gt;Your mail has been sent.&lt;/P&gt; <BR><BR>&lt;% <BR><BR>} <BR><BR>catch(MessagingException m) <BR><BR>{ <BR><BR>out.println(m.toString()); <BR><BR>} <BR><BR>%&gt; <BR><BR>&lt;/BODY&gt; <BR><BR>&lt;/HTML&gt; <BR><BR>你会很快体会到JavaMail的方便之处，JSP和JavaMail将是未来的希望。<BR><BR><BR><BR>文件/图片上传<BR>package uploadfile; <BR><BR>import javax.servlet.ServletInputStream; <BR>import javax.servlet.http.HttpServletRequest; <BR>import java.io.FileOutputStream; <BR>import java.io.*; <BR>import java.util.Hashtable; <BR>import java.util.*; <BR><BR>public class FileUploadBean { <BR><BR>private String savePath=null; //文件上传保存的路径 <BR>private String contentType=""; //内容类型 <BR>private String charEncode=null; //字符编码 <BR>private String boundary=""; //分界线 <BR>private String fileName=null; //本地文件名字 <BR>private Hashtable dic=new Hashtable(); //用于保存"元素名--元素值"对 <BR>private int totalSize=0; //上传文件总大小 <BR>private String path=""; //保存文件的路径 <BR>private String newFileName=""; //存入随机产生的文件名 <BR><BR><BR>/////////////////////////////////////////////////// <BR>//设置文件上传保存的路径 <BR>public void setSavePath(String s) { <BR>s=path+s; <BR>savePath=s; <BR>System.out.println("上传路径："+savePath); <BR>} <BR><BR>/////////////////////////////////////////////////// <BR>//取文件上传保存的路径 <BR>public String getSavePath() { <BR>return savePath; <BR><BR>} <BR><BR>//////////////////////////////////////////////////// <BR>//设置文件名字,也可以为它命名,暂时先用它原来的名字 <BR>public void setFileName(String s) { <BR>int pos=s.indexOf("\"; filename=\""); <BR>if (pos&gt;0) { <BR>s=s.substring(pos+13,s.length()-3); //去 " 和 crlf <BR>pos=s.lastIndexOf("\\"); <BR>if (pos&lt;0) <BR>pos=s.lastIndexOf("/"); <BR>if (pos&lt;0) <BR>fileName=s; <BR>fileName=s.substring(pos+1); <BR>} <BR>} <BR><BR>//////////////////////////////////////////////////// <BR>//取得文件名 <BR>public String getFileName() { <BR>System.out.println("得到文件名"+newFileName); <BR>return newFileName; <BR><BR>} <BR>/////////////////////////// <BR>//以时间为种子数产生新文件名 <BR>public String getNewFileName() { <BR>int pos=0; //.的位置 <BR>long seed=0; //随机种子数 <BR>String ext=""; //存入文件扩展名 <BR>System.out.println("upload file name："+fileName); <BR>pos=fileName.lastIndexOf("."); <BR>ext=fileName.substring(pos); //得到扩展名 <BR>seed=new Date().getTime(); <BR>Random rand=new Random(seed);//以时间为种子产生随机数作为文件名 <BR>newFileName=Long.toString(Math.abs(rand.nextInt()))+ext; //生成文件名 <BR>System.out.println("new file name:"+newFileName); <BR>return newFileName; <BR><BR>} <BR>////////////////////////////////////////////////////// <BR>//设置字符的编码方式 <BR>public void setCharEncode(HttpServletRequest req) { <BR>charEncode=req.getCharacterEncoding(); <BR>} <BR><BR><BR><BR><BR>///////////////////////////////////////////////// <BR>//设置得ContentType <BR>public void setBoundary(HttpServletRequest req) { <BR>//传递的参数值类似"multipart/form-data; boundary=---------------------------7d21441a30013c" <BR>//传过来的分界线比实际显示在上传数据中的要多两个"--" <BR><BR>boundary=req.getContentType(); <BR>//System.out.println("boundary"+boundary); <BR>int pos=boundary.indexOf("boundary="); <BR>//加上这两个"--" <BR>boundary="--"+boundary.substring(pos+9); <BR><BR><BR>} <BR><BR>//////////////////////////////////////////////////// <BR>//取得ContentType <BR>public String getBoundary(){ <BR>//返回值类似"-----------------------------7d21441a30013c" <BR>return boundary; <BR>} <BR><BR><BR>///////////////////////////////////////////// <BR>//设置ContentType <BR>public void setContentType(String s) { <BR>int pos =s.indexOf(": "); <BR>if (pos!=-1) <BR>contentType=s.substring(pos+2); <BR>} <BR><BR>//////////////////////////////////////////// <BR>//取得ContentType <BR>public String getContentType() { <BR>return contentType; <BR>} <BR><BR>///////////////////////////////////////////// <BR>//初始化 <BR>public void init(HttpServletRequest req) { <BR>setCharEncode(req); <BR>setBoundary(req); <BR><BR>} <BR><BR><BR>//////////////////////////////////////////////////// <BR>//取哈希表中的数据 <BR>public String getFieldValue(String s) { <BR>String temp=""; <BR>if(dic.containsKey(s)) //判断表中是否存在s键,不判断则返回nullpointerException <BR>{ <BR>temp=(String)dic.get(s); <BR>temp=temp.trim(); <BR>}else <BR>temp=""; <BR>return temp; <BR>} <BR><BR><BR><BR>//////////////////////////////////////////////// <BR>////用指定的编码方式生成字符串 <BR>public String newLine(byte oneLine[],int sp,int i,String charEncode) <BR>throws java.io.UnsupportedEncodingException { <BR>sp=0; // start position <BR>String lineStr=null; <BR>if (charEncode!=null) { <BR>return lineStr=new String(oneLine,sp,i,charEncode); //用指定的编码方式生成字符串 <BR>} <BR>else { <BR>return lineStr=new String(oneLine,sp,i); <BR>} <BR>} <BR><BR>/////////////////////////////////////////////// <BR>//得到上传文件的大小 <BR>public int getTotalSize() { <BR>return totalSize/1000; <BR>} <BR>/////////////////////////////////////// <BR>//删除指定路径的文件 <BR>public boolean delFiles(String fn) //fn为要删除的文件名，不包括路径 <BR>{ <BR>try <BR>{ <BR>File file=new File(savePath+fn); <BR>System.out.println(savePath+fn); <BR>if(file.exists()) <BR>{ <BR>file.delete(); <BR>System.out.println(file.getPath()+"delete file successfully!"); <BR>return true; <BR>}else <BR>{ <BR>System.out.println("the file is not existed!"); <BR>return true; <BR>} <BR>}catch(Exception e) <BR>{ <BR>System.out.println(e.toString()); <BR>return false; <BR>} <BR>} <BR><BR>//////////////////////////////////////////////// <BR>//文件列表 <BR>public String[] listFiles(String fp) <BR>{ <BR>String[] lf=null; <BR>try{ <BR>savePath=path+fp; <BR>File file=new File(savePath); <BR>lf=file.list(new DirFilter()); <BR>for(int i=0;i&lt;lf.length;i++) <BR>System.out.println(lf[i]); <BR>}catch(Exception e){ e.printStackTrace();} <BR>return lf; <BR>} <BR>///////////////////////////////////////////////// <BR>//开始上传文件 <BR>public boolean doUpload(HttpServletRequest req) <BR>throws java.io.IOException { <BR><BR>String fieldValue=""; //表单元素值 <BR>String fieldName=""; //表单元名称 <BR>int pos=-1; //临时变量,用于记录位置 <BR>int pos2=-1; //临时变量,用于记录位置 <BR>String lineStr=null; //用oneLine[]生成的每行字符串 <BR>byte oneLine[] =new byte[4096]; //用于每次读取的数据 <BR>FileOutputStream fos=null; //文件输出流 <BR>init(req); //初始化 <BR>ServletInputStream sis=req.getInputStream(); <BR>int i=sis.readLine(oneLine,0,oneLine.length); //返回实际读取的字符数,并把数据写到oneLine中 <BR>while (i!=-1) { <BR>lineStr=newLine(oneLine,0,i,charEncode); //生成字符串 <BR>if (lineStr.indexOf(getBoundary()+"--")&gt;=0) <BR>break; <BR><BR>if (lineStr.startsWith("Content-Disposition: form-data; name=\"")) { <BR>//分离数据,因为表单元素也一并上传,还有其它数据,对我们有用的只是 <BR>//文件的内容,表单元素及表单元素对应的值 <BR>if (lineStr.indexOf("\"; filename=\"")&gt;=0) { //是文件输入域 <BR>//设置文件名 <BR>setFileName(lineStr); <BR>if (!fileName.equals("")) { //如果文件名为空则跳过 <BR><BR>//提取表单元素名称及表单元素对应的值 <BR>pos=lineStr.indexOf("name=\""); <BR>pos2=lineStr.indexOf("\"; filename=\""); <BR>//表单元素名字 <BR>fieldName=lineStr.substring(pos+6,pos2); <BR>//表单元素值 <BR>fieldValue=lineStr.substring(pos2+13,lineStr.length()-3); <BR>//加入哈希表中 <BR>dic.put(fieldName,fieldValue); <BR>sis.readLine(oneLine,0,oneLine.length); //读取的数据类似"Content-Type: text/plain" <BR>sis.readLine(oneLine,0,oneLine.length); //空行 <BR>//建立文件输出 <BR>fos=new FileOutputStream(new File(getSavePath(),getNewFileName())); <BR>//开始读上传文件数据 <BR>i=sis.readLine(oneLine,0,oneLine.length); <BR>while(i!=-1) { <BR>totalSize=i+totalSize; <BR>lineStr=newLine(oneLine,0,i,charEncode); <BR>if (lineStr.indexOf(getBoundary())&gt;=0) <BR>break; //表明这个文件区的数据读取完毕 <BR>fos.write(oneLine,0,i); <BR>i=sis.readLine(oneLine,0,oneLine.length); <BR>}//end while <BR>fos.close(); <BR>}//end if (!getFileName().equals("")) <BR>} <BR>else { //非文件输入域 <BR>pos=lineStr.indexOf("name=\""); <BR>//表单元素名字 <BR>fieldName=lineStr.substring(pos+6,lineStr.length()-3); <BR>//读空行 <BR>sis.readLine(oneLine,0,oneLine.length); <BR>//这行含有元素值,如里元素值为空,则这行也是空行,也要读的 <BR>String temp=""; <BR>i=sis.readLine(oneLine,0,oneLine.length); <BR>while(i!=-1) <BR>{ <BR>temp=newLine(oneLine,0,i,charEncode); <BR>if (temp.indexOf(getBoundary())&gt;=0) <BR>break; <BR>fieldValue=fieldValue+temp; <BR>i=sis.readLine(oneLine,0,oneLine.length); <BR>} <BR>//加入哈希表中 <BR>dic.put(fieldName,fieldValue); <BR>fieldValue=""; <BR>} <BR>} <BR>i=sis.readLine(oneLine,0,oneLine.length); <BR>}//end while <BR><BR>sis.close(); <BR><BR>return true; <BR>} //end doUpload <BR><BR><BR>////////////////////////// <BR>//清空Hashtable <BR>public void clearDic() { <BR>dic.clear(); <BR>if (dic.isEmpty()) { <BR>System.out.println("empty"); <BR>} <BR>else { <BR>System.out.println("not empty"); <BR>} <BR><BR>} <BR>////////////////////////////////// <BR>//测试用的主函数 <BR>public static void main(String args[]) <BR>{ <BR>String[] fileList=null; <BR>try{ <BR>FileUploadBean fub=new FileUploadBean(); <BR>fileList=fub.listFiles("/avatars/"); <BR>for(int i=0;i&lt;fileList.length;i++) <BR>System.out.println(fileList[i]); <BR><BR>}catch(Exception e){ e.printStackTrace();} <BR>} <BR><BR>} <BR><BR><BR>/////////////////////////////////// <BR>////文件目录过滤内部类 <BR>class DirFilter implements FilenameFilter { <BR><BR>public boolean accept(File dir, String name) { //dir为目录名，name 为包含路径的文件名 <BR><BR>File f = new File(dir,name); //生成文件对象 <BR>if(f.isDirectory()) <BR>return false; <BR>return true; <BR>} <BR>}<BR><!-- / message --><!-- sig --></P><img src ="http://www.blogjava.net/yuyi/aggbug/947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-02-03 11:20 <a href="http://www.blogjava.net/yuyi/articles/947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在jsp中使用smartupload组件上传文件</title><link>http://www.blogjava.net/yuyi/articles/946.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Thu, 03 Feb 2005 03:17:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/946.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/946.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/946.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/946.html</trackback:ping><description><![CDATA[<P>jsp对上传文件的支持不象php中支持的那么好，直接做成了函数，也不象asp中要通过组件才能实现。jsp中可以通过javabean来实现。但是我们没有必要自己去写一个上载的bean，在网上已经有了很多成型的技术，smartupload就是其中的一个。但是smartupload是将文件先读到服务器的内存中，所以上传太大的文件（超过100兆）有可能会出问题，也算是一个美中不足吧：）<BR><BR>先说一下提交的页面，smartupload组件要求用字节流的方式来提交&lt;FORM action="upload.jsp" encType=multipart/form-data method=post&gt;。下面就是个例子upload.htm：<BR><BR>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"&gt;<BR>&lt;!-- saved from url=(0057)<A href="http://localhost:8080/jspsmartfile/jsp/uploadTemplate.jsp" target=_blank><FONT color=#000000>http://localhost:8080/jspsmartfile/jsp/uploadTemplate.jsp</FONT></A> --&gt;<BR>&lt;HTML&gt;&lt;HEAD&gt;<BR>&lt;META content="text/html; charset=gb2312" http-equiv=Content-Type&gt;<BR>&lt;META content="MSHTML 5.00.2920.0" name=GENERATOR&gt;&lt;/HEAD&gt;<BR>&lt;BODY bgColor=#e6e6e6&gt;&lt;BR&gt;<BR>&lt;FORM action="upload.jsp" encType=multipart/form-data method=post&gt;<BR>&lt;TABLE&gt;<BR>&lt;TBODY&gt;<BR>&lt;TR&gt;<BR>&lt;TD&gt;&lt;FONT color=#000000 face=helv,helvetica size=1&gt;&amp;nbsp;&amp;nbsp;File <BR>:&amp;nbsp;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&lt;INPUT size=60 type=file name="file"&gt;&lt;/TD&gt;&lt;/TR&gt;<BR>&lt;TR&gt;<BR>&lt;TR&gt;<BR>&lt;TD&gt;&lt;FONT color=#000000 face=helv,helvetica size=1&gt;&amp;nbsp;&amp;nbsp;File <BR>:&amp;nbsp;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&lt;INPUT size=60 type=file name="file1"&gt;&lt;/TD&gt;&lt;/TR&gt;<BR>&lt;TR&gt; <BR>&lt;TD&gt;&lt;FONT color=#000000 face=helv,helvetica size=1&gt;&amp;nbsp;&amp;nbsp;File <BR>:&amp;nbsp;&lt;/FONT&gt;&amp;nbsp;&amp;nbsp;&lt;INPUT size=60 type=text name="text"&gt;&lt;/TD&gt;&lt;/TR&gt;<BR>&lt;TR&gt;<BR>&lt;TD <BR>align=right&gt;&lt;INPUT type=submit value=Send name="send"&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/FORM&gt;&lt;/BODY&gt;&lt;/HTML&gt;<BR><BR>再来看一下接收的页面 ，我们把文件上传到服务器以后就直接把它再存入数据库中：upload.jsp<BR><BR>&lt;%@ page contentType="text/html;charset=gb2312"%&gt;<BR>&lt;%@ page import="java.sql.*"%&gt;<BR>&lt;%@ page import="com.jspsmart.upload.*" %&gt;<BR>&lt;%@ page import="DBstep.iDBManager2000.*"%&gt;<BR>&lt;%<BR>//实例化上载bean<BR>com.jspsmart.upload.SmartUpload mySmartUpload=new com.jspsmart.upload.SmartUpload();<BR>//初始化<BR>mySmartUpload.initialize(pageContext); <BR>//设置上载的最大值<BR>mySmartUpload.setMaxFileSize(500 * 1024*1024);<BR>//上载文件<BR>mySmartUpload.upload();<BR>//循环取得所有上载的文件<BR>for (int i=0;i&lt;mySmartUpload.getFiles().getCount();i++){<BR>//取得上载的文件<BR>com.jspsmart.upload.File myFile = mySmartUpload.getFiles().getFile(i);<BR>if (!myFile.isMissing())<BR>{<BR>//取得上载的文件的文件名<BR>String myFileName=myFile.getFileName();<BR>//取得不带后缀的文件名<BR>String suffix=myFileName.substring(0,myFileName.lastIndexOf('.'));<BR>//取得后缀名<BR>String ext= mySmartUpload.getFiles().getFile(0).getFileExt(); <BR>//取得文件的大小 <BR>int fileSize=myFile.getSize();<BR>//保存路径<BR>String aa=getServletContext().getRealPath("/")+"jsp\\";<BR>String trace=aa+myFileName;<BR>//取得别的参数<BR>String explain=(String)mySmartUpload.getRequest().getParameter("text");<BR>String send=(String)mySmartUpload.getRequest().getParameter("send");<BR>//将文件保存在服务器端 <BR>myFile.saveAs(trace,mySmartUpload.SAVE_PHYSICAL);<BR>//下面的是将上载的文件保存到数据库中<BR>//将文件读到流中 <BR>java.io.File file = new java.io.File(trace);<BR>java.io.FileInputStream fis = new java.io.FileInputStream(file);<BR>out.println(file.length());<BR>//打开数据库<BR>ResultSet result=null;<BR>String mSql=null;<BR>PreparedStatement prestmt=null; <BR>DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000();<BR>DbaObj.OpenConnection();<BR>//将文件写到数据库中<BR>mSql="insert into marklist (markname,password,marksize,markdate,MarkBody) values (?,?,?,?,?)";<BR>prestmt =DbaObj.Conn.prepareStatement(mSql);<BR>prestmt.setString(1, "aaa1");<BR>prestmt.setString(2, "0000");<BR>prestmt.setInt(3, fileSize);<BR>prestmt.setString(4, DbaObj.GetDateTime());<BR>prestmt.setBinaryStream(5,fis,(int)file.length());<BR>DbaObj.Conn.setAutoCommit(true) ;<BR>prestmt.executeUpdate();<BR>DbaObj.Conn.commit();<BR>out.println(("上载成功！！！").toString());<BR>}<BR>else <BR>{ out.println(("上载失败！！！").toString()); } <BR>}//与前面的if对应<BR>%&gt;<BR><BR>再说一下下载，下载分两种情况1。从数据库直接下载2。从服务器上下载<BR><BR>先说从数据库直接下载的情形：就是把输入流从数据库里读出来，然后转存为文件<BR><BR>&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&lt;%@ page import="java.sql.*"%&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%@ page import="DBstep.iDBManager2000.*"%&gt;<BR>&lt;%<BR>int bytesum=0;<BR>int byteread=0;<BR>//打开数据库<BR>ResultSet result=null;<BR>String Sql=null;<BR>PreparedStatement prestmt=null; <BR>DBstep.iDBManager2000 DbaObj=new DBstep.iDBManager2000();<BR>DbaObj.OpenConnection();<BR>//取得数据库中的数据<BR>Sql="select * from t_local_zhongzhuan ";<BR>result=DbaObj.ExecuteQuery(Sql);<BR>result.next();<BR><BR>//将数据库中的数据读到流中 <BR>InputStream inStream=result.getBinaryStream("content"); <BR>FileOutputStream fs=new FileOutputStream( "c:/dffdsafd.doc");<BR><BR>byte[] buffer =new byte[1444];<BR>int length;<BR>while ((byteread=inStream.read(buffer))!=-1)<BR>{<BR>out.println("&lt;DT&gt;&lt;B&gt;"+byteread+"&lt;/B&gt;&lt;/DT&gt;");<BR>bytesum+=byteread;<BR>System.out.println(bytesum);<BR><BR><BR>fs.write(buffer,0,byteread);<BR>}<BR>%&gt;<BR><BR>再说从服务器上下载的情形：<BR><BR>&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<BR>&lt;%@ page import="java.io.*" %&gt;<BR>&lt;%<BR>String fileName = "zsc104.swf".toString();<BR>f//读到流中<BR>InputStream inStream=new FileInputStream("c:/zsc104.swf");<BR>//设置输出的格式 <BR>response.reset(); <BR>response.setContentType("bin");<BR>response.addHeader("Content-Disposition","attachment; filename=\"" + fileName + "\"");<BR>//循环取出流中的数据 <BR>byte[] b = new byte[100]; <BR>int len; <BR>while((len=inStream.read(b)) &gt;0) <BR>response.getOutputStream().write(b,0,len); <BR>inStream.close(); <BR>%&gt;<BR></P>
<P>缩略图实现，将图片(jpg,gif,bmp等等)真实的变成想要的大小<BR>import java.io.*;<BR>import java.util.*;<BR>import com.sun.image.codec.jpeg.*;<BR>import java.awt.image.*;<BR>import java.awt.*;<BR>import java.net.*;<BR>import java.applet.*;<BR>import java.sql.*;<BR>//缩略图类，<BR>//本java类能将jpg图片文件，进行等比或非等比的大小转换。<BR>//具体使用方法<BR>//s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))<BR>public class Small_pic{<BR>String InputDir; //输入图路径<BR>String OutputDir; //输出图路径<BR>String InputFileName; //输入图文件名<BR>String OutputFileName; //输出图文件名<BR>int OutputWidth=80; //默认输出图片宽<BR>int OutputHeight=80; //默认输出图片高<BR>int rate=0;<BR>boolean proportion=true; //是否等比缩放标记(默认为等比缩放)<BR><BR>public Small_pic(){<BR>//初始化变量<BR>InputDir="";<BR>OutputDir="";<BR>InputFileName="";<BR>OutputFileName="";<BR>OutputWidth=80;<BR>OutputHeight=80;<BR>rate=0;<BR>}<BR><BR>public void setInputDir(String InputDir){<BR>this.InputDir=InputDir;<BR>}<BR><BR>public void setOutputDir(String OutputDir){<BR>this.OutputDir=OutputDir;<BR>}<BR><BR>public void setInputFileName(String InputFileName){<BR>this.InputFileName=InputFileName;<BR>}<BR><BR>public void setOutputFileName(String OutputFileName){<BR>this.OutputFileName=OutputFileName;<BR>}<BR><BR>public void setOutputWidth(int OutputWidth){<BR>this.OutputWidth=OutputWidth;<BR>}<BR><BR>public void setOutputHeight(int OutputHeight){<BR>this.OutputHeight=OutputHeight;<BR>}<BR><BR>public void setW_H(int width,int height){<BR>this.OutputWidth=width;<BR>this.OutputHeight=height;<BR>}<BR><BR>public String s_pic(){<BR>BufferedImage image;<BR>String NewFileName;<BR>//建立输出文件对象<BR>File file = new File(OutputDir+OutputFileName);<BR>FileOutputStream tempout =null;<BR>try{<BR>tempout= new FileOutputStream(file);<BR>}catch(Exception ex){<BR>System.out.println(ex.toString());<BR>}<BR>Image img=null;<BR>Toolkit tk=Toolkit.getDefaultToolkit();<BR>Applet app=new Applet();<BR>MediaTracker mt = new MediaTracker(app);<BR>try {<BR>img=tk.getImage(InputDir+InputFileName);<BR>mt.addImage(img, 0);<BR>mt.waitForID(0);<BR>}catch(Exception e) {<BR>e.printStackTrace();<BR>}<BR><BR>if(img.getWidth(null)==-1){<BR>System.out.println(" can't read,retry!"+"&lt;BR&gt;");<BR>return "no";<BR>}else{<BR>int new_w;<BR>int new_h;<BR>if (this.proportion==true) //判断是否是等比缩放.<BR>{<BR>//为等比缩放计算输出的图片宽度及高度<BR>double rate1=((double)img.getWidth(null))/(double)OutputWidth+0.1;<BR>double rate2=((double)img.getHeight(null))/(double)OutputHeight+0.1;<BR>double rate=rate1&gt;rate2?rate1:rate2;<BR>new_w=(int)(((double)img.getWidth(null))/rate);<BR>new_h=(int)(((double)img.getHeight(null))/rate);<BR>}<BR>else{<BR>new_w=OutputWidth; //输出的图片宽度<BR>new_h=OutputHeight; //输出的图片高度<BR>}<BR>BufferedImage buffImg = new BufferedImage(new_w,new_h,BufferedImage.TYPE_INT_RGB);<BR><BR>Graphics g = buffImg.createGraphics();<BR><BR>g.setColor(Color.white);<BR>g.fillRect(0,0,new_w,new_h);<BR><BR>g.drawImage(img,0,0,new_w,new_h,null);<BR>g.dispose();<BR><BR>JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(tempout);<BR>try{<BR>encoder.encode(buffImg);<BR>tempout.close();<BR>}catch(IOException ex){<BR>System.out.println(ex.toString());<BR>}<BR>}<BR>return "ok";<BR>}<BR><BR>public String s_pic(String InputDir,String OutputDir,String InputFileName,String OutputFileName){<BR>//输入图路径<BR>this.InputDir=InputDir;<BR>//输出图路径<BR>this.OutputDir=OutputDir;<BR>//输入图文件名<BR>this.InputFileName=InputFileName;<BR>//输出图文件名<BR>this.OutputFileName=OutputFileName;<BR>return s_pic();<BR>}<BR><BR>public String s_pic(String InputDir,String OutputDir,String InputFileName,String OutputFileName,int width,int height,boolean gp){<BR>//输入图路径<BR>this.InputDir=InputDir;<BR>//输出图路径<BR>this.OutputDir=OutputDir;<BR>//输入图文件名<BR>this.InputFileName=InputFileName;<BR>//输出图文件名<BR>this.OutputFileName=OutputFileName;<BR>//设置图片长宽<BR>setW_H(width,height);<BR>//是否是等比缩放 标记<BR>this.proportion=gp;<BR>return s_pic();<BR>}<BR>public static void main(String [] a)<BR>{<BR>//s_pic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度)<BR>Small_pic mypic =new Small_pic();<BR>System.out.println(<BR>mypic.s_pic("E:\\JAVA\\J2EEDatum\\王亮jsp资料\\缩图例子\\personal\\",<BR>"E:\\JAVA\\J2EEDatum\\酒剑仙jsp资料\\缩图例子\\personal\\",<BR>"1.jpg","new1.jpg",80,80,true)<BR>);<BR>}<BR></P><img src ="http://www.blogjava.net/yuyi/aggbug/946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-02-03 11:17 <a href="http://www.blogjava.net/yuyi/articles/946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp初学大全</title><link>http://www.blogjava.net/yuyi/articles/945.html</link><dc:creator>yuyi</dc:creator><author>yuyi</author><pubDate>Thu, 03 Feb 2005 03:15:00 GMT</pubDate><guid>http://www.blogjava.net/yuyi/articles/945.html</guid><wfw:comment>http://www.blogjava.net/yuyi/comments/945.html</wfw:comment><comments>http://www.blogjava.net/yuyi/articles/945.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/yuyi/comments/commentRss/945.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/yuyi/services/trackbacks/945.html</trackback:ping><description><![CDATA[测试环境为 jdk1.2.2　jswdk-1.0　winnt4.0中文版。 <BR><BR>1。java是大小写敏感的，用过其他编程语言的人最容易犯这个错误，尤其是刚上手的时候。我刚开始调试jsp的时50%以上的编译错误是都是因为这个。 <BR><BR>2。java的调用过程都是要加括号的，一开始比较容易忽视，如title=request.getParameter(\"title\").trim(); <BR><BR>3。jsp中对应asp中的request.form()和request.querystring()的解决方法。 <BR>jsp中取得参数没有form和queryString之分，都是通过request.getParameter(\"XXXX\")来取得。虽然jsp也有request.getQueryString()方法，但测试结果是 test.jsp?id=1&amp;page=20　得到 id=1&amp;page=20。 <BR>　 如果url和form有相同的参数名称呢？下面是一段测试代码： <BR>&lt;form method=\"POST\" action=\"query.jsp?id=2\"&gt; <BR>　&lt;input type=\"text\" name=\"id\" value=\"1\" size=\"60\"&gt; <BR>&lt;/form&gt; <BR>name都是id，结果是url的参数优先得到，jsp的这种处理方式和asp相比我觉的各有所长。 <BR><BR>4。头疼的汉字处理问题。 <BR>在其他的文章里曾说到在中文NT环境下如下语句输出会得到乱码， <BR>&lt;%=\"你好\"%&gt; 及 out.print(\"你好\");等。解决方法是只要对字符串变量进行编码就可以得到正确结果,如下代码可以得到正确的输出： <BR>&lt;%　String title=\"你好\"; <BR>　byte[] tmpbyte=title.getBytes(\"ISO8859_1\"); <BR>　title=new String(tmpbyte); <BR>　out.print(title); %&gt; <BR>或者&lt;%=title%&gt; <BR><BR>关于sql语句汉字问题，例句为 select * from test where title=\'谁是傻瓜\' <BR>在jdbc-odbc驱动下连db2，不管是原句还是对sql语句进行编码后都死活通不过。 <BR>换了ibm的jdbc直接驱动后，对sql语句编码后程序可以通过。 <BR><BR>这个问题的产生大概是中文NT的原因，在其他环境下可能就没汉字处理问题了，据说ibm的web sphere对中文支持的很好，这也给jsp的开发带来一定的通用性问题。据说对字符串编码是一种通用的解决方法，不过没有这么多环境来测试。 <BR><BR>5。在asp中经常使用到字符串判断语句如 if state=\"真是傻瓜\" then..... <BR>　 在java中String变量不是一个简单的变量而是一个类实例，不同的方法会得到不同的结果 <BR>a. <BR>String　str1=\"我是傻瓜\"; <BR>String　str2=\"我是傻瓜\"; (or String　str2=\"我是\"+\"傻瓜\"; ) <BR>if (str1==str2) <BR>　out.print(\"yes\"); <BR>else　 <BR>　out.print(\"no\"); <BR>结果是\"yes\"。 <BR>大概是编译优化，str1,str2指向同一个类实例； <BR><BR>b. <BR>String str1,str2,str3; <BR>str1=\"我是傻瓜\"; <BR>str2=\"我是\"; <BR>str3=str2+\"傻瓜\"; <BR>if (str1==str3) <BR>　out.print(\"yes\"); <BR>else <BR>　out.print(\"no\"); <BR>结果是\"no\"。 <BR><BR>String str1=new String(\"我是傻瓜\"); <BR>String str2=new String(\"我是傻瓜\"); <BR>if (str1==str2) <BR>　out.print(\"yes\"); <BR>else <BR>　out.print(\"no\"); <BR>结果是\"no\"。 <BR><BR>String str1=new String(\"我是傻瓜\"); <BR>String str2=new String(\"我是傻瓜\"); <BR>if (str1.compareTo(str2)==0) <BR>　out.print(\"yes\"); <BR>else <BR>　out.print(\"no\"); <BR>结果是\"yes\"。 <BR><BR>所以在jsp中判断字符串要使用compareTo方法，用惯传统语言还真一下子适应不过来，熟悉java的朋友应该没这个问题。 <BR><BR>6。如何判断数据库为空？ <BR>　 result = stmt.executeQuery(sql); <BR>　 if (result.next()) <BR>　　　...... <BR>　 result执行后游标出于一个未明的状态，不能进行状态判断，也不能取值，一定要next()一下才可以用。 <BR>　 <BR><BR>7。在jsp中实现分页。 <BR>page是关键字，不能当变量。 <BR>conn.jsp <BR>&lt;% <BR>　　String sDBDriver = \"COM.ibm.db2.jdbc.app.DB2Driver\"; <BR>　　String sConnStr = \"jdbc:db2:faq\"; <BR>　　Connection conn = null; <BR>　　Statement stmt = null; <BR>　　ResultSet rs=null; <BR>　　　 try { <BR>　　　　　　　 Class.forName(sDBDriver);　　 <BR>　　} <BR>　　　 catch(java.lang.ClassNotFoundException e)　　 { <BR>　　　　out.print(\"faq(): \" + e.getMessage()); <BR>　　} <BR>　　 <BR>　　try{ <BR>　　　 conn = DriverManager.getConnection(sConnStr,\"wsdemo\",\"wsdemo1\");　　　　 <BR>　　　 stmt = conn.createStatement(); <BR>　　}catch(SQLException e){ <BR>　　　　out.print(e.toString()); <BR>　　} <BR>%&gt; <BR><BR>query.jsp <BR><BR>&lt;%@ page language=\"java\" import=\"java.sql.*\"　%&gt; <BR>&lt;%@ page contentType=\"text/html; charset=gb2312\" %&gt; <BR>&lt;%@ include file=\"conn.jsp\" %&gt; <BR>&lt;% <BR>....... <BR>int pages=0; <BR>int pagesize=10; <BR>ResultSet result = null; <BR>ResultSet rcount = null; <BR><BR>pages = new Integer(request.getParameter(\"pages\")).intValue(); <BR><BR>if (pages&gt;0) <BR>{ <BR><BR>String sql=\" state=\'我不傻\'\"; <BR>int count=0; <BR>try { <BR>rcount = stmt.executeQuery(\"SELECT count(id) as id from user where \"+sql); <BR>catch(SQLException ex) { <BR>　out.print(\"aq.executeQuery: \" + ex.getMessage()); <BR>　} <BR>if(rcount.next()) <BR>　count = rcount.getInt(\"id\"); <BR>rcount.close(); <BR><BR>if (count&gt;0) <BR>{ <BR>sql=\"select * from user where　\"+sql; <BR>try { <BR>result = stmt.executeQuery(sql); <BR>　　} <BR>catch(SQLException ex) { <BR>　out.print(\"aq.executeQuery: \" + ex.getMessage()); <BR>　} <BR><BR>int i; <BR>String name; <BR>//　result.first(); <BR>//　result.absolute((pages-1)*pagesize); <BR>//　此方法jdbc2.0支持。编译通过，但执行不过，不知是不是跟驱动有关，只好用下面的笨办法。 <BR>for(i=1;i&lt;=(pages-1)*pagesize;i++) <BR>　result.next(); <BR>for(i=1;i&lt;=pagesize;i++) { <BR>　if (result.next()) { <BR>　name=result.getString(\"name\"); <BR>　out.print(name); <BR>　} <BR>result.close(); <BR>int n= (int)(count/pagesize); <BR>if (n*pagesize&lt;count) n++; <BR>if (n&gt;1) <BR>{ <BR>for(i=1;i&lt;=n;i++) <BR>　 out.print(\"&lt;a href=query.jsp?pages=\"+i+\"&gt;\"+i+\" &lt;/a&gt;\"); <BR>} <BR>} <BR>} <BR>%&gt; <BR><BR><BR><BR><BR><B>现在有好多初学jsp的网友经常会问数据库怎么连接啊</B>，怎么老出错啊？所以我集中的在这写篇文章供大家参考，其实这种把数据库逻辑全部放在jsp里未必是好的做法，但是有利于初学者学习，所以我就这样做了，当大家学到一定程度的时候，可以考虑用MVC的模式开发。在练习这些代码的时候，你一定将jdbc的驱动程序放到服务器的类路径里，然后要在数据库里建一个表test,有两个字段比如为test1，test2，可以用下面SQL建 <BR>create table test(test1 varchar(20),test2 varchar(20) <BR>然后向这个表写入一条测试纪录 <BR>那么现在开始我们的jsp和数据库之旅吧。 <BR>一、jsp连接Oracle8/8i/9i数据库（用thin模式） <BR>testoracle.jsp如下： <BR>&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <BR>&lt;%@ page import="java.sql.*"%&gt; <BR>&lt;html&gt; <BR>&lt;body&gt; <BR>&lt;%Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); <BR>String url="jdbc:oracle:thin:@localhost:1521:orcl"; <BR>//orcl为你的数据库的SID <BR>String user="scott"; <BR>String password="tiger"; <BR>Connection conn= DriverManager.getConnection(url,user,password); <BR>Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <BR>String sql="select * from test"; <BR>ResultSet rs=stmt.executeQuery(sql); <BR>while(rs.next()) {%&gt; <BR>您的第一个字段内容为：&lt;%=rs.getString(1)%&gt; <BR>您的第二个字段内容为：&lt;%=rs.getString(2)%&gt; <BR>&lt;%}%&gt; <BR>&lt;%out.print("数据库操作成功，恭喜你");%&gt; <BR>&lt;%rs.close(); <BR>stmt.close(); <BR>conn.close(); <BR>%&gt; <BR>&lt;/body&gt; <BR>&lt;/html&gt; <BR><B>二、jsp连接Sql Server7.0/2000数据库</B> <BR>testsqlserver.jsp如下： <BR>&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <BR>&lt;%@ page import="java.sql.*"%&gt; <BR>&lt;html&gt; <BR>&lt;body&gt; <BR>&lt;%Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); <BR>String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=pubs"; <BR>//pubs为你的数据库的 <BR>String user="sa"; <BR>String password=""; <BR>Connection conn= DriverManager.getConnection(url,user,password); <BR>Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <BR>String sql="select * from test"; <BR>ResultSet rs=stmt.executeQuery(sql); <BR>while(rs.next()) {%&gt; <BR>您的第一个字段内容为：&lt;%=rs.getString(1)%&gt; <BR>您的第二个字段内容为：&lt;%=rs.getString(2)%&gt; <BR>&lt;%}%&gt; <BR>&lt;%out.print("数据库操作成功，恭喜你");%&gt; <BR>&lt;%rs.close(); <BR>stmt.close(); <BR>conn.close(); <BR>%&gt; <BR>&lt;/body&gt; <BR>&lt;/html&gt; <BR><B>三、jsp连接DB2数据库</B> <BR>testdb2.jsp如下： <BR>&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <BR>&lt;%@ page import="java.sql.*"%&gt; <BR>&lt;html&gt; <BR>&lt;body&gt; <BR>&lt;%Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); <BR>String url="jdbc:db2://localhost:5000/sample"; <BR>//sample为你的数据库名 <BR>String user="admin"; <BR>String password=""; <BR>Connection conn= DriverManager.getConnection(url,user,password); <BR>Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <BR>String sql="select * from test"; <BR>ResultSet rs=stmt.executeQuery(sql); <BR>while(rs.next()) {%&gt; <BR>您的第一个字段内容为：&lt;%=rs.getString(1)%&gt; <BR>您的第二个字段内容为：&lt;%=rs.getString(2)%&gt; <BR>&lt;%}%&gt; <BR>&lt;%out.print("数据库操作成功，恭喜你");%&gt; <BR>&lt;%rs.close(); <BR>stmt.close(); <BR>conn.close(); <BR>%&gt; <BR>&lt;/body&gt; <BR>&lt;/html&gt; <BR><B>四、jsp连接Informix数据库</B> <BR>testinformix.jsp如下： <BR>&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <BR>&lt;%@ page import="java.sql.*"%&gt; <BR>&lt;html&gt; <BR>&lt;body&gt; <BR>&lt;%Class.forName("com.informix.jdbc.IfxDriver").newInstance(); <BR>String url = <BR>"jdbc:informix-sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver; <BR>user=testuser;password=testpassword"; <BR>//testDB为你的数据库名 <BR>Connection conn= DriverManager.getConnection(url); <BR>Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <BR>String sql="select * from test"; <BR>ResultSet rs=stmt.executeQuery(sql); <BR>while(rs.next()) {%&gt; <BR>您的第一个字段内容为：&lt;%=rs.getString(1)%&gt; <BR>您的第二个字段内容为：&lt;%=rs.getString(2)%&gt; <BR>&lt;%}%&gt; <BR>&lt;%out.print("数据库操作成功，恭喜你");%&gt; <BR>&lt;%rs.close(); <BR>stmt.close(); <BR>conn.close(); <BR>%&gt; <BR>&lt;/body&gt; <BR>&lt;/html&gt; <BR><B>五、jsp连接Sybase数据库</B> <BR>testmysql.jsp如下： <BR>&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <BR>&lt;%@ page import="java.sql.*"%&gt; <BR>&lt;html&gt; <BR>&lt;body&gt; <BR>&lt;%Class.forName("com.sybase.jdbc.SybDriver").newInstance(); <BR>String url =" jdbc:sybase:Tds:localhost:5007/tsdata"; <BR>//tsdata为你的数据库名 <BR>Properties sysProps = System.getProperties(); <BR>SysProps.put("user","userid"); <BR>SysProps.put("password","user_password"); <BR>Connection conn= DriverManager.getConnection(url, SysProps); <BR>Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <BR>String sql="select * from test"; <BR>ResultSet rs=stmt.executeQuery(sql); <BR>while(rs.next()) {%&gt; <BR>您的第一个字段内容为：&lt;%=rs.getString(1)%&gt; <BR>您的第二个字段内容为：&lt;%=rs.getString(2)%&gt; <BR>&lt;%}%&gt; <BR>&lt;%out.print("数据库操作成功，恭喜你");%&gt; <BR>&lt;%rs.close(); <BR>stmt.close(); <BR>conn.close(); <BR>%&gt; <BR>&lt;/body&gt; <BR>&lt;/html&gt; <BR><B>六、jsp连接MySQL数据库</B> <BR>testmysql.jsp如下： <BR>&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <BR>&lt;%@ page import="java.sql.*"%&gt; <BR>&lt;html&gt; <BR>&lt;body&gt; <BR>&lt;%Class.forName("org.gjt.mm.mysql.Driver").newInstance(); <BR>String url ="jdbc:mysql://localhost/softforum?user=soft&amp;password=soft1234&amp;useUnicode=true&amp;characterEncoding=8859_1" <BR>//testDB为你的数据库名 <BR>Connection conn= DriverManager.getConnection(url); <BR>Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <BR>String sql="select * from test"; <BR>ResultSet rs=stmt.executeQuery(sql); <BR>while(rs.next()) {%&gt; <BR>您的第一个字段内容为：&lt;%=rs.getString(1)%&gt; <BR>您的第二个字段内容为：&lt;%=rs.getString(2)%&gt; <BR>&lt;%}%&gt; <BR>&lt;%out.print("数据库操作成功，恭喜你");%&gt; <BR>&lt;%rs.close(); <BR>stmt.close(); <BR>conn.close(); <BR>%&gt; <BR>&lt;/body&gt; <BR>&lt;/html&gt; <BR><B>七、jsp连接PostgreSQL数据库</B> <BR>testmysql.jsp如下： <BR>&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <BR>&lt;%@ page import="java.sql.*"%&gt; <BR>&lt;html&gt; <BR>&lt;body&gt; <BR>&lt;%Class.forName("org.postgresql.Driver").newInstance(); <BR>String url ="jdbc:postgresql://localhost/soft" <BR>//soft为你的数据库名 <BR>String user="myuser"; <BR>String password="mypassword"; <BR>Connection conn= DriverManager.getConnection(url,user,password); <BR>Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <BR>String sql="select * from test"; <BR>ResultSet rs=stmt.executeQuery(sql); <BR>while(rs.next()) {%&gt; <BR>您的第一个字段内容为：&lt;%=rs.getString(1)%&gt; <BR>您的第二个字段内容为：&lt;%=rs.getString(2)%&gt; <BR>&lt;%}%&gt; <BR>&lt;%out.print("数据库操作成功，恭喜你");%&gt; <BR>&lt;%rs.close(); <BR>stmt.close(); <BR>conn.close(); <BR>%&gt; <BR>&lt;/body&gt; <BR>&lt;/html&gt;<!-- / message --><!-- sig --><img src ="http://www.blogjava.net/yuyi/aggbug/945.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/yuyi/" target="_blank">yuyi</a> 2005-02-03 11:15 <a href="http://www.blogjava.net/yuyi/articles/945.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>