<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>zxjava</title>
    <description></description>
    <link>http://zxjava.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>Spring iBatis Clob</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/216714" style="color:red;">http://zxjava.javaeye.com/blog/216714</a>&nbsp;
          发表时间: 2008年07月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          iBATIS作为一个易于易用的orm(sql mapping)工具，已经广泛应用在国内的大量的项目中，成熟的iBATIS2已经为社区服务了三年之久，在iBATIS2.3.0中已经废弃了其自带的DAO的框架，转而推荐Spring 提供的ibatis support dao框架，从而得到所有依赖注入，bean管理和template以及声明式事务带来的好处。<br /><br />本文就在使用过程中Spring DAO + iBATIS + Oracle Clob(Blob)存取时的一些问题的经验总结。<br /><br />一、开发、测试环境描述<br />SUN JDK1.4.2<br />eclipse3.2.1<br />tomcat 5.0.28<br />spring-2.0.5.jar<br />ibatis-2.3.0.677.jar<br />ojdbc14-10.2.0.3.jar(thin)<br />commons-dbcp链接池<br /><br />二、布署环境描述<br />IBM WebSphere 6.0.2.17<br /><br />三、数据库描述<br />Oracle 10.2.0.2.0<br />采用thin模式连接<br /><br />四、使用iBATIS自带的clobTypeHanle<br /><br />读取：将clob字段对应的domain属性配置为String，不需做任何配置<br />insert,update，时不时出现问题，后采用变态方法，将clob字段移到insert语句的最后，将clob字段移到update的最前位置，问题解决，采用的内联的parametermap<br /><br />&lt;insert id="insertNews" parameterClass="newsForm">   <br />&lt;selectKey resultClass="long" keyProperty="id">select mmt_seq.nextval as id from dualselectKey>   <br />  <br />    insert into mmt_news_main(   <br />    id,    <br />    title,    <br />    info_source,    <br />    mod_index,    <br />    craft_index,    <br />    p_index,    <br />    p_name,    <br />    lang_type,    <br />    title_short,    <br />    title_deck,    <br />    brief,    <br />    add_date,   <br />    content   <br />    )values(   <br />    #id#,    <br />    #title#,    <br />    #info_source#,    <br />    #mod_index#,    <br />    #craft_index#,    <br />    #p_index#,    <br />    #p_name#,    <br />    #lang_type#,    <br />    #title_short#,    <br />    #title_deck#,    <br />    #brief#,    <br />    sysdate,   <br />    #content,javaType=java.lang.String,jdbcType=CLOB#   <br />    )   <br /> ]]&gt;   <br />&lt;/insert>   <br /><br /><br />&lt;update id="updateNews" parameterClass="newsForm">   <br />      <br />        update mmt_news_main set   <br />        content=#content,javaType=java.lang.String,jdbcType=CLOB#,   <br />        mod_index=#mod_index#,    <br />        craft_index=#craft_index#,    <br />        p_index=#p_index#,    <br />        p_name=#p_name#,    <br />        lang_type=#lang_type#,   <br />        title=#title#,    <br />        info_source=#info_source#,     <br />        title_short=#title_short#,    <br />        title_deck=#title_deck#,    <br />        brief=#brief#              <br />        where id=#id#   <br />    ]]&gt;   <br />&lt;update>   <br /><br /><br />但没有测试过多个clob字段的情况，不存在4000字符的问题。<br />注意，在插入语句中clob字段的java类型为java.io.StringReader<br /><br />五、使用spring自带的OracleLobHandler<br /><br />看了一下spring的源码中的注释<br />位置：org.springframework.jdbc.support.lob.OracleLobHandler<br />/**<br /> * LobHandler implementation for Oracle databases. Uses proprietary API to<br /> * create oracle.sql.BLOB and oracle.sql.CLOB<br /> * instances, as necessary when working with Oracle's JDBC driver.<br /> * Note that this LobHandler requires Oracle JDBC driver 9i or higher!<br /> *<br /> * <br /><br />While most databases are able to work with DefaultLobHandler, Oracle just<br /> * accepts Blob/Clob instances created via its own proprietary BLOB/CLOB API,<br /> * and additionally doesn't accept large streams for PreparedStatement's<br /> * corresponding setter methods. Therefore, you need to use a strategy like<br /> * this LobHandler implementation.<br /> *<br /> * <br /><br />Needs to work on a native JDBC Connection, to be able to cast it to<br /> * oracle.jdbc.OracleConnection. If you pass in Connections from<br /> * a connection pool (the usual case in a J2EE environment), you need to set<br /> * an appropriate NativeJdbcExtractor to allow for automatical retrieval of<br /> * the underlying native JDBC Connection. LobHandler and NativeJdbcExtractor<br /> * are separate concerns, therefore they are represented by separate strategy<br /> * interfaces.<br /> *<br /> * <br /><br />Coded via reflection to avoid dependencies on Oracle classes.<br /> * Even reads in Oracle constants via reflection because of different Oracle<br /> * drivers (classes12, ojdbc14) having different constant values! As this<br /> * LobHandler initializes Oracle classes on instantiation, do not define this<br /> * as eager-initializing singleton if you do not want to depend on the Oracle<br /> * JAR being in the class path: use "lazy-init=true" to avoid this issue.<br /> *<br /> * @author Juergen Hoeller<br /> * @since 04.12.2003<br /> * @see #setNativeJdbcExtractor<br /> * @see oracle.sql.BLOB<br /> * @see oracle.sql.CLOB<br /> */<br /><br />大体的意思是：oracle使用私有的API产生oracle.sql.BLOB和oracle.sql.CLOB实例，oracle只接受其自己API产生的实例，并且在PreparedStatement中不支持大的数据流。<br /><br />此实现类需要一个原生的可以被转换成oracle.jdbc.OracleConnection的链接，所以在使用连接池的时候，就需要一个原生JDBC的转换器。<br /><br />原来如此，马上配置， 快速搞定，在测试，生产环境中都没有问题，sqlMap也不需要注意clob字段的位置，以下是配置：<br /><br />1、sqlMapConfig<br /><br /><br />xml 代码<br />xml version="1.0" encoding="UTF-8"?>   <br /><br />        PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"     <br />        "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">   <br />   <br />&lt;sqlMapConfig>   <br />    &lt;settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true"   <br />        useStatementNamespaces="false" statementCachingEnabled="true" classInfoCacheEnabled="true" />   <br />   <br />    &lt;typeHandler jdbcType="BLOB" javaType="[B"   <br />        callback="org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler" />   <br />    &lt;typeHandler jdbcType="CLOB" javaType="java.lang.String"   <br />        callback="org.springframework.orm.ibatis.support.ClobStringTypeHandler" />   <br />   <br />    &lt;sqlMap resource="com/xx/ssi/dao/ibatis/maps/SysModule.xml" />   <br />   <br />sqlMapConfig>   <br /><br />2、spring配置(部分)<br /><br /><br />xml 代码<br />&lt;jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/dsmmt" />   <br />   <br />   <br />&lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">   <br />    &lt;property name="dataSource" ref="dataSource" />   <br />bean>   <br />   <br />   <br />   <br />   <br />&lt;bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor"   <br />    lazy-init="true" />   <br />   <br />   <br />   <br />   <br />&lt;bean id="oracleLobHandler" class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true">   <br />    &lt;property name="nativeJdbcExtractor">   <br />        &lt;ref local="nativeJdbcExtractor" />   <br />    property>   <br />bean>   <br />   <br />   <br />&lt;bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">   <br />    &lt;property name="configLocation" value="classpath:com/ahtec/ssi/config/ibatis/sql-map-config.xml" />   <br />    &lt;property name="dataSource" ref="dataSource" />   <br />    &lt;property name="lobHandler">   <br />        &lt;ref local="oracleLobHandler" />   <br />    property>   <br />bean>   <br /><br /><br />在发布环境中，要将nativeJdbcExtractor  换成 org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor<br />留意log4j日志，此时的clob字段的java类型为oracle.sql.Clob<br />Spring内置提供的NativeJdbcExtractor转换器有：<br />C3P0NativeJdbcExtractor<br />CommonsDbcpNativeJdbcExtractor<br />JBossNativeJdbcExtractor<br />NativeJdbcExtractor<br />NativeJdbcExtractorAdapter<br />SimpleNativeJdbcExtractor<br />WebLogicNativeJdbcExtractor<br />WebSphereNativeJdbcExtractor<br />XAPoolNativeJdbcExtractor<br />基本上够用了。<br />位于org\springframework\jdbc\support\nativejdbc下<br /><br />六、最后也总结一下：<br />ibatis 2.0.9 + (最新的是iBATIS-2.3.0.667)<br />oracle 10g driver + (最新的是ojdbc14-10.2.0.3.jar)<br />使用spring 提供的dao框架，按如上配置，不同的链接池采用不同的NativeJdbcExtractor<br />不需要写显式的parameterMap(我测试了也没有成功)，简洁好用的inline-parameterMap应该是首选，配合abator等自动化工具，ibatis照样能达到快速开发。
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/216714#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 20 Jul 2008 18:08:52 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/216714</link>
        <guid>http://zxjava.javaeye.com/blog/216714</guid>
      </item>
      <item>
        <title>XFire</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/215962" style="color:red;">http://zxjava.javaeye.com/blog/215962</a>&nbsp;
          发表时间: 2008年07月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          为了实现Web Services的平台无关性和实现访问独立性，软件行业需要遵循一些作为标准的技术。其中一些包括:---XML:在Web Services环境中各层之间进行传递的默认数据格式。　---SOAP:封装和交换信息的默认协议。第一次被提出时，它是只取Simple Object Access Protocol(简单对象访问协议)的首字母。但是现在SOAP更多被认为是一个特定的名词，以它自己而命名，同样很多人认为这是用词不当:SOAP实际上不是用来访问对象的。另外，它也不再简单。---WSDL(Web Services Description Language，Web Services描述语言):描述Web Services的语言。尽管基于XML并且可以被人理解，WSDL主要是由机器处理，由客户端程序读取和理解。下面的高级层次图表，基于WWW协会发布的“Web Services Architecture”(Web Services架构)文档，显示了这些技术在实际的工作环境中是如何发挥作用: <br /><br />　　这个流程图显示了Web Services中的核心技术是如何工作的。这里，Provider是提供服务的应用程序组件，Requester是使用服务的客户端程序。很多其他技术也会参与到交互中，但是这个图只显示了在Web Services环境中必需的核心技术组件。XFire是一个免费的开源SOAP框架，它不仅可以极大方便地实现这样一个环境，并且可以提供许多Web Services规范中高级特征，这些特征在多数的商业或者开源工具都没有提供。你要恰当的理解这些单词:great ease and simplicity(非常轻松和简单)。你将会看到使用XFire创建Web Services是多么的简单。　假如你的Web应用有一个Java类，并且你想把它的一个方法发布为Web Services，当使用XFire时，你不需要编写一行额外的Java代码。只需要编辑发布描述符，然后你就会得到一个Web Services。是的，它相当地简单。我们来看一个例子。一个简单的Java类我们的例子是一个银行业应用程序，服务器是运行在J2SE1.4.2_07下的Apache Tomcat5.5.7。假定你已经了解如何使用Java编写Web应用程序，并知道应该如何把它部署到Apache Tomcat服务器上。我们的Web应用程序非常简单;它只做一件事——将资金从一个账户转到另外一个账户上。一个普通的Java类BankingService包含了一个叫做transferFunds()的方法来为我们完成这项工作。它需要四个输入参数:1、 String fromAccount 2、 String toAccount 　3、 double amount 4、 String currency <br />package com.mybank.xfire.example; <br />import java.text.NumberFormat; <br />import java.text.DecimalFormat; <br />/** XFire WebServices sample implementation class. <br />*/ <br />public class BankingService implements IBankingService { <br /><br />//Default constructor. <br />public BankingService(){ <br />} <br /><br />/** Transfers fund from one account to another. <br />*/ <br />public String transferFunds( <br />String fromAccount, String toAccount, double amount, String currency){ <br /><br />String statusMessage = ""; <br /><br />//Call business objects and other components to get the job done. <br />//Then create a status message and return. <br />try { <br />NumberFormat formatter = new DecimalFormat("###,###,###,###.00"); <br />statusMessage = "COMPLETED: " + currency + " " + formatter.format(amount)+ <br />" was successfully transferred from A/C# " + fromAccount + " to A/C# " + toAccount; <br />} catch (Exception e){ <br />statusMessage = "BankingService.transferFunds(): EXCEPTION: " + e.toString(); <br />} <br />return statusMessage; <br />} <br /><br />} <br />　　在这里你看到了什么异常的东西了吗?或许没有，除了默认的构造函数，类型是public。这是必须的。否则，XFire不能够初始化这个类。　　因为使用接口的设计是一个好的实践，所以我们的Java类也实现了一个称为IBankingService的接口。代码十分简单: <br />package com.mybank.xfire.example; <br />public interface IBankingService { <br />public String transferFunds( <br />String fromAccount, String toAccount, double amount, String currency); <br /><br />} <br />　　在实际实现中，这样一个方法可能包括各种类型的复杂调用、查询和处理操作。但是我们的示例代码已经最小化了，以至于我们可以集中精力在主要目标上:把这个方法发布为Web Services。 <br />　　你可以看到BankingService是一个普通的Java类，没有任何代码告诉我们它将会在Web Services中使用。好的，这里我们不需要增加任何东西。我们所有的工作都在部署描述符里完成。 <br />　　Web应用的部署描述符 <br />　　在Java中，Web应用程序通常需要至少一个部署描述符(叫做web.xml)对其进行配置。XFire本身是一个基于servlet的应用程序。因此，我们需要增加必要的引用到描述符文件中。然后我们还必须配置将要创建的Web Services。我们使用一个称为services.xml的新文件来完成这件事。 <br />　　web.xml <br />　　首先，修改web.xml。我们需要增加下面的XFire servlet相关的条目: <br />&lt;servlet> <br />&lt;servlet-name>XFireServlet&lt;/servlet-name> <br />&lt;display-name>XFire Servlet&lt;/display-name> <br />&lt;servlet-class>org.codehaus.xfire.transport.http.XfireConfigurableServlet <br />&lt;/servlet-class> <br />&lt;/servlet> <br />&lt;servlet-mapping> <br />&lt;servlet-name>XFireServlet&lt;/servlet-name> <br />&lt;url-pattern>/servlet/XFireServlet/*&lt;/url-pattern> <br />&lt;/servlet-mapping> <br /><br />&lt;servlet-mapping> <br />&lt;servlet-name>XFireServlet&lt;/servlet-name> <br />&lt;url-pattern>/services/*&lt;/url-pattern> <br />&lt;/servlet-mapping> <br />services.xml现在我们不得不说一下我们的Web Services的由什么组成的了。这由一个叫做services.xml的文件完成，它存放在META-INF/xfire目录下，而这整个目录放在WEB-INF/classes文件夹中，它在Web应用程序的标准类路径中。这里是services.xml中的基本配置条目: <br />&lt;beans xmlns="http://xfire.codehaus.org/config/1.0"> <br /><br />&lt;service> <br />&lt;name>Banking&lt;/name> <br />&lt;namespace>mybank&lt;/namespace> <br />&lt;serviceClass>com.mybank.xfire.example.IBankingService&lt;/serviceClass> <br />&lt;implementationClass>com.mybank.xfire.example.BankingService&lt;/implementationClass> <br />&lt;/service> <br /><br />&lt;/beans> <br />　　让我们看看这里都包含了什么内容。Web Services的定义包含在元素中，它还含有一些子元素。第一个子元素是，它可以是你提供任何的合法名字。这将会被客户端程序和其它需要定位你的服务的组件用到。例如，在服务准备好以后，你将在浏览器上使用这个名字来查看WSDL。下一个子元素是&lt;namespace>。任何合法的XML名字都是可以的。&lt;namespace>用来唯一标识你的服务的各个参数。 <br />&lt;serviceClass>元素包含了Java类的名字，它指定了方法签名。在我们的例子中，它是接口IBankingService。如果Java类没有实现任何接口，你就需要把类的名字放在这里。在你的Java类或者接口中可能有几个方法。只需要一个入口把它们全部发布为Web Services。&lt;implementationClass>保存了实现方法的Java类名。这是一个可选元素。如果上一个元素&lt;serviceClass>包含了一个接口，那么相应的实现类必须在这里指定。 <br />　　就是这样。我们的Web Services配置完成了。　XFire和其它类库现在是最后一步了，需要得到所有必需的类库。我们怎样得到它们呢?去XFire网站，下载xfire-distribution-1.0.zip，然后解压到一个本地文件夹。复制下面的jar文件和它的库文件夹到WEB-INF/lib中:• activation-1.0.2.jar • commons-codec-1.3.jar • commons-httpclient-3.0.jar • commons-logging-1.0.4.jar • jaxen-1.1-beta-8.jar• jdom-1.0.jar • log4j-1.2.x.jar • mail-1.3.3_01.jar • spring-1.2.x.jar • stax-api-1.0.jar • wsdl4j-1.5.2.jar • wstx-asl-2.9.jar • xbean-2.1.0.jar • xbean-spring-2.2.jar • xfire-all-1.0.jar 　• XmlSchema-1.0.jar 一切妥当。我们来部署和启动应用程序。为了部署示例应用，只需要复制websvc.war到Apache Tomcat的webapps文件夹中，再等待几秒钟。它将会自动启动。这个应用的全部源代码也包含在这个war文件中。我们的程序已经准备作为一个Web Service了。我们如何知道Web Service正在工作呢?　为了了解Web Service是否正在工作，我们需要测试。首先，我们测试来看WSDL是否可用。我们在浏览器中输入URL。哪个URL?因为我们的应用程序的war文件是websvc.war，并且在services.xml中给出的服务名是Banking，WSDL的URL应该是:http://localhost:8080/websvc/services/Banking?wsdl。请注意:URL的第一部分，例如，http://localhost:8080，可能会根据你的应用服务器不同而不同。无论怎样，当你输入URL后，将会看到一个XML文档，它的根元素是。这个文档叫做服务的WSDL。如果你看到了，这就是你的应用作为Web Service已经可用的第一个证明。　但是这个测试是不够的。可能会发生这种情况，可以看到WSDL，但是从客户端程序可能会访问不到服务。因此为了核实服务是否可以访问了，我们必须使用一个客户端进行服务的实际调用来进行一个真正的测试。开发一个客户端　你可以使用任何的SOAP工具创建客户端，例如，.Net或者Apache Axis，有很多种方法:使用从WSDL产生的stubs，使用动态代理，等等。在例子中，我们使用一个动态代理，以一个简单的Servlet形式，叫做WsClient.java。为了保持代码两最小，所有在屏幕显示的元素都放在了doGet()方法中。对Web Service的实际调用由callWebService()方法完成，它相当地简单。和下面的类似: <br />/* Call the Web service <br />* <br />*/ <br />public String callWebService( <br />String fromAccount, String toAccount, double amount, String currency) <br />throws MalformedURLException, Exception { <br /><br />//Create a metadata of the service <br />Service serviceModel = new ObjectServiceFactory().create(IBankingService.class); <br />log.debug("callSoapServiceLocal(): got service model." ); <br /><br />//Create a proxy for the deployed service <br />XFire xfire = XFireFactory.newInstance().getXFire(); <br />XFireProxyFactory factory = new XFireProxyFactory(xfire); <br /><br />String serviceUrl = "http://localhost:8080/websvc/services/Banking"; <br /><br />IBankingService client = null; <br />try { <br />client = (IBankingService) factory.create(serviceModel, serviceUrl); <br />} catch (MalformedURLException e) { <br />log.error("WsClient.callWebService(): EXCEPTION: " + e.toString()); <br />} <br /><br />//Invoke the service <br />String serviceResponse = ""; <br />try { <br />serviceResponse = client.transferFunds(fromAccount, toAccount, amount, currency); <br />} catch (Exception e){ <br />log.error("WsClient.callWebService(): EXCEPTION: " + e.toString()); <br />serviceResponse = e.toString(); <br />} <br />log.debug("WsClient.callWebService(): status=" + serviceResponse); <br />//Return the response <br />return serviceResponse; <br />} <br />　　这个代码是如何工作的呢?我来解释一下:首先，我们创建一个服务模型，它包含服务的说明——换句话说，就是服务的元数据。我们使用XFire的ObjectServiceFactory从IBankingService.class接口创建这个模型。接着，为XFire获得一个代理工厂对象，它包含了常规的代码，也相当地简单和易懂。这一步中没有任何特定应用的东西。从这个proxyFactory，使用服务模型和服务端点URL(用来获得WSDL)，我们可以得到一个服务的本地代理。就是它了。这个代理就是实际的客户端。现在，我们可以调用它的transferFunds()方法来得到我们需要的Web Service。一旦示例应用发布并启动，就可以尝试servlet URL:http://localhost:8080/websvc/ws　这个Servlet使用默认参数来调用Web Service和显示接收到的响应。页面的最后两行应该读取:Response Received <br />　　COMPLETED: CDN$ 500.00 was successfully transferred from A/C# 11111-01234 to A/C# 99999-05678现在你可以确定Web Service已经发布并且在运行中了。 <br />　　为了尝试不同的输入值，你可以使用完整的URL，例如:http://localhost:8080/websvc/ws?from=11-2345&to=77-9876&amt=250.00&cur=EUR。基本的Web Services开发步骤清单这个清单总结了将一个Java方法发布为Web Service所必须的步骤:　1、 检查Java类的方法和默认构造函数确保为public 　2、 增加XFire servlet相关条目到web.xml中 　3、 创建services.xml，把它放到WEB-INF/classes/META-INF/xfire目录下 4、 增加XFire和第三方包到你的Web应用的WEB-INF/lib文件夹中 <br />　　这就是所有需要的步骤，是的，相当简单。 <br />　　XFire的其他高级特性 <br />　　XFire的使用可能比较简单，但是在特性和功能性上，它却占据着领导者的位置。下面是它的高级特性: <br />• 　　---本地数据绑定支持POJOs(plain-old Java objects)、XMLBeans、JAXB(Java Architecture for XML Binding)、Castor等等。数据绑定说明了Web Services的XML请求和映射到Java对象的XML响应。 <br />• 　　---使用StAX(Streaming API for XML)处理XML文档。同DOM的基于树和SAX的事件驱动的处理方式相比，StAX使用了拉(pull)机制，它使处理更快速，内存效率更高。 <br />• 　　---支持多种传输协议，如HTTP、JMS(Java Message Service)和JVM内部传输。 <br />• 　　---嵌入式，这是XFire的核心功能之一。你可以把这个SOAP引擎嵌入到你的应用中，完全隐藏所有XFire特定引用，同样所有配置都是程序驱动。 <br />• 　　---丰富的API，它使XFire可高度自定义，允许开发者在不同的阶段截获请求，并且对他们进行处理。 <br />• 　　---兼容最新的标准例如SOAP1.1(没有加密远程工程调用，或者RPC)和1.2、WSDL1.1、the Web Services Interoperability Organization’s Basic Profile 1.0、Web Services Addressing和WS-Security。 <br />　　最重要的是，XFire属于新一代Web Services引擎。不仅仅是营销用语，“新一代”有一些重要的意义。Apache Axis是第一代Java语言的Web Services引擎，已经成为了所有后来工具的参考标准。在过去的几年里，Axis以及这些其它的工具已经在很多生产环境中进行了实地测试。从中得出的一个关键的问题就是Web Services并不最适合RPC类型的通信。对于性能和效率，面向文档的消息形式是最好的方式。但是Apache Axis和很多其他的Web Services引擎都被设计成了面向RPC的(尽管它们支持文档形式)。现在，整个行业正在开发新一代的SOAP引擎，设计为面向文档的。Apache已经宣布结束旧版本的Axis引擎开发，现在专注于Axis2，现在它的预发布版本是0.95。XFire在今年的2月份发布了它的第一个产品版本(1.0)。它的下一个版本(1.1)仅仅在几个星期之后就进行了发布。 <br /><br />　　性能 <br />　　Web Services需要消耗很多资源，但是性能方面它们不是那么引人注目。XFire打破了这种趋势。它消耗更少的内存(部分因为 StAX的使用)，但是表现却比多数可比较的SOAP引擎出色。你可以在资源中提供的链接中看到比较的结果。 <br />　　此外，XFire还提供了各种方法来进一步优化性能。一个方法是使用JVM内置传输(in-JVM transport)。如果你知道Web Services和客户端运行在同一个JVM上，你可以选择使用本地传输，它可以大幅提升性能。在示例中的客户端代码，看以下指定服务端点URL的这行: <br />　　String serviceUrl = "http://localhost:8080/websvc/services/Banking"; <br />　　替换为 <br />　　String serviceUrl = "xfire.local://Banking"; <br />　　你会看到性能上的明显提高，因为它绕过了整个网络层。 <br />　　局限性 <br />　　XFire有些重要的局限性你应该清楚: <br />• 　　---开发Web Services的好的实践是从WSDL开始。大部分的SOAP引擎提供了从WSDL生成服务stub的工具。XFire也提供了这样一个工具。但是它是基于注释(annotations-based)的，因此需要J2SE5.0。对于仍坚持使用J2SE1.4.x的人来说，它不是一个令人拍手叫好的工具，因为我们有很多其他方式来编写客户端，一个就是文章中演示的方式。 <br />• 　　---附件支持，它将会包含在未来发行的版本中。 <br />• 　　---易于学习的用户向导。XFire团队在这个方面还有很多工作需要做。 <br />　　结论 <br />　　Java当前的趋势是简化技术的使用。因此，我们正看到一波基于POJO的开发成就。同时，面向服务架构(SOA，Services-oriented architecture)和Web Services已经变成了当前行业的热点话题。XFire正是在这种情况下产生的。它能够使POJO发布为最少的Web Services，而只需要付出最小化的努力。从而，它使希望使用这项技术的初级开发者的学习曲线变得平缓。同时，由于它兼容最新标准和提供了丰富的API，XFire为高级用户提供了更多的大好机会。
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/215962#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 17 Jul 2008 22:33:43 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/215962</link>
        <guid>http://zxjava.javaeye.com/blog/215962</guid>
      </item>
      <item>
        <title>Spring mvc 初体验</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/208986" style="color:red;">http://zxjava.javaeye.com/blog/208986</a>&nbsp;
          发表时间: 2008年06月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这篇文章将教你快速地上手使用 Spring 框架. 如果你手上有一本《Spring in Action》, 那么你最好从第三部分"Spring 在 Web 层的应用--建立 Web 层"开始看, 否则那将是一场恶梦! <br /><br />首先, 我需要在你心里建立起 Spring MVC 的基本概念. 基于 Spring 的 Web 应用程序接收到 http://localhost:8080/hello.do(事实上请求路径是 /hello.do) 的请求后, Spring 将这个请求交给一个名为 helloController 的程序进行处理, helloController 再调用 一个名为 hello.jsp 的 jsp 文件生成 HTML 代码发给用户的浏览器显示. 上面的名称(/hello.do, helloController, hello.jsp) 都是变量, 你可以更改. <br /><br />在 Spring MVC 中, jsp 文件中尽量不要有 Java 代码, 只有 HTML 代码和"迭代(forEach)"与"判断(if)"两个jstl标签. jsp 文件只作为渲染(或称为视图 View)模板使用. <br /><br />好了, 我们开始吧. 首先我们需要一个放在 WEB-INF 目录下的 web.xml 文件: <br /><br />web.xml: <br /> 1 &lt;?xml version="1.0" encoding="UTF-8"?> 2  3 &lt;web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" 4          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5          xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 6          http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 7  8     &lt;context-param> 9         &lt;param-name>contextConfigLocation&lt;/param-name>10         &lt;param-value>11             /WEB-INF/database.xml12             /WEB-INF/applicationContext.xml13         &lt;/param-value>14     &lt;/context-param>15 16     &lt;listener>17         &lt;listener-class>org.springframework.web.context.ContextLoaderListener&lt;/listener-class>18     &lt;/listener>19 20     &lt;filter>21         &lt;filter-name>encodingFilter&lt;/filter-name>22         &lt;filter-class>org.springframework.web.filter.CharacterEncodingFilter&lt;/filter-class>23         &lt;init-param>24             &lt;param-name>encoding&lt;/param-name>25             &lt;param-value>UTF-8&lt;/param-value>26         &lt;/init-param>27     &lt;/filter>28 29     &lt;filter-mapping>30         &lt;filter-name>encodingFilter&lt;/filter-name>31         &lt;url-pattern>*.do&lt;/url-pattern>32     &lt;/filter-mapping>33 34     &lt;servlet>35         &lt;servlet-name>ideawu&lt;/servlet-name>36         &lt;servlet-class>org.springframework.web.servlet.DispatcherServlet&lt;/servlet-class>37         &lt;load-on-startup>1&lt;/load-on-startup>38     &lt;/servlet>39 40     &lt;servlet-mapping>41         &lt;servlet-name>ideawu&lt;/servlet-name>42         &lt;url-pattern>*.do&lt;/url-pattern>43     &lt;/servlet-mapping>44 45     &lt;welcome-file-list>46         &lt;welcome-file>index.jsp&lt;/welcome-file>47         &lt;welcome-file>index.html&lt;/welcome-file>48     &lt;/welcome-file-list>49 50     &lt;jsp-config>51         &lt;taglib>52             &lt;taglib-uri>http://java.sun.com/jsp/jstl/core&lt;/taglib-uri>53             &lt;taglib-location>/WEB-INF/tld/c.tld&lt;/taglib-location>54         &lt;/taglib>55         &lt;taglib>56             &lt;taglib-uri>http://java.sun.com/jsp/jstl/fmt&lt;/taglib-uri>57             &lt;taglib-location>/WEB-INF/tld/fmt.tld&lt;/taglib-location>58         &lt;/taglib>59     &lt;/jsp-config>60 61 &lt;/web-app> 它配置了以下功能: <br /><br />配置 DispatcherServlet (servlet 标签), 它是一个 Java Servlet 程序. 我们将它命名为 ideawu. 然后我们再配置 Servlet 映射(servlet-mapping 标签), 也就是你希望哪些请求被DispatcherServlet处理. 这里, 我们设置后缀名为 do(*.do) 的所有URL请求都被名为 ideawu 的 DispatcherServlet 的程序处理. 选择 .do 只是一个习惯,但是你不要选择 .html! 虽然《Spring in Action》选择了 .html, 但是那是一种非常糟糕的作法, 特别是你整合 Apache 和 Tomcat 的时候. <br />配置 CharacterEncodingFilter (filter 标签), 否则你会发现中文乱码. 因为我的 jsp 和 html 文件都是 UTF-8 编码的, 所以我在 param-value 标签中设置了 UTF-8. 估计你使用的是 GB2312 或者 GBK, 立即转到 UTF-8 上来吧. <br />分解配置文件. context-param 标签指明我们的配置文件还有 /WEB-INF/database.xml 和 /WEB-INF/applicationContext.xml. ContextLoaderListener(listener 标签) 由此得知配置文件是哪些, 它会将它们载入. <br />因为我们将 DispatcherServlet 命名为 ideawu, 所以我们在 WEB-INF 目录下建立一个名为 ideawu-servlet.xml 的文件: <br /><br />ideawu-servlet.xml: <br /> 1 &lt;?xml version="1.0" encoding="UTF-8" ?> 2 &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 3  4 &lt;beans> 5  6     &lt;bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 7         &lt;property name="prefix" value="/WEB-INF/jsp/" /> 8         &lt;property name="suffix" value=".jsp" /> 9     &lt;/bean>10 11     &lt;bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">12         &lt;property name="mappings">13             &lt;props>14                 &lt;prop key="/hello.do">helloController&lt;/prop>15             &lt;/props>16         &lt;/property>17     &lt;/bean>18 19     &lt;bean id="helloController" class="com.ideawu.HelloController">20         &lt;!--21         &lt;property name="helloManager" ref="helloManager" />22         -->23     &lt;/bean>24 25 &lt;/beans> 它配置了以下功能: <br /><br />配置 InternalResourceViewResolver, 它是 jsp 渲染模板的处理器. 如果你告诉 InternalResourceViewResolver 处理一个名为 hello 的模板时, 它会渲染 /WEB-INF/jsp/hello.jsp 文件. 把 jsp 文件放到 /WEB-INF/jsp/ 目录下是被鼓励的, 这样可以防止用户不经过 Controller 直接访问 jsp 文件从而出错(有些顽皮的人很喜欢这样做). <br />配置 SimpleUrlHandlerMapping, 在上面的配置文件中, /hello.do 的请求将被 helloController 处理. "/hello.do"和"helloController" 是变量, 你可以更改. 但是你注意到了吗, hello.do 以 .do 作为后缀名. 如果这里(本文的条件下)你 不使用.do 作为后缀名, 就没有程序来处理这个请求了. 因为 DispatcherServlet 将收到的请求转交给 SimpleUrlHandlerMapping, DispatcherServlet 收不到的请求, SimpleUrlHandlerMapping 当然也收不到了. 你可以在 props 标签内配置多个 prop 标签. <br />我们将在后面编写 com.ideawu.HelloController 类. <br />上面, 我们在 web.xml 文件中告诉 ContextLoaderListener, 我们还有另外两个配置文件 /WEB-INF/database.xml 和 /WEB-INF/applicationContext.xml. <br /><br />applicationContext.xml: <br /> 1 &lt;?xml version="1.0" encoding="UTF-8"?> 2 &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 3  4 &lt;beans> 5  6     &lt;bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 7         &lt;property name="locations"> 8             &lt;list> 9                 &lt;value>/WEB-INF/jdbc.properties&lt;/value>10             &lt;/list>11         &lt;/property>12     &lt;/bean>13 14 &lt;/beans> 它配置了以下功能: <br /><br />读取 /WEB-INF/jdbc.properties 文件. 你可以在 list 标签中配置多个 value 标签. <br />database.xml: <br /> 1 &lt;?xml version="1.0" encoding="UTF-8"?> 2 &lt;!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> 3  4 &lt;beans> 5  6     &lt;!-- Remove this if your database setting is fine. 7     &lt;bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 8         &lt;property name="driverClassName" value="${jdbc.driverClassName}"/> 9         &lt;property name="url" value="${jdbc.url}"/>10         &lt;property name="username" value="${jdbc.username}"/>11         &lt;property name="password" value="${jdbc.password}"/>12     &lt;/bean>13     -->14 15     &lt;!-- Transaction manager for a single JDBC DataSource16     &lt;bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">17         &lt;property name="dataSource" ref="dataSource"/>18     &lt;/bean>19     -->20 21     &lt;!--22     &lt;bean id="attributeManager" class="com.ideawu.core.AttributeManager">23         &lt;property name="dataSource" ref="dataSource"/>24     &lt;/bean>25     -->26 27 &lt;/beans> 它配置了以下功能(不过,已经注释掉了): <br /><br />配置数据库连接. 类似${jbbc.url}是一种访问变量的方法. 我们可以从 /WEB-INF/jdbc.properties 中找到这个变量的值. 如果你的数据库已经配置好, 就将第一个注释去掉. <br />jdbc.properties: <br />1 jdbc.driverClassName=com.mysql.jdbc.Driver2 jdbc.url=jdbc:mysql://localhost/test?useUnicode=true&characterEncoding=UTF-83 jdbc.username=test4 jdbc.password=12345 现在, 我们来编写 Java 代码吧. <br /> 1 /*********************************************************** 2 * Date: 2006-8-26 3 * File: HelloController.java 4 * Author: ideawu 5 ***********************************************************/ 6  7 package com.ideawu; 8  9 import org.springframework.web.servlet.mvc.Controller;10 import org.springframework.web.servlet.ModelAndView;11 12 import javax.servlet.http.HttpServletRequest;13 import javax.servlet.http.HttpServletResponse;14 15 /**16  * @author ideawu17  *18  */19 public class HelloController implements Controller {20 /*  21     private HelloManager helloManager;22 23     public void setHelloManager(HelloManager helloManager) {24         this.helloManager = helloManager;25     }26 */27 28     public ModelAndView handleRequest(HttpServletRequest request,29             HttpServletResponse response)throws Exception{30 31         request.setAttribute("hello_1", "你好啊, Spring!");32         request.setAttribute("hello_2", "Hello World!");33 34         return new ModelAndView("hello");35     }36 37 }return new ModelAndView("hello"); 告诉 InternalResourceViewResolver jsp 模板的名字叫作 hello. request.setAttribute() 设置的对象我们可以在 jsp 文件中使用. <br /><br />hello.jsp: <br /> 1 &lt;%@ page contentType="text/html; charset=UTF-8" %> 2 &lt;%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 4 &lt;html xmlns="http://www.w3.org/1999/xhtml"> 5 &lt;head> 6     &lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 7     &lt;title>Hello World!&lt;/title> 8 &lt;/head> 9 &lt;body>10 11 &lt;h2>${hello_1}&lt;/h2>12 13 &lt;h2>${hello_2}&lt;/h2>14 15 &lt;/body>16 &lt;/html>
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/208986#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 28 Jun 2008 18:33:56 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/208986</link>
        <guid>http://zxjava.javaeye.com/blog/208986</guid>
      </item>
      <item>
        <title>synchronized的作用</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/200403" style="color:red;">http://zxjava.javaeye.com/blog/200403</a>&nbsp;
          发表时间: 2008年06月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一、同步方法<br />public synchronized void methodAAA(){<br /><br />//….<br /><br />}<br />锁定的是调用这个同步方法的对象<br /><br />测试：<br />a、不使用这个关键字修饰方法，两个线程调用同一个对象的这个方法。<br />目标类：<br /><br />1public class TestThread {<br />2    public  void execute(){  //synchronized,未修饰<br />3        for(int i=0;i&lt;100;i++){<br />4            System.out.println(i);<br />5        }    <br />6    }<br />7}<br /><br />线程类：<br /><br />1public class ThreadA implements Runnable{<br />2    TestThread test=null;<br />3    public ThreadA(TestThread pTest){  //对象有外部引入，这样保证是同一个对象<br />4        test=pTest;<br />5    }<br />6    public void run() {<br />7        test.execute();<br />8    }<br />9}<br />调用：<br />1TestThread test=new TestThread();<br />2Runnable runabble=new ThreadA(test);<br />3Thread a=new Thread(runabble,"A");                <br />4a.start();<br />5Thread b=new Thread(runabble,"B");<br />6b.start();<br /><br />结果：<br />输出的数字交错在一起。说明不是同步的，两个方法在不同的线程中是异步调用的。<br /><br />b、修改目标类，增加synchronized修饰<br /><br />1public class TestThread {<br />2    public synchronized  void execute(){  //synchronized修饰<br />3        for(int i=0;i&lt;100;i++){<br />4            System.out.println(i);<br />5        }    <br />6    }<br />7}<br /><br />结果：<br />输出的数字是有序的，首先输出A的数字，然后是B，说明是同步的，虽然是不同的线程，但两个方法是同步调用的。<br />注意：上面虽然是两个不同的线程，但是是同一个实例对象。下面使用不同的实例对象进行测试。<br /><br />c、每个线程都有独立的TestThread对象。<br />目标类：<br /><br />1public class TestThread {<br />2    public synchronized void execute(){  //synchronized修饰<br />3        for(int i=0;i&lt;100;i++){<br />4            System.out.println(i);<br />5        }    <br />6    }<br />7}<br />线程类：<br />1public class ThreadA implements Runnable{<br />2    public void run() {<br />3        TestThread test=new TestThread();<br />4        test.execute();<br />5    }<br />6}<br />7<br />调用：<br />1Runnable runabble=new ThreadA();<br />2Thread a=new Thread(runabble,"A");                <br />3a.start();<br />4Thread b=new Thread(runabble,"B");<br />5b.start();<br /><br />结果：<br />输出的数字交错在一起。说明虽然增加了synchronized 关键字来修饰方法，但是不同的线程调用各自的对象实例，两个方法仍然是异步的。<br /><br />引申：<br />对于这种多个实例，要想实现同步即输出的数字是有序并且按线程先后顺序输出，我们可以增加一个静态变量，对它进行加锁(后面将说明锁定的对象)。<br /><br />修改目标类：<br /><br /> 1public class TestThread {<br /> 2    private static Object lock=new Object(); //必须是静态的。<br /> 3    public  void execute(){<br /> 4        synchronized(lock){<br /> 5            for(int i=0;i&lt;100;i++){<br /> 6                System.out.println(i);<br /> 7            }    <br /> 8        }<br /> 9    }<br />10}<br />二、同步代码块<br /><br />1public void method(SomeObject so){<br />2    synchronized(so)<br />3       //…..<br />4    }<br />5}<br />锁定一个对象，其实锁定的是该对象的引用（object reference）<br />谁拿到这个锁谁就可以运行它所控制的那段代码。当有一个明确的对象作为锁时，就可以按上面的代码写程序，但当没有明确的对象作为锁，只是想让一段代码同步时，可以创建一个特殊的instance变量（它必须是一个对象）来充当锁（上面的解决方法就是增加了一个状态锁）。<br /><br />a、锁定一个对象，它不是静态的<br />private byte[] lock = new byte[0]; // 特殊的instance变量<br />目标类：<br /><br /> 1public class TestThread {<br /> 2    private Object lock=new Object(); <br /> 3    public  void execute(){<br /> 4        synchronized(lock){  //增加了个锁，锁定了对象lock，在同一个类实例中，是线程安全的，但不同的实例还是不安全的。<br /> 5<br /> 6因为不同的实例有不同对象锁lock<br /> 7            for(int i=0;i&lt;100;i++){<br /> 8                System.out.println(i);<br /> 9            }    <br />10        }<br />11    }<br />12}  <br /><br />其实上面锁定一个方法，等同于下面的：<br /><br />1public void execute(){  <br />2    synchronized(this){   //同步的是当然对象<br />3        for(int i=0;i&lt;100;i++){<br />4            System.out.println(i);<br />5        }    <br />6    }<br />7}<br />b、锁定一个对象或方法，它是静态的<br />这样锁定，它锁定的是对象所属的类<br />public synchronized  static void execute(){<br />    //...<br />}<br />等同于<br /><br />1public class TestThread {<br />2    public static void execute(){<br />3        synchronized(TestThread.class){<br />4            //<br />5        }<br />6    }<br />7}<br />测试：<br /><br />目标类：<br /><br /> 1public class TestThread {<br /> 2    private static Object lock=new Object();<br /> 3    public synchronized static void execute(){  //同步静态方法<br /> 4        for(int i=0;i&lt;100;i++){<br /> 5            System.out.println(i);<br /> 6        }    <br /> 7    }<br /> 8    public static void execute1(){<br /> 9        for(int i=0;i&lt;100;i++){<br />10            System.out.println(i);<br />11        }    <br />12    }<br />13    public void test(){<br />14        execute();     //输出是有序的，说明是同步的<br />15        //execute1();  //输出是无须的，说明是异步的<br />16    }<br />17}<br />线程类：调用不同的方法，于是建立了两个线程类<br /><br /><br /> 1public class ThreadA implements Runnable{<br /> 2    public void run() {<br /> 3        TestThread.execute();//调用同步静态方法<br /> 4    }<br /> 5}<br /> 6public class ThreadB implements Runnable{<br /> 7    public void run() {<br /> 8        TestThread test=new TestThread();<br /> 9        test.test();//调用非同步非静态方法<br />10    }<br />11}<br />调用：<br /><br />1Runnable runabbleA=new ThreadA();<br />2Thread a=new Thread(runabbleA,"A");                <br />3a.start();<br />4Runnable runabbleB=new ThreadB();<br />5Thread b=new Thread(runabbleB,"B");                <br />6b.start();<br />注意:<br />1、用synchronized 来锁定一个对象的时候，如果这个对象在锁定代码段中被修改了，则这个锁也就消失了。看下面的实例：<br /><br />目标类：<br /><br /> 1public class TestThread {<br /> 2     private static final class TestThreadHolder {<br /> 3            private static TestThread theSingleton = new TestThread();<br /> 4            public static TestThread getSingleton() {<br /> 5                return theSingleton;<br /> 6            }<br /> 7            private TestThreadHolder() {<br /> 8            }<br /> 9        }<br />10     <br />11    private Vector ve =null;<br />12    private Object lock=new Object();<br />13    private TestThread(){<br />14        ve=new Vector();<br />15        initialize();<br />16    }<br />17    public static TestThread getInstance(){<br />18        return TestThreadHolder.getSingleton();<br />19    }<br />20    private void initialize(){<br />21        for(int i=0;i&lt;100;i++){<br />22            ve.add(String.valueOf(i));<br />23        }<br />24    }<br />25    public void reload(){<br />26        synchronized(lock){<br />27            ve=null;            <br />28            ve=new Vector();<br />29                        //lock="abc"; <br />30            for(int i=0;i&lt;100;i++){<br />31                ve.add(String.valueOf(i));<br />32            }<br />33        }<br />34        System.out.println("reload end");<br />35    }<br />36    <br />37    public boolean checkValid(String str){<br />38        synchronized(lock){<br />39            System.out.println(ve.size());<br />40            return ve.contains(str);<br />41        }<br />42    }<br />43}<br />说明：在reload和checkValid方法中都增加了synchronized关键字，对lock对象进行加锁。在不同线程中对同一个对象实例分别调用reload和checkValid方法。<br />在reload方法中，不修改lock对象即注释lock="abc"; ，结果在控制台输出reload end后才输出100。说明是同步调用的。<br />如果在reload方法中修改lock对象即去掉注释，结果首先输出了一个数字(当前ve的大小)，然后输出reload end。说明是异步调用的。 <br /><br />2、单例模式中对多线程的考虑<br /><br /> 1public class TestThread {<br /> 2     private static final class TestThreadHolder {<br /> 3            private static TestThread theSingleton = new TestThread();<br /> 4            public static TestThread getSingleton() {<br /> 5                return theSingleton;<br /> 6            }<br /> 7            private TestThreadHolder() {<br /> 8            }<br /> 9        }<br />10    private Vector ve =null;<br />11    private Object lock=new Object();<br />12    private TestThread(){<br />13        ve=new Vector();<br />14        initialize();<br />15    }<br />16    public static TestThread getInstance(){<br />17        return TestThreadHolder.getSingleton();<br />18    }<br />19        '''<br />20}<br />说明：增加了一个内部类，在内部类中申明一个静态的对象，实例化该单例类，初始化的数据都在单例类的构造函数中进行。这样保证了多个实例同时访问的时候，初始化的数据都已经成功初始化了。<br /><br />总结：<br />A. 无论synchronized关键字加在方法上还是对象上，它取得的锁都是对象，而不是把一段代码或函数当作锁,所以首先应知道需要加锁的对象<br />B．每个对象只有一个锁（lock）与之相关联。<br />C．实现同步是要很大的系统开销作为代价的，甚至可能造成死锁，所以尽量避免无谓的同步控制。
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/200403#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 05 Jun 2008 10:27:47 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/200403</link>
        <guid>http://zxjava.javaeye.com/blog/200403</guid>
      </item>
      <item>
        <title>ibatis使用</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/197780" style="color:red;">http://zxjava.javaeye.com/blog/197780</a>&nbsp;
          发表时间: 2008年05月28日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          使用ibatis的十个理由,知道怎样操作10种以上的数据库<br />9 、可配置的caching(包括从属)<br />8、支持DataSource、local transaction managemen和global transaction<br />7、简单的XML配置文档<br />6、支持Map, Collection, List和简单类型包装(如Integer, String)<br />5、支持JavaBeans类(get/set 方法)<br />4、支持复杂的对象映射(如populating lists, complex object models)<br />3、对象模型从不完美(不需要修改)<br />2、数据模型从不完美(不需要修改)<br />1、你已经知道SQL，为什么还要学习其他东西 <br /><br /> <br /><br />配至文件说明：DB.properties:<br /><br />SimpleDriver=oracle.jdbc.OracleDriver<br />SimpleUrl=jdbc:oracle:thin:@10.0.0.5:1521:champion<br />SimpleUsername=root<br />SimplePassword=aa<br /><br /><br />sql-map-config-storedb.xml:<br /><br />&lt;?xml version="1.0" encoding="UTF-8"?><br />&lt;!DOCTYPE sql-map-config<br />PUBLIC "-//iBATIS.com//DTD SQL Map Config 1.0//EN"<br />"http://www.ibatis.com/dtd/sql-map-config.dtd"> <br /><br />&lt;sql-map-config><br /><br />&lt;properties resource="properties/DB.properties" /><br /><br />&lt;settings<br />maxExecute="0"<br />maxExecutePerConnection="0"<br />maxTransactions="0"<br />cacheModelsEnabled="true"<br />statementCacheSize="175"<br />useBeansMetaClasses="false"<br />useGlobalTransactions="false" /><br /><br />&lt;datasource name="jpestoreSimple"<br />factory-class="com.ibatis.db.sqlmap.datasource.DbcpDataSourceFactory"<br />default="true" ><br />&lt;property name="JDBC.Driver" value="${SimpleDriver}"/><br />&lt;property name="JDBC.ConnectionURL" value="${SimpleUrl}"/><br />&lt;property name="JDBC.Username" value="${SimpleUsername}"/><br />&lt;property name="JDBC.Password" value="${SimplePassword}"/><br />&lt;property name="Pool.MaximumActiveConnections" value="15"/><br />&lt;property name="Pool.MaximumIdleConnections" value="15"/><br />&lt;property name="Pool.MaximumWait" value="1000"/><br />&lt;/datasource><br /><br />&lt;sql-map resource="sqlmap/Category.xml" /><br /><br />&lt;/sql-map-config><br /><br /><br />这里真正实现了数据库连接，我们使用的是dbcp的连接池。JDBC的配置大家都很熟了。${SimpleDriver}就是指的前面DB.properties中的SimpleDriver的内容。<br /><br /><br />Category.xml:<br /><br />&lt;?xml version="1.0" encoding="UTF-8"?><br />&lt;!DOCTYPE sql-map<br />PUBLIC "-//iBATIS.com//DTD SQL Map 1.0//EN"<br />"http://www.ibatis.com/dtd/sql-map.dtd"><br /><br />&lt;sql-map name="Category"><br /><br />　<br /><br />&lt;result-map name="result" class="com.ewuxi.champion.persistence.vo.Category"><br />&lt;property name="categoryId" column="CATID" columnIndex="1" /><br />&lt;property name="name" column="NAME" columnIndex="2"/><br />&lt;property name="description" column="DESCN" columnIndex="3"/><br />&lt;/result-map><br /><br />&lt;mapped-statement name="findByPrimaryKeyCategoryDao" result-map="result"><br />select CATID, NAME, DESCN from CATEGORY where CATID = #categoryId#<br />&lt;/mapped-statement><br /><br />&lt;dynamic-mapped-statement name="findCategoryDao" result-map="result"><br />select CATID, NAME, DESCN from CATEGORY<br />&lt;dynamic prepend="where"><br />&lt;isNotNull prepend="and" property="categoryId" ><br />CATID = #categoryId#<br />&lt;/isNotNull><br />&lt;isNotNull prepend="and" property="name" ><br />NAME = #name#<br />&lt;/isNotNull><br />&lt;isNotNull prepend="and" property="description"><br />DESCN = #description#<br />&lt;/isNotNull><br />&lt;/dynamic><br />&lt;/dynamic-mapped-statement><br /><br /><br />&lt;mapped-statement name="findCategoryDaoCount" result-class="java.lang.Integer"><br />select count(1) as value from CATEGORY<br />&lt;/mapped-statement><br /><br /><br />&lt;!-- =============================================<br />mapped-statement<br />============================================= --><br /><br />&lt;dynamic-mapped-statement name="updateByPrimaryKeyCategoryDao"><br />update CATEGORY<br />&lt;dynamic prepend="set"><br />&lt;isNotNull prepend="," property="name" ><br />NAME = #name#<br />&lt;/isNotNull><br />&lt;isNotNull prepend="," property="description"><br />DESCN = #description#<br />&lt;/isNotNull><br />&lt;/dynamic><br />where<br />CATID =#categoryId#<br />&lt;/dynamic-mapped-statement><br /><br />&lt;!-- =============================================<br />mapped-statement<br />============================================= --><br /><br />&lt;mapped-statement name="deleteByPrimaryKeyCategoryDao"><br />delete from CATEGORY<br />where CATID =#categoryId#<br />&lt;/mapped-statement><br /><br /><br />&lt;!-- =============================================<br />OPTIONAL EXPLICIT PARAMETER MAP<br />============================================= --><br /><br />&lt;parameter-map name="insert-params"><br />&lt;property name="categoryId"/><br />&lt;property name="name" type="VARCHAR"/><br />&lt;property name="description" type="VARCHAR"/><br />&lt;/parameter-map><br /><br />&lt;!-- =============================================<br />MAPPED STATEMENTS - w/Explicit Parameter Map<br />============================================= --><br /><br />&lt;mapped-statement name="insertCategoryDao" parameter-map="insert-params" ><br />insert into CATEGORY (<br />CATID,NAME,DESCN)<br />values (<br />?,?,?<br />)<br />&lt;/mapped-statement><br />&lt;/sql-map><br /><br />上述文件就是真正的SQL所存在的地方。
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/197780#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 28 May 2008 11:04:41 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/197780</link>
        <guid>http://zxjava.javaeye.com/blog/197780</guid>
      </item>
      <item>
        <title>JFreeChart教程</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/197096" style="color:red;">http://zxjava.javaeye.com/blog/197096</a>&nbsp;
          发表时间: 2008年05月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一、JFreeChart获取。 <br />JFreeChart是JFreeChart公司在开源网站SourceForge.net上的一个项目，该公司的主要产品有如下： <br />1、JFreeReport：报表解决工具 <br />2、JFreeChart：Java图形解决方案（Application/Applet/Servlet/Jsp） <br />3、JCommon：JFreeReport和JFreeChart的公共类库 <br />4、JFreeDesigner：JFreeReport的报表设计工具 <br /><br />我们可以从jfree官方网站上获取最新版本（最新的版本是1.0.5）和相关资料（但是jfree的Developer Guides是需要花美金才能获取）， <br />获取地址：http://www.jfree.org/jfreechart/index.html（同时可以获得简明介绍） <br />我们以当前版本：jfreechart-1.0.0-rc3.tar.gz为例子进行说明 <br /><br />二、JFreeChart配置安装 <br />1、解压jfreechart_0.9.21.zip到指定位置，其中source是jfreechart的源码，jfreechart-0.9.21-demo.jar <br />是例子程序（该部分留给大家自己去研究） <br />2、为了配置成功，我们需要关注的文件有如下三个：jfreechart-0.9.21.jar、lib\jcommon-0.9.6.jar、 <br />lib\gnujaxp.jar <br />3、如果是Application开发，把上述三个文件拷贝到%JAVA_HOME%\LIB中，同时在环境变量CLASSPATH中加入 <br />二、JFreeChart配置安装 <br />1、解压jfreechart_0.9.21.zip到指定位置，其中source是jfreechart的源码，jfreechart-0.9.21-demo.jar <br />是例子程序（该部分留给大家自己去研究） <br />2、为了配置成功，我们需要关注的文件有如下三个：jfreechart-0.9.21.jar、lib\jcommon-0.9.6.jar、 <br />lib\gnujaxp.jar <br />3、如果是Application开发，把上述三个文件拷贝到%JAVA_HOME%\LIB中，同时在环境变量CLASSPATH中加入 <br />如果是WEB开发，以TOMCAT中的一个WEB项目TEST为例子说明： <br />把上述三个文件拷贝到TEST\WEB-INF\LIB中，然后修改TEST\WEB-INF\web.xml文件，在其中加入如下代码： <br />&lt;servlet> <br />&lt;servlet-name>DisplayChart&lt;/servlet-name> <br />&lt;servlet-class>org.jfree.chart.servlet.DisplayChart&lt;/servlet-class> <br />&lt;/servlet> <br />&lt;servlet-mapping> <br />&lt;servlet-name>DisplayChart&lt;/servlet-name> <br />&lt;url-pattern>/servlet/DisplayChart&lt;/url-pattern> <br />&lt;/servlet-mapping> <br />至此jfreechart的配置就完成了，下面就可以进行jfreechart的开发了。这里值得提出的是jfreechart的类 <br />结构设计前后兼容性不是很好，不同版本的jfreechart中类库结构可能不一样，有时候可能需要查源码。如果 <br />是中文显示的时候可能依据观感需要改变源码的字体，不过我个人觉得这个版本比以前版本要好一些。 <br /><br />三、JFreeChart功能介绍 <br />JFreeChart目前是最好的java图形解决方案，基本能够解决目前的图形方面的需求，主要包括如下几个方面： <br />pie charts (2D and 3D)：饼图（平面和立体） <br />bar charts (regular and stacked, with an optional 3D effect)：柱状图 <br />line and area charts：曲线图 <br />scatter plots and bubble charts <br />time series, high/low/open/close charts and candle stick charts：时序图 <br />combination charts：复合图 <br />Pareto charts <br />Gantt charts：甘特图 <br />wind plots, meter charts and symbol charts <br />wafer map charts <br />(态图表,饼图(二维和三维) , 柱状图 (水平,垂直),线图,点图,时间变化图,甘特图, 股票行情图,混和图, 温度计图, 刻度图等常用商用图表) <br />图形可以导出成PNG和JPEG格式，同时还可以与PDF和EXCEL关联 <br />JFreeChart核心类库介绍： <br />研究jfreechart源码发现源码的主要由两个大的包组成：org.jfree.chart,org.jfree.data。其中前者主要与图形 本身有关，后者与图形显示的数据有关。具体研究如果大家有兴趣的话可以自己研究，以后有时间我会告诉大家怎么去研究源码。 <br />核心类主要有： <br />org.jfree.chart.JFreeChart：图表对象，任何类型的图表的最终表现形式都是在该对象进行一些属性的定制。JFreeChart引擎本身提供了一个工厂类用于创建不同类型的图表对象 <br />org.jfree.data.category.XXXDataSet:数据集对象，用于提供显示图表所用的数据。根据不同类型的图表对应着很多类型的数据集对象类 <br />org.jfree.chart.plot.XXXPlot：图表区域对象，基本上这个对象决定着什么样式的图表，创建该对象的时候需要Axis、Renderer以及数据集对象的支持 <br />org.jfree.chart.axis.XXXAxis：用于处理图表的两个轴：纵轴和横轴 <br />org.jfree.chart.render.XXXRender：负责如何显示一个图表对象 <br />org.jfree.chart.urls.XXXURLGenerator:用于生成Web图表中每个项目的鼠标点击链接 <br />XXXXXToolTipGenerator:用于生成图象的帮助提示，不同类型图表对应不同类型的工具提示类 <br />四、JFreeChart开发（Application/Applet） <br /><br />one: pie charts <br /><br />/** <br /><br />* JfreeChartTest.java <br /><br />* author:longlong <br /><br />* May 31, 2007 <br /><br />*/ <br /><br />package com.ghg.java; <br /><br /><br /><br />import org.jfree.data.general.DefaultPieDataset; <br /><br />import org.jfree.chart.*; <br /><br /><br /><br />public class JfreeChartTest { <br /><br />public static void main(String[] args) { <br /><br />//创建饼图数据对象 <br /><br />DefaultPieDataset dfp=new DefaultPieDataset(); <br /><br />dfp.setValue("管理人员", 25); <br /><br />dfp.setValue("市场人员", 35); <br /><br />dfp.setValue("开发人员", 20); <br /><br />dfp.setValue("后勤人员", 5); <br /><br />dfp.setValue("财务人员", 15); <br /><br />//Create JFreeChart object <br /><br />JFreeChart a =ChartFactory.createPieChart("CityInfoPort公司组织架构图",dfp, true, true, true); <br /><br />ChartFrame frame=new ChartFrame ("CityInfoPort公司组织架构图 ",a,true); <br /><br />frame.pack(); <br /><br />frame.setVisible(true); <br /><br />} <br /><br />} <br /><br />Refactor one <br /><br />/** <br /><br />* JfreeChartOne.java <br /><br />* author:longlong <br /><br />* May 31, 2007 <br /><br />*/ <br /><br />package com.ghg.java; <br /><br /><br /><br />import java.awt.Font; <br /><br />import javax.swing.JPanel; <br /><br />import org.jfree.chart.ChartFactory; <br /><br />import org.jfree.chart.ChartPanel; <br /><br />import org.jfree.chart.JFreeChart; <br /><br />import org.jfree.chart.plot.PiePlot; <br /><br />import org.jfree.chart.plot.PlotOrientation; <br /><br />import org.jfree.data.category.CategoryDataset; <br /><br />import org.jfree.data.category.DefaultCategoryDataset; <br /><br />import org.jfree.data.general.DefaultPieDataset; <br /><br />import org.jfree.data.general.PieDataset; <br /><br />import org.jfree.ui.ApplicationFrame; <br /><br /><br /><br />public class JfreeChartOne extends ApplicationFrame { <br /><br />private static final long serialVersionUID = 1L; <br /><br />public JfreeChartOne(String s) <br /><br />{ <br /><br />super(s); <br /><br />setContentPane(createJPanel()); <br /><br />} <br /><br />public static void main(String[] args) { <br /><br />JfreeChartOne one=new JfreeChartOne("CityInfoPort公司组织架构图"); <br /><br />one.pack(); <br /><br />one.setVisible(true); <br /><br />} <br /><br />//利用静态方法设定数据源(饼状图) <br /><br />public static PieDataset createPieDataset() { <br /><br />DefaultPieDataset defaultpiedataset = new DefaultPieDataset(); <br /><br />defaultpiedataset.setValue("管理人员", 10.02D); <br /><br />defaultpiedataset.setValue("市场人员", 20.23D); <br /><br />defaultpiedataset.setValue("开发人员", 60.02D); <br /><br />defaultpiedataset.setValue("OEM人员", 10.02D); <br /><br />defaultpiedataset.setValue("其他人员", 5.11D); <br /><br />return defaultpiedataset; <br /><br />} <br /><br />// 通过ChartFactory创建JFreeChart的实例 <br /><br />public static JFreeChart createJFreeChart(PieDataset p) <br /><br />{ <br /><br />JFreeChart a =ChartFactory.createPieChart("CityInfoPort公司组织架构图",p, true, true, true); <br /><br />PiePlot pie=(PiePlot )a.getPlot(); <br /><br />pie.setLabelFont(new Font("SansSerif",Font.BOLD,12)); <br /><br />pie.setNoDataMessage("No data available"); <br /><br />pie.setCircular(true); <br /><br />pie.setLabelGap(0.01D);//间距 <br /><br />return a; <br /><br />} <br /><br />public static JPanel createJPanel (){ <br /><br />JFreeChart jfreechart = createJFreeChart(createPieDataset()); <br /><br />return new ChartPanel(jfreechart); <br /><br />} <br /><br />} <br /><br />效果如图所示： <br /><br /><br />two：创建类别图 <br /><br />/** <br /><br />* JfreeChartTest.java <br /><br />* author:longlong <br /><br />* May 31, 2007 <br /><br />*/ <br /><br />package com.ghg.java; <br /><br /><br /><br />import org.jfree.data.category.DefaultCategoryDataset; <br /><br />import org.jfree.data.general.DefaultPieDataset; <br /><br />import org.jfree.chart.*; <br /><br />import org.jfree.chart.plot.PlotOrientation; <br /><br /><br /><br />public class JfreeChartTest { <br /><br />public static void main(String[] args) { <br /><br />// 创建类别图（Category）数据对象 <br /><br />DefaultCategoryDataset dataset = new DefaultCategoryDataset(); <br /><br />dataset.addValue(100, "北京", "苹果"); <br /><br />dataset.addValue(100, "上海", "苹果"); <br /><br />dataset.addValue(100, "广州", "苹果"); <br /><br />dataset.addValue(200, "北京", "梨子"); <br /><br />dataset.addValue(200, "上海", "梨子"); <br /><br />dataset.addValue(200, "广州", "梨子"); <br /><br />dataset.addValue(300, "北京", "葡萄"); <br /><br />dataset.addValue(300, "上海", "葡萄"); <br /><br />dataset.addValue(300, "广州", "葡萄"); <br /><br />dataset.addValue(400, "北京", "香蕉"); <br /><br />dataset.addValue(400, "上海", "香蕉"); <br /><br />dataset.addValue(400, "广州", "香蕉"); <br /><br />dataset.addValue(500, "北京", "荔枝"); <br /><br />dataset.addValue(500, "上海", "荔枝"); <br /><br />dataset.addValue(500, "广州", "荔枝"); <br /><br />JFreeChart chart=ChartFactory.createBarChart3D("水果产量图", "水果", "水果", dataset, PlotOrientation.VERTICAL, true, true, true); <br /><br />ChartFrame frame=new ChartFrame ("水果产量图 ",chart,true); <br /><br />frame.pack(); <br /><br />frame.setVisible(true); <br /><br />} <br /><br />} <br /><br />按照one的重构办法也可以对这个程序实现重构。 <br />当前位置：主页>技术资讯>JSP编程>文章内容 <br /><br />jFreeChart初探-JSP教程,资料/其他 <br />来源： 作者： 发布时间：2007-12-27 <br /><br /><br />//****************************************** <br />//* author:rautinee * <br />//* email:rautinee@21cn.com * <br />//* http://www.tryitsoft.com * <br />//*本文可自由传播使用，但请务必保留此信息 * <br />//****************************************** <br /><br />jfreechart也许对大家来说很陌生，她是一款免费的、功能强大的统计图生成工具，能够直接生成png,jpg等各式的文档 <br />为我们java项目的研发增加了一部利器。她的英文简介 <br />jfreechart is a free java class library for generating charts, including: <br />pie charts; <br />line charts and horizontal/vertical bar charts (regular and stacked, with optional 3d-effect); <br />xy plots and scatter plots; <br />time series, high/low/open/close charts and candle stick charts; <br />combination charts; <br />pareto charts; <br />gantt charts; <br />bubble charts; <br />wind plots, meter charts and symbol charts; <br /><br />正好我最近的一个项目用到她，于是就很粗略的看了一下，现在把他拿出来和大家分享，希望对大家的工作有所 <br />帮助。 <br /><br />本文主要是讲解她在jsp上面的应用。例子采用jsp+javabean结构实现 <br /><br />准备工作：首先我们需要什么？当然是jfreechart的package了，能够在她的官方网站上面找到下载链接 <br />http://www.jfree.org/jfreechart/，把包下下来，配置到tomcat当中，然后能够开始我们的jfreechart之旅 <br />了。 <br /><br />下面我要做的是个饼状统计图，首先建立javabean文档 <br /><br />文档名：tryitshow.java <br /><br />package com.tryit; <br /><br />import java.io.*; <br />import java.awt.insets; <br />import java.awt.font; <br />import java.io.printwriter; <br />import java.text.simpledateformat; <br />import java.util.iterator; <br />import java.util.locale; <br />import java.text.numberformat; <br />import javax.servlet.http.httpsession; <br />import org.jfree.data.*; <br />import org.jfree.chart.*; <br />import org.jfree.chart.axis.*; <br />import org.jfree.chart.renderer.verticalbarrenderer; <br />import org.jfree.chart.renderer.standardxyitemrenderer; <br />import org.jfree.chart.plot.*; <br />import org.jfree.chart.entity.*; <br />import org.jfree.chart.tooltips.*; <br />import org.jfree.chart.urls.*; <br />import org.jfree.chart.servlet.*; <br />import org.jfree.chart.texttitle; <br />import java.net.url; <br /><br />public class tryitshow <br />{ <br />public static string generatepiechart(string infostr, string titles,httpsession session, printwriter pw) <br />{ <br />string filename = null; <br />font font; <br /><br />try { <br />// 建立piedataset <br />defaultpiedataset data = new defaultpiedataset(); <br />string ss[]=infostr.split(","); <br />for (int n=0;n&lt;ss.length;n++) <br />{ <br />string sspart[]=ss[n].split("#"); <br />int tt=integer.parseint(sspart[1]); <br />string mm=sspart[0]; <br />data.setvalue(mm,tt); <br />} <br /><br />// 生成chart物件 <br />pieplot plot = new pieplot(data); <br />plot.setinsets(new insets(0, 5, 5, 5)); <br /><br />plot.settooltipgenerator(new standardpietooltipgenerator()); <br /><br />font=new font("黑体",font.center_baseline,20);//这个地方是配置统计图标题的字体和大小 <br /><br />jfreechart chart = new jfreechart("",jfreechart.default_title_font, plot, true); <br /><br />texttitle tt=new texttitle(titles); <br />tt.setfont(font); <br />chart.setbackgroundpaint(java.awt.color.white);//统计图片的底色 <br />chart.settitle(tt); <br /><br />// 把生成的文档写入到临时的目录中 <br />chartrenderinginfo info = new chartrenderinginfo(new standardentitycollection()); <br />filename = servletutilities.savechartaspng(chart, 500, 300, info, session); <br />//选择存储成png格式的文档，当然您也能够使用savechartasjpeg的方法生成jpg图片 <br /><br />// 把image map 写入到 printwriter <br />chartutilities.writeimagemap(pw, filename, info); <br />pw.flush(); <br />} <br />catch (exception ex) { <br />system.out.println("error:"+ex.getmessage()); <br />} <br />return filename; <br />} <br />} <br /><br /><br />接着是jsp文档 <br />&lt;%@ page contenttype="text/html;charset=gb2312"%> <br />&lt;%@ page import = "com.tryit.tryitshow" %> <br />&lt;%@ page import = "java.io.printwriter" %> <br />&lt;%@ page import = "java.text.simpledateformat" %> <br />&lt;%@ page import = "java.text.parseexception" %> <br />&lt;%@ page import = "java.util.arraylist" %> <br />&lt;%@ page import = "java.util.date" %> <br />&lt;%@ page import = "java.util.iterator" %> <br />&lt;%@ page import = "java.util.locale" %> <br />&lt;!doctype html public "-//w3c//dtd html 4.0 transitional//en"> <br />&lt;html> <br />&lt;head> <br />&lt;title> new document &lt;/title> <br />&lt;meta name="generator" content="editplus"> <br />&lt;meta name="author" content=""> <br />&lt;meta name="keywords" content=""> <br />&lt;meta name="description" content=""> <br />&lt;/head> <br />&lt;% <br />string filename = tryitshow.generatepiechart("本科#100,专科#200","人才学历信息统计",session, new printwriter(out)); <br /><br />string graphurl = request.getcontextpath() + "/servlet/displaychart?filename=" + filename; <br />%> <br />&lt;body> <br />&lt;img src="&lt;%= graphurl %>" width=500 height=300 border=0 usemap="#&lt;%= filename %>"> <br />&lt;/body> <br />&lt;/html> <br /><br />ok,大功告成，当然，您能够采用其他方式，比如您能够把dataset的数据配置在xml文档中，从xml文档读取 <br />统计数据中添加百分比等等，还能够选择生成柱状图、折线图等。 <br /><br />jfreechart更有很多其他的用法，希望大家能够多多交流。 <br /><br /><br />web.xml文档的配置 <br /><br />&lt;web-app> <br />&lt;servlet> <br />&lt;servlet-name>displaychart&lt;/servlet-name> <br />&lt;servlet-class>org.jfree.chart.servlet.displaychart&lt;/servlet-class> <br />&lt;/servlet> <br />&lt;servlet-mapping> <br />&lt;servlet-name>displaychart&lt;/servlet-name> <br />&lt;url-pattern>/servlet/displaychart&lt;/url-pattern> <br />&lt;/servlet-mapping> <br />&lt;/web-app> <br /><br /><br /><br />import java.awt.Insets; <br />import java.awt.Image; <br />import java.io.PrintWriter; <br />import java.text.SimpleDateFormat; <br />import java.util.Date; <br />import java.util.ArrayList; <br />import java.util.Iterator; <br />import java.util.Locale; <br />import java.text.NumberFormat; <br />import javax.servlet.http.HttpSession; <br />import org.jfree.data.*; <br />import org.jfree.chart.*; <br />import org.jfree.chart.axis.*; <br />import org.jfree.chart.renderer.VerticalBarRenderer; <br />import org.jfree.chart.renderer.StandardXYItemRenderer; <br />import org.jfree.chart.plot.*; <br />import org.jfree.chart.entity.*; <br />import org.jfree.chart.tooltips.*; <br />import org.jfree.chart.urls.*; <br />import org.jfree.chart.servlet.*; <br />import java.awt.Font; <br /><br />/** <br />* &lt;p>Title: &lt;/p> <br />* &lt;p>Description: &lt;/p> <br />* &lt;p>Copyright: Copyright (c) 2003&lt;/p> <br />* &lt;p>Company: &lt;/p> <br />* @author jagie <br />* @version 1.0 <br />*/ <br /><br />public class GSPieChart { <br />public static void main(String[] args) { <br />Long[] testData = { <br />new Long(10), new Long(20), new Long(30), new Long(40)}; <br />generatePieChart(testData, "", null, new PrintWriter(System.out), 580, 250); <br />} <br /><br />/** <br />* 生成图像文件 <br />* @param datas Long[]数组 <br />* @param targetUrl 点饼形图上的扇形，定向到的url <br />* @param session httpsession <br />* @param pw PrintWriter <br />* @param w 生成的图的宽度 <br />* @param h 生成的图的高度 <br />* @return 生成的图像文件的路径 <br />*/ <br /><br />public static String generatePieChart(Long[] datas, String targetUrl, <br />HttpSession session, PrintWriter pw, <br />int w, int h) { <br />String filename = null; <br />try { <br /><br />DefaultPieDataset data = new DefaultPieDataset(); <br />data.setValue("正常纳税人", datas[0]); <br />data.setValue("异常纳税人", datas[1]); <br />data.setValue("数据不全纳税人", datas[2]); <br />data.setValue("未处理纳税人", datas[3]); <br /><br />// Create the chart object <br />Pie3DPlot plot = new Pie3DPlot(data); <br />plot.setInsets(new Insets(0, 5, 5, 5)); <br />plot.setForegroundAlpha(0.6f); <br />plot.setSectionLabelType(plot.NO_LABELS); <br /><br />plot.setURLGenerator(new StandardPieURLGenerator(targetUrl, "type")); <br />plot.setToolTipGenerator(new StandardPieToolTipGenerator()); <br />JFreeChart chart = new JFreeChart( <br />"数据处理结果统计图", JFreeChart.DEFAULT_TITLE_FONT, plot, true); <br />chart.setTitle(new TextTitle( <br />"数据处理结果统计图", new Font("黑体", Font.BOLD, 15))); <br />StandardLegend sl = (StandardLegend) chart.getLegend(); <br />sl.setItemFont(new Font("黑体", Font.TRUETYPE_FONT, 12)); <br /><br />chart.setBackgroundPaint(new java.awt.Color(254, 254, 141)); <br /><br />//因为jfreechart把生成的png文件保存在系统的临时文件夹中，你需要在适当的 <br />//时候调用session.removeAttribute("JFreeChart_Deleter")，这样可以保证png文 <br />//件被删除掉 <br /><br />ChartRenderingInfo info = new ChartRenderingInfo(new <br />StandardEntityCollection()); <br />filename = ServletUtilities.saveChartAsPNG(chart, w, h, info, session); <br /><br />// Write the image map to the PrintWriter <br />ChartUtilities.writeImageMap(pw, filename, info); <br />pw.flush(); <br /><br />} <br />catch (Exception e) { <br />System.out.println("Exception - " + e.toString()); <br />e.printStackTrace(System.out); <br />filename = "public_error_500x300.png"; <br />} <br />return filename; <br />} <br />} <br />.........java代码................. <br /><br />&lt;% <br /><br />//以下部分为图象输出 <br />String targetUrl="../servlet/gov.gwssi.tax.nspg. <br />controlservlet.GSMainControlServlet?id="+sid; <br />Long[] datas={normals,new Long(totalAbnormal), <br />dataLacks,notProcesses}; <br />String filename=GSPieChart.generatePieChart <br />(datas,targetUrl,session,new PrintWriter(out),580,250); <br />String graphURL = request.getContextPath() + <br />"/servlet/DisplayChart?filename=" + filename; <br /><br />%> <br /><br />JFreeChart Hacking <br />来自于http://www.itepub.net/ <br />&lt;本文允许任意转载，请注明出处！最后一块骨头.2005-05-16> <br /><br />JFreeChart 是什么？我就不再重复介绍了，网上文章大把... <br />官方主页：http://www.jfree.org/jfreechart/index.html <br /><br />&lt;--本文以jfreechart-1.0.0-pre2版本为基准--> <br /><br />那么为什么要Hacking JFreeChart呢？ <br /><br />罪状一：中文Label显示模糊； <br />罪状二：无简体中文LocalizationBundle.properties文件； <br />罪状三：向下兼容性不好，官方说jdk1.2+，其实是jdk1.4+； <br />兼容问题A：另存菜单输出PNG文件只能运行于jdk1.4+； <br />兼容问题B：另存菜单不能输出JPEG格式图片； <br />兼容问题C：jdk1.3-环境下中文ToolTips不能正常显示； <br /><br />如果一定要加一条罪状的话：目前开源免费的chart项目无出其右； <br />十分感谢JFreeChart开发者的辛苦努力！虽然它现在还不完美。 <br /><br />Ok，下面为Hacking做一些准备工作... <br />1.下载jfreechart-1.0.0-pre2.zip解压； <br />2.将\解压目录\source\下的源码加入任意project并配置jdk&lib； <br />3.安装一个有批量文件查询/替换功能的工具，比如UtralEdit； <br /><br />&lt;本文允许任意转载，请注明出处！最后一块骨头.2005-05-16> <br /><br />Hacking Begin <br /><br />1.解决中文Label显示模糊问题 <br />原因分析：JFreeChart默认字体对中文的支持不完善； <br />解决步骤：搜索\解压目录\source\下含有"new Font("的文件； <br />发现JFreeChart默认字体为 <br />"foo" <br />"Serif" <br />"Dialog" <br />"SansSerif" <br />"Bitstream Vera Sans" <br />批量替换他们为任意中文字体（推荐"黑体"）； <br />当然你也可以把字体写入properties文件， <br />但这里介绍的是最简单的方法； <br />然后重新编译你修改过的文件，Ok，搞定！ <br /><br />2.无简体中文LocalizationBundle.properties文件 <br />org\jfree\chart\LocalizationBundle.properties <br />主要用来显示右键功能菜单的文字，下面我们来汉化： <br /><br />注意：LocalizationBundle.properties的编码不是Unicode， <br />简体中文要用GBK编码。 <br /><br />获得GBK编码的方法是： <br />cd ***\j2sdk1.*.*\bin <br />native2ascii -encoding GBK 1.txt 2.txt <br />注：1.txt放中文文本，2.txt输出GBK编码。 <br /><br /># org.jfree.chart.ChartPanel ResourceBundle properties file <br /># <br /># Changes (from 31-Aug-2003) <br /># -------------------------- <br /># 31-Aug-2003 : Initial version (AL); <br /># 16-May-2005 : Add GBK version (FinalBone); <br /># 16-May-2005 : Add JPG_Image_Files (FinalBone); <br /><br />#---------------EN---------------# <br />#Auto_Range=Auto Range <br />#All_Axes=Both Axes <br />#Chart_Properties=Chart Properties <br />#Copy=Copy <br />#Print...=Print... <br />#Save_as...=Save as... <br />#Properties...=Properties... <br />#PNG_Image_Files=PNG Image Files <br />#JPG_Image_Files=JPG Image Files <br />#Domain_Axis=Domain Axis <br />#Range_Axis=Range Axis <br />#Zoom_In=Zoom In <br />#Zoom_Out=Zoom Out <br /><br />#---------------GBK---------------# <br />Auto_Range=\u81ea\u52a8\u8c03\u6574 <br />All_Axes=\u6240\u6709\u5750\u6807\u8f74 <br />Chart_Properties=\u56fe\u8868\u5c5e\u6027 <br />Copy=\u590d\u5236 <br />Print...=\u6253\u5370... <br />Save_as...=\u53e6\u5b58\u4e3a... <br />Properties...=\u5c5e\u6027... <br />PNG_Image_Files=PNG\u56fe\u50cf <br />JPG_Image_Files=JPG\u56fe\u50cf <br />Domain_Axis=\u57df\u5750\u6807\u8f74 <br />Range_Axis=\u503c\u5750\u6807\u8f74 <br />Zoom_In=\u653e\u5927 <br />Zoom_Out=\u7f29\u5c0f <br /><br />另外还有两个同名文件，希望大家有时间也汉化一下。 <br />org\jfree\chart\ui\LocalizationBundle.properties <br />org\jfree\chart\plot\LocalizationBundle.properties <br /><br />3.兼容性问题 <br />a.PNG输出问题 b.无JPEG输出菜单 <br />原因分析：javax.imageio.ImageIO这个类只有jdk1.4+才有。 <br />解决步骤：1.打开org.jfree.chart.ChartPanel， <br />查看doSaveAs()方法，了解其结构； <br />2.改写doSaveAs()方法，重新编译； <br />3.如果运行环境是jdk1.3- <br />打开org.jfree.chart.encoders.SunPNGEncoderAdapter <br />注释掉javax.imageio.ImageIO，重新编译。 <br /><br /><br />/** <br />* Updated by FinalBone 2005-5-16 PNG --> JPEG <br />* <br />* Opens a file chooser and gives the user an opportunity <br />* to save the chart in JPEG format. <br />* <br />* @throws IOException if there is an I/O error. <br />*/ <br />public void doSaveAs() throws IOException { <br /><br />JFileChooser fileChooser = new JFileChooser(); <br />ExtensionFileFilter filter = new ExtensionFileFilter( <br />localizationResources.getString("JPG_Image_Files"), ".jpg" <br />); <br />fileChooser.addChoosableFileFilter(filter); <br /><br />int option = fileChooser.showSaveDialog(this); <br />if (option == JFileChooser.APPROVE_OPTION) { <br />String filename = fileChooser.getSelectedFile().getPath(); <br />if (isEnforceFileExtensions()) { <br />if (!filename.endsWith(".jpg")) { <br />filename = filename + ".jpg"; <br />} <br />} <br />ChartUtilities.saveChartAsJPEG( <br />new File(filename), this.chart, getWidth(), getHeight() <br />); <br />} <br /><br />} <br /><br />c.中文ToolTips不能正常显示（显示为小方框） <br />原因分析：相关字体找不到。 <br />解决步骤：1.打开org.jfree.chart.block.LabelBlock <br />查看其构造函数public LabelBlock(String label)； <br />2.修改构造函数的字体定义，重新编译。 <br /><br />/** <br />* Creates a new label block. <br />* <br />* @param label the label. <br />*/ <br />public LabelBlock(String label) { <br />/** <br />* Updated by FinalBone 2005-05-16 <br />* "Bitstream Vera Sans" --> "黑体" <br />* For Chinese-Simplified ToolTips <br />* JDK 1.3- Environment <br />*/ <br />this(label, new Font("黑体", Font.PLAIN, 11)); <br />} <br /><br />Hacking End <br /><br />&lt;本文允许任意转载，请注明出处！最后一块骨头.2005-05-16> <br /><br />这时的 JFreeChart 才是真正jdk1.2+兼容，完美支持中文。 <br /><br />希望下一版本的 JFreeChart 的字体定义写入properties文件， <br />并且不同路经下的properties文件最好不要重名。 <br /><br />本人接触 JFreeChart 刚刚几天，错漏难免，请多多指正！ <br /><br />&lt;本文允许任意转载，请注明出处！最后一块骨头.2005-05-16>
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/197096#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 26 May 2008 15:35:49 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/197096</link>
        <guid>http://zxjava.javaeye.com/blog/197096</guid>
      </item>
      <item>
        <title>java中文件操作大全</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/193929" style="color:red;">http://zxjava.javaeye.com/blog/193929</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          一.获得控制台用户输入的信息<br /><br />/** *//**获得控制台用户输入的信息<br />     * @return<br />     * @throws IOException<br />     */<br />    public String getInputMessage() throws IOException...{<br />        System.out.println("请输入您的命令∶");<br />        byte buffer[]=new byte[1024];<br />        int count=System.in.read(buffer);<br />        char[] ch=new char[count-2];//最后两位为结束符，删去不要<br />        for(int i=0;i&lt;count-2;i++)<br />            ch[i]=(char)buffer[i];<br />        String str=new String(ch);<br />        return str;<br />    }<br />可以返回用户输入的信息，不足之处在于不支持中文输入，有待进一步改进。<br /><br />二.复制文件<br /><br />1.以文件流的方式复制文件<br /><br />/** *//**以文件流的方式复制文件<br />     * @param src 文件源目录<br />     * @param dest 文件目的目录<br />     * @throws IOException  <br />     */<br />    public void copyFile(String src,String dest) throws IOException...{<br />        FileInputStream in=new FileInputStream(src);<br />        File file=new File(dest);<br />        if(!file.exists())<br />            file.createNewFile();<br />        FileOutputStream out=new FileOutputStream(file);<br />        int c;<br />        byte buffer[]=new byte[1024];<br />        while((c=in.read(buffer))!=-1)...{<br />            for(int i=0;i&lt;c;i++)<br />                out.write(buffer[i]);        <br />        }<br />        in.close();<br />        out.close();<br />    }<br />该方法经过测试，支持中文处理，并且可以复制多种类型，比如txt，xml，jpg，doc等多种格式<br /><br />三.写文件<br /><br />1.利用PrintStream写文件<br /><br />/** *//**<br />     * 文件输出示例<br />     */<br />    public void PrintStreamDemo()...{<br />        try ...{<br />            FileOutputStream out=new FileOutputStream("D:/test.txt");<br />            PrintStream p=new PrintStream(out);<br />            for(int i=0;i&lt;10;i++)<br />                p.println("This is "+i+" line");<br />        } catch (FileNotFoundException e) ...{<br />            e.printStackTrace();<br />        }<br />    }<br />2.利用StringBuffer写文件<br /><br />public void StringBufferDemo() throws IOException......{<br />        File file=new File("/root/sms.log");<br />        if(!file.exists())<br />            file.createNewFile();<br />        FileOutputStream out=new FileOutputStream(file,true);        <br />        for(int i=0;i&lt;10000;i++)......{<br />            StringBuffer sb=new StringBuffer();<br />            sb.append("这是第"+i+"行:前面介绍的各种方法都不关用,为什么总是奇怪的问题 ");<br />            out.write(sb.toString().getBytes("utf-8"));<br />        }        <br />        out.close();<br />    }<br />该方法可以设定使用何种编码，有效解决中文问题。<br /><br />四.文件重命名<br /><br /><br />    /** *//**文件重命名<br />     * @param path 文件目录<br />     * @param oldname  原来的文件名<br />     * @param newname 新文件名<br />     */<br />    public void renameFile(String path,String oldname,String newname)...{<br />        if(!oldname.equals(newname))...{//新的文件名和以前文件名不同时,才有必要进行重命名<br />            File oldfile=new File(path+"/"+oldname);<br />            File newfile=new File(path+"/"+newname);<br />            if(newfile.exists())//若在该目录下已经有一个文件和新文件名相同，则不允许重命名<br />                System.out.println(newname+"已经存在！");<br />            else...{<br />                oldfile.renameTo(newfile);<br />            } <br />        }         <br />    }五.转移文件目录 <br /> <br /><br />转移文件目录不等同于复制文件，复制文件是复制后两个目录都存在该文件，而转移文件目录则是转移后，只有新目录中存在该文件。 <br /><br />    /** *//**转移文件目录<br />     * @param filename 文件名<br />     * @param oldpath 旧目录<br />     * @param newpath 新目录<br />     * @param cover 若新目录下存在和转移文件具有相同文件名的文件时，是否覆盖新目录下文件，cover=true将会覆盖原文件，否则不操作<br />     */<br />    public void changeDirectory(String filename,String oldpath,String newpath,boolean cover)...{<br />        if(!oldpath.equals(newpath))...{<br />            File oldfile=new File(oldpath+"/"+filename);<br />            File newfile=new File(newpath+"/"+filename);<br />            if(newfile.exists())...{//若在待转移目录下，已经存在待转移文件<br />                if(cover)//覆盖<br />                    oldfile.renameTo(newfile);<br />                else<br />                    System.out.println("在新目录下已经存在："+filename);<br />            }<br />            else...{<br />                oldfile.renameTo(newfile);<br />            }<br />        }       <br />    }<br /><br /> <br /><br />六.读文件<br /><br />1.利用FileInputStream读取文件<br /><br /><br />    /** *//**读文件<br />     * @param path<br />     * @return<br />     * @throws IOException<br />     */<br />    public String FileInputStreamDemo(String path) throws IOException...{<br />        File file=new File(path);<br />        if(!file.exists()||file.isDirectory())<br />            throw new FileNotFoundException();<br />        FileInputStream fis=new FileInputStream(file);<br />        byte[] buf = new byte[1024];<br />        StringBuffer sb=new StringBuffer();<br />        while((fis.read(buf))!=-1)...{<br />            sb.append(new String(buf));    <br />            buf=new byte[1024];//重新生成，避免和上次读取的数据重复<br />        }<br />        return sb.toString();<br />    }<br /><br /><br />2.利用BufferedReader读取<br /><br />在IO操作，利用BufferedReader和BufferedWriter效率会更高一点 <br /><br />    /** *//**读文件<br />     * @param path<br />     * @return<br />     * @throws IOException<br />     */<br />    public String BufferedReaderDemo(String path) throws IOException...{<br />        File file=new File(path);<br />        if(!file.exists()||file.isDirectory())<br />            throw new FileNotFoundException();<br />        BufferedReader br=new BufferedReader(new FileReader(file));<br />        String temp=null;<br />        StringBuffer sb=new StringBuffer();<br />        temp=br.readLine();<br />        while(temp!=null)...{<br />            sb.append(temp+" ");<br />            temp=br.readLine();<br />        }<br />        return sb.toString();<br />    }<br /><br /><br />3.利用dom4j读取xml文件 <br /><br />    /** *//**从目录中读取xml文件<br />     * @param path 文件目录<br />     * @return<br />     * @throws DocumentException<br />     * @throws IOException<br />     */<br />    public Document readXml(String path) throws DocumentException, IOException...{<br />        File file=new File(path);<br />        BufferedReader bufferedreader = new BufferedReader(new FileReader(file));<br />        SAXReader saxreader = new SAXReader();<br />        Document document = (Document)saxreader.read(bufferedreader);<br />        bufferedreader.close();<br />        return document;<br />    }<br /> <br /><br />七.创建文件(文件夹)<br /><br />1.创建文件夹  /** *//**创建文件夹<br />     * @param path  目录<br />     */<br />    public void createDir(String path)...{<br />        File dir=new File(path);<br />        if(!dir.exists())<br />            dir.mkdir();<br />    }<br />2.创建新文件 /** *//**创建新文件<br />     * @param path 目录<br />     * @param filename 文件名<br />     * @throws IOException<br />     */<br />    public void createFile(String path,String filename) throws IOException...{<br />        File file=new File(path+"/"+filename);<br />        if(!file.exists())<br />            file.createNewFile();<br />    }<br />八.删除文件(目录)<br /><br />1.删除文件     /** *//**删除文件<br />     * @param path 目录<br />     * @param filename 文件名<br />     */<br />    public void delFile(String path,String filename)...{<br />        File file=new File(path+"/"+filename);<br />        if(file.exists()&&file.isFile())<br />            file.delete();<br />    }<br />2.删除目录<br />要利用File类的delete()方法删除目录时，必须保证该目录下没有文件或者子目录，否则删除失败，因此在实际应用中，我们要删除目录，必须利用递归删除该目录下的所有子目录和文件，然后再删除该目录。  /** *//**递归删除文件夹<br />     * @param path<br />     */<br />    public void delDir(String path)...{<br />        File dir=new File(path);<br />        if(dir.exists())...{<br />            File[] tmp=dir.listFiles();<br />            for(int i=0;i&lt;tmp.length;i++)...{<br />                if(tmp[i].isDirectory())...{<br />                    delDir(path+"/"+tmp[i].getName());<br />                }<br />                else...{<br />                    tmp[i].delete();<br />                }<br />            }<br />            dir.delete();<br />        }<br />    }
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/193929#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 18:17:01 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/193929</link>
        <guid>http://zxjava.javaeye.com/blog/193929</guid>
      </item>
      <item>
        <title>javascript 动态创建表格：新增、删除行和单元格</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/193926" style="color:red;">http://zxjava.javaeye.com/blog/193926</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          利用js来动态创建表格有两种格式，appendChild()和insertRow、insertCell()。两种方式其实差不多，但第一种有可能在IE上有问题，所以推荐大家使用第二种了，直接说吧。<br /><br />1、inserRow()和insertCell()函数<br /><br />insertRow()函数可以带参数，形式如下：<br /><br />insertRow(index)：index从0开始<br /><br />这个函数将新行添加到index的那一行前，比如insertRow(0),是将新行添加到第一行之前。默认的insertRow()函数相当于insertRow(-1)，将新行添加到表的最后。一般我们在使用的时候都是：objTable.insertRow(objTable.rows.length).就是为表格objTable在最后新增一行。<br /><br />insertCell()和insertRow的用法相同，这里就不再说了。<br /><br />2、deleteRow()和deleteCell()方法<br /><br />deleteRow()函数可以带参数，形式如下：deleteRow(index)：index从0开始<br /><br />和上面两个方法差不多的意思，就是删除指定位置的行和单元格。要传入的参数：Index是行在表格中的位置，可以下面的方法取得然后去删除：<br /><br />var row=document.getElementById("行的Id");<br />var index=row.rowIndex;//有这个属性，嘿嘿<br />objTable.deleteRow(index);<br /><br />在使用过程中我碰到的一个问题跟大家说一下，就是删除表格的行的时候，如果你删除了某一行，那么表格行数是马上就变化的，所以如果你要删除表格的所有行，下面的代码是错误的：<br /><br />function clearRow(){ <br />   objTable= document.getElementById("myTable"); <br />      <br />   for( var i=1; i&lt;objTable.rows.length ; i++ )<br />   {<br />   tblObj.deleteRow(i);    <br />      }<br />}<br /><br />这段代码要删除原来的表格的表体，有两个问题。首先不能是deleteRow(i)，应该是deleteRow(1)。因为在删除表格行的时候，表格的行数在变化，这就是问题的关键，rows.length总是在变小，删除的行数总是会比预想的要少一半，所以正确的删除表格的行的代码应该这样：<br /><br />function clearRow(){ <br />   objTable= document.getElementById("myTable"); <br />   var length= objTable.rows.length ;  <br />   for( var i=1; i&lt;length; i++ )<br />   {<br />       objTable.deleteRow(i);    <br />      }<br />}<br /><br />3、动态设置单元格与行的属性<br /><br />A、采用setAttribute()方法，格式如下：setAttribute(属性，属性值)<br /><br />说明：这个方法几乎所有的DOM对象都可以使用，第一个参数是属性的名称，比如说：border，第二个就是你要为border设置的值了，比如：1<br /><br />var objMyTable = document.getElementById("myTable");<br /><br />objMyTable.setAttribute("border",1);//为表格设置边框为1<br /><br />其他的比如你要为一个TD设置高度，同样先取得这个TD对象，然后使用setAttribute()方法<br /><br />var objCell = document.getElementById("myCell");<br /><br />objCell.setAttribute("height",24);//为单元格设置高度为24<br /><br />在使用的时候遇到一个设置样式的问题，不能用setAttribute("class","inputbox2");而应该使用setAttribute("className","inputbox2")，呵呵，其他我估计也有同样的问题，有些属性和我们在DW里面的不一致，呵呵，大家自己摸索吧。<br /><br />B、直接赋值<br /><br />var objMyTable = document.getElementById("myTable");<br /><br />objMyTable.border=1;//为表格设置边框为1<br /><br />这个方法也全部适用，呵呵。<br /><br />4、创建表格<br /><br />了解了行&lt;tr>与单元格&lt;td>的增删那就可以创建表格了。<br /><br />第一步：你需要有一个你去动态变化的表格，我这里讲的是已经存在页面的表格，我们要设置一个id:myTable<br /><br />var objMyTable = document.getElementById("myTable");<br /><br />第二步：创建行与列的对象<br /><br />var index = objMyTable.rows.length-1;<br />var nextRow = objMyTable.insertRow(index);//要新增的行，我这里是从倒数第二行开始新增的<br /><br />//单元格箱号<br />var newCellCartonNo = nextRow.insertCell();<br />var cartonNoName = "IptCartonNo";<br />newCellCartonNo.innerHTML = "&nbsp;&lt;input type='text' size='5' name="+cartonNoName+" id="+cartonNoName+" value=''>";<br />newCellCartonNo.setAttribute("className","tablerdd");<br /><br />这样就搞定了，可以简单的创建一个行和列了。具体的代码我贴在下面。只是很简单的例子，不过方法就大概是上面的了，呵呵，慢慢摸索吧~<br /><br />&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <br />&lt;html xmlns="http://www.w3.org/1999/xhtml"> <br />&lt;head> <br />&lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <br />&lt;title>蓝光-BlueShine&lt;/title> <br />&lt;script language="JavaScript"> <br />var Count=false,NO=1; <br />function addRow(){ <br />Count=!Count; <br />//添加一行 <br />var newTr = testTbl.insertRow(testTbl.rows.length); <br />//添加两列 <br />var newTd0 = newTr.insertCell(); <br />var newTd1 = newTr.insertCell(); <br />var newTd2 = newTr.insertCell(); <br />//设置列内容和属性 <br />if(Count){newTr.style.background="#FFE1FF";} <br />else {newTr.style.background="#FFEFD5";} <br />newTd0.innerHTML = '&lt;input type=checkbox id="box4">'; <br />NO++ <br />newTd1.innerText="第"+ NO+"行"; <br />} <br />&lt;/script> <br />&lt;/head><br /><br />&lt;body> <br />&lt;table width="399" border=0 cellspacing="1" id="testTbl" style="font-size:14px;" > <br />&lt;tr bgcolor="#FFEFD5"> <br />&lt;td width=6%>&lt;input type=checkbox id="box1">&lt;/td> <br />&lt;td >第1行&lt;/td> <br />&lt;td > &lt;/td> <br />&lt;/tr> <br />&lt;/table> <br />&lt;label> <br />&lt;input type="button" value="插入行" onclick="addRow()" /> <br />&lt;/label> <br />&lt;/body> <br />&lt;/html><br /><br /><br />5、appendChild()方法<br /><br />我就直接贴代码了，大家去研究，时间紧，哈哈，见谅~<br /><br />&lt;html><br />&lt;head><br />&lt;title>My Test Page&lt;/title><br />&lt;script type="text/javascript"><br />&lt;!--<br />var textNumber = 1;<br />function addTextBox(form, afterElement) {<br />// Increment the textbox number<br />textNumber++;<br />// Create the label<br />var label = document.createElement("label");<br />// Create the textbox<br />var textField = document.createElement("input");<br />textField.setAttribute("type","text");<br />textField.setAttribute("name","txt"+textNumber);<br />textField.setAttribute("id","txt"+textNumber);<br />// Add the label's text<br />label.appendChild(document.createTextNode("Text Box #"+textNumber+": "));<br />// Put the textbox inside<br />label.appendChild(textField);<br />// Add it all to the form<br />form.insertBefore(label,afterElement);<br />return false;<br />}<br />function removeTextBox(form) {<br />if (textNumber > 1) { // If there's more than one text box<br />    // Remove the last one added<br />    form.removeChild(document.getElementById("txt"+textNumber).parentNode);<br />    textNumber--;<br />}<br />}<br />//--><br />&lt;/script><br />&lt;style type="text/css"><br />&lt;!--<br />label {<br />display:block;<br />margin:.25em 0em;<br />}<br />--><br />&lt;/style><br />&lt;/head><br />&lt;body><br />&lt;form id="myForm" method="get" action="./" /><br />&lt;label>Text Box #1: &lt;input type="text" name="txt1" id="txt1" />&lt;/label><br />&lt;p><br />    &lt;input type="button" value="Add Textbox" onclick="addTextBox(this.form,this.parentNode)" /><br />    &lt;input type="button" value="Remove Textbox" onclick="removeTextBox(this.form)" /><br />&lt;/p><br />&lt;p>&lt;input type="Submit" value="Submit" />&lt;/p><br />&lt;/form><br />&lt;/body><br />&lt;/html><br /><br />&lt;html><br />&lt;head><br />&lt;title>My Test Page&lt;/title><br />&lt;script type="text/javascript"><br />&lt;!--<br />var textNumber = 1;<br />function addTextBox(form, afterElement) {<br />// Increment the textbox number<br />textNumber++;<br />// Create the label<br />var label = document.createElement("label");<br />// Create the textbox<br />var textField = document.createElement("input");<br />textField.setAttribute("type","text");<br />textField.setAttribute("name","txt"+textNumber);<br />textField.setAttribute("id","txt"+textNumber);<br />// Add the label's text<br />label.appendChild(document.createTextNode("Text Box #"+textNumber+": "));<br />// Put the textbox inside<br />label.appendChild(textField);<br />// Add it all to the form<br />form.insertBefore(label,afterElement);<br />return false;<br />}<br />function removeTextBox(form) {<br />if (textNumber > 1) { // If there's more than one text box<br />    // Remove the last one added<br />    form.removeChild(document.getElementById("txt"+textNumber).parentNode);<br />    textNumber--;<br />}<br />}<br />//--><br />&lt;/script><br />&lt;style type="text/css"><br />&lt;!--<br />label {<br />display:block;<br />margin:.25em 0em;<br />}<br />--><br />&lt;/style><br />&lt;/head><br />&lt;body><br />&lt;form id="myForm" method="get" action="./" /><br />&lt;label>Text Box #1: &lt;input type="text" name="txt1" id="txt1" />&lt;/label><br />&lt;p><br />    &lt;input type="button" value="Add Textbox" onclick="addTextBox(this.form,this.parentNode)" /><br />    &lt;input type="button" value="Remove Textbox" onclick="removeTextBox(this.form)" /><br />&lt;/p><br />&lt;p>&lt;input type="Submit" value="Submit" />&lt;/p><br />&lt;/form><br />&lt;/body><br />&lt;/html>
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/193926#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 17:56:19 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/193926</link>
        <guid>http://zxjava.javaeye.com/blog/193926</guid>
      </item>
      <item>
        <title>dwr中的util.js应用</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/193912" style="color:red;">http://zxjava.javaeye.com/blog/193912</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          util.js包含一些有用的函数function,用于在客户端页面调用，它可以和dwr分开，独立营用于你的系统中。 <br />主要功能如下： <br />1、$() 获得页面参数值 <br />2、addOptions and removeAllOptions 初始化下拉框 <br />3、addRows and removeAllRows 填充表格 <br />4、getText 取得text属性值 <br />5、getValue 取得form表单值 <br />6、getValues 取得form多个值 <br />7、onReturn   <br />8、selectRange <br />9、setValue <br />10、setValues <br />11、toDescriptiveString <br />12、useLoadingMessage <br />13、Submission box <br />*************************************************************************************** <br />////////////////////////////////////////////////////////////////////////////////////// <br />**************************************************************************************** <br />1、$()函数 <br />IE5.0 不支持 <br />$ = document.getElementById <br />取得form表单值 <br />var name = $("name"); <br />*************************************************************************************** <br />////////////////////////////////////////////////////////////////////////////////////// <br />**************************************************************************************** <br />2、用于填充 select 下拉框 option <br />a、如果你想在更新select 时，想保存原来的数据，即在原来的select中添加新的option： <br />     var sel = DWRUtil.getValue(id); <br />     DWRUtil.removeAllOptions(id); <br />     DWRUtil.addOptions(id,...); <br />     DWRUtil.setValue(id,sel); <br />     demo:比如你想添加一个option：“--请选择--” <br />    DWRUtil.addOptions(id,["--请选择--"]);     <br />    DWRUtil.addOptions()有5中方式： <br />    @ Simple Array Example: 简单数组 <br />      例如: <br />      Array array = new Array[ 'Africa', 'America', 'Asia', 'Australasia', 'Europe' ]； <br />      DWRUtil.addOptions("demo1",array); <br />    @ Simple Object Array Example 简单数组,元素为beans <br />      这种情况下,你需要指定要显示 beans 的 property 以及 对应的 bean 值 <br />      例如: <br />       public class Person { <br />     private String name; <br />     private Integer id; <br />     pirvate String address; <br />     public void set(){……} <br />     public String get(){……} <br />       } <br />       DWRUtil.addOptions("demo2",array,'id','name'); <br />       其中id指向及bean的id属性，在optiong中对应value，name指向bean的name属性，对应下拉框中显示的哪个值. <br />     @ Advanced Object Array Example 基本同上 <br />    DWRUtil.addOptions( "demo3", <br />                [{ name:'Africa', id:'AF' }, <br />                 { name:'America', id:'AM' }, <br />                 { name:'Asia', id:'AS' }, <br />                 { name:'Australasia', id:'AU' }, <br />                 { name:'Europe', id:'EU' } <br />        ],'id','name'); <br />     @ Map Example 用制定的map来填充 options: <br />       如果 server 返回 Map,呢么这样处理即可： <br />       DWRUtil.addOptions( "demo3",map); <br />       其中 value 对应 map keys，text 对应 map values； <br />     @ &lt;ul> and &lt;ol> list editing <br />       DWRUtil.addOptions() 函数不但可以填出select,开可以填出&lt;ul>和&lt;ol>这样的heml元素 <br />*************************************************************************************** <br />////////////////////////////////////////////////////////////////////////////////////// <br />**************************************************************************************** <br />3、addRows and removeAllRows 填充表格 <br />   DWR 提供2个函数来操作 table； <br />   ---------------------------- <br />   DWRUtil.addRows(); 添加行 <br />   ---------------------------- <br />   DWRUtil.removeAllRows(id); 删除指定id的table <br />   ---------------------------- <br />   下面着重看一下 addRows() 函数： <br />   DWRUtil.addRows(id, array, cellfuncs, [options]); <br />    其中id 对应 table 的 id(更适合tbodye，推荐使用 tbodye) <br />    array 是server端服务器的返回值，比如list，map等等 <br />    cellfuncs 及用返回值来天春表格 <br />    [options] 用来设置表格样式，它有2个内部函数来设置单元格样式(rowCreator、cellCreator)。 <br />    比如: server端返回list，而list中存放的是下面这个 bean： <br />        public class Person { <br />     private String name; <br />     private Integer id; <br />     pirvate String address; <br />     public void set(){……} <br />     public String get(){……} <br />       } <br />    下面用 DWRUtil.addRows(); <br />   /**************************************************************************************/ <br />   /*************************************************************/ <br />   /**************************************************************************************/ <br />   function userList(data){ <br />    //var delButton = "&lt;input type='button'/>"; <br />    //var editButton = "&lt;input type='button'/>"; <br />    var cellfuncs = [ <br />        function(data){return data.id;}, <br />        function(data){return data.userName;}, <br />        function(data){return data.userTrueName;}, <br />        function(data){return data.birthday;}, <br />        function(data){ <br />            var idd = data.id; <br />            var delButton = document.createElement("&lt;INPUT TYPE='button' onclick='delPerson("+ idd +")'>"); <br />            delButton.setAttribute("id","delete"); <br />            delButton.setAttribute("value","delete"); <br />            return delButton; <br />        }, <br />        function(data){ <br />            var idd = data.id; <br />            var editButton = document.createElement("&lt;INPUT TYPE='button' onclick='editPerson("+ idd +")'>"); <br />            editButton.setAttribute("name","edit"); <br />            editButton.setAttribute("value","edit");             <br />            return editButton; <br />        } <br />    ]; <br />    DWRUtil.removeAllRows('tabId');     <br />    DWRUtil.addRows('tabId', data,cellfuncs,{ <br />    rowCreator:function(options) { <br />        var row = document.createElement("tr"); <br />        var index = options.rowIndex * 50; <br />        row.setAttribute("id",options.rowData.id); <br />        row.style.collapse = "separate"; <br />        row.style.color = "rgb(" + index + ",0,0)"; <br />        return row; <br />      }, <br />      cellCreator:function(options) { <br />        var td = document.createElement("td"); <br />        var index = 255 - (options.rowIndex * 50); <br />        //td.style.backgroundColor = "rgb(" + index + ",255,255)"; <br />        td.style.backgroundColor = "menu"; <br />        td.style.fontWeight = "bold"; <br />        td.style.align = "center"; <br />        return td; <br />      }         <br />    }); <br />    document.getElementById("bt").style.display = "none"; <br />     } <br />     待续………………………………………… <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   4、getText 取得text属性值 <br />      DWRUtil.getText(id): 用来获得 option 中的文本 <br />      比如： <br />       &lt;select id="select"> <br />    &lt;option value="1"> 苹果 &lt;/option> <br />    &lt;option value="2" select> 香蕉 &lt;/option> <br />    &lt;option value="3"> 鸭梨 &lt;/option> <br />       &lt;/select> <br />      调用 DWRUtil.getText("select"); 将返回 "香蕉" 字段； <br />      DWRUtil.getText(id)；仅仅是用来获得 select 文本值，其他不适用。 <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   5、DWRUtil.getValue(id): 用来获得 form 表单值 <br />      有如下几种情况： <br />          Text area (id="textarea"): DWRUtil.getValue("textarea")将返回 Text area的值; <br />      Selection list (id="select"): DWRUtil.getValue("select") 将返回 Selection list 的值; <br />      Text input (id="text"): DWRUtil.getValue("text") 将返回 Text input 的值; <br />      Password input (id="password"): DWRUtil.getValue("text") 将返回 Password input 的值; <br />      Form button (id="formbutton"): DWRUtil.getValue("formbutton") 将返回 Form button 的值; <br />      Fancy button (id="button"): DWRUtil.getValue("formbutton") 将返回 Fancy button 的值; <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   6、getValues 取得form多个值 <br />      批量获得页面表单的值,组合成数组的形式,返回 name/value; <br />      例如: form(): <br />       &lt;input type="textarea" id="textarea" value="1111"/> <br />       &lt;input type="text" id="text" value="2222"/> <br />       &lt;input type="password" id= "password" value="3333"/> <br />       &lt;select id="select"> <br />    &lt;option value="1"> 苹果 &lt;/option> <br />    &lt;option value="4444" select> 香蕉 &lt;/option> <br />    &lt;option value="3"> 鸭梨 &lt;/option> <br />       &lt;/select> <br />       &lt;input type="button" id="button" value="5555"/> <br />      那么: DWRUtil.getValues({textarea:null,select:null,text:null,password:null,button:null}) <br />      将返回 ^^^^^^^^^^^^^^^^{textarea:1111,select:4444,text:2222,password:3333,button:5555} <br />     <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   7、DWRUtil.onReturn 防止当在文本框中输入后，直接按回车就提交表单。 <br />     &lt;input type="text" onkeypress="DWRUtil.onReturn(event, submitFunction)"/> <br />     &lt;input type="button" onclick="submitFunction()"/> <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   8、DWRUtil.selectRange(ele, start, end); <br />      在一个input box里选一个范围 <br />      DWRUtil.selectRange("sel-test", $("start").value, $("end").value); <br />      比如:&lt;input type="text" id="sel-test" value="012345678901234567890"> <br />      DWRUtil.selectRange("sel-test", 2, 15); 结果 文本框中的值"2345678901234"将被选中' <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   /**************************************************************************************/ <br />   9、DWRUtil.setValue(id,value); <br />      为指定的id元素,设置一个新值; <br />   /**************************************************************************************/ <br />   10、DWRUtil.setValues({   <br />    name: "fzfx88", <br />    password: "1234567890" <br />    } <br />       ); 同上,批量更新表单值. <br />   /**************************************************************************************/ <br />   11、DWRUtil.toDescriptiveString() <br />   带debug信息的toString，第一个为将要debug的对象，第二个参数为处理等级。等级如下： <br />    0: Single line of debug 单行调试   <br />    1: Multi-line debug that does not dig into child objects 不分析子元素的多行调试   <br />    2: Multi-line debug that digs into the 2nd layer of child objects 最多分析到第二层子元素的多行调试 <br />    &lt;input type="text" id="text"> <br />    DWRUtil。toDescriptiveString("text",0); <br />   /**************************************************************************************/ <br />   12、DWRUtil.useLoadingMessage(); <br />    当发出ajax请求后,页面显示的提示等待信息; <br />    function searchUser(){ <br />    var loadinfo = "loading....." <br />    try{ <br />        regUser.queryAllUser(userList); <br />        DWRUtil.useLoadingMessage(loadinfo);         <br />    }catch(e){ <br />    } <br />    } <br />    /**************************************************************************************/
          <br/>
          <span style="color:red;">
            <a href="http://zxjava.javaeye.com/blog/193912#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 17:17:20 +0800</pubDate>
        <link>http://zxjava.javaeye.com/blog/193912</link>
        <guid>http://zxjava.javaeye.com/blog/193912</guid>
      </item>
      <item>
        <title>Ecside 基于数据库端分页——AbstractQueryForPagedListAction</title>
        <author>zxjava</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://zxjava.javaeye.com">zxjava</a>&nbsp;
          链接：<a href="http://zxjava.javaeye.com/blog/191776" style="color:red;">http://zxjava.javaeye.com/blog/191776</a>&nbsp;
          发表时间: 2008年05月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          此类是基于iBatis数据库端访问组件的抽象Action类<br />只需继承该Action实现3个方法即<br />==========================================<br /><br />import java.io.IOException;<br />import java.math.BigDecimal;<br />import java.sql.SQLException;<br />import java.util.HashMap;<br />import java.util.List;<br />import java.util.Map;<br /><br />import javax.servlet.ServletException;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;<br /><br />import org.apache.log4j.Logger;<br />import org.apache.struts.action.Action;<br />import org.apache.struts.action.ActionForm;<br />import org.apache.struts.action.ActionForward;<br />import org.apache.struts.action.ActionMapping;<br />import org.ecside.table.limit.Limit;<br />import org.ecside.table.limit.Sort;<br />import org.ecside.util.RequestUtils;<br /><br />import com.fp.zyyw.util.SpringHelper;<br />import com.ibatis.sqlmap.client.SqlMapClient;<br /><br />public abstract class AbstractQueryForPagedListAction extends Action {<br /><br />	int DEFAULT_PAGESIZE = 20;<br /><br />	protected String sqlMapStringForList = null;<br /><br />	protected String sqlMap