??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲AV成人片色在线观看高潮,亚洲AV日韩综合一区尤物,亚洲AV无码之日韩精品http://m.tkk7.com/hk2000c/archive/2008/04/12/192305.htmlhk2000chk2000cFri, 11 Apr 2008 17:37:00 GMThttp://m.tkk7.com/hk2000c/archive/2008/04/12/192305.htmlhttp://m.tkk7.com/hk2000c/comments/192305.htmlhttp://m.tkk7.com/hk2000c/archive/2008/04/12/192305.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/192305.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/192305.html1.1 JMS与ActiveMQҎ?nbsp; 

   JMS始终在JavaEE五花八门的协议里QWebService满天飞的时候占一位置Q是因ؓQ?/p>

  • 它可以把不媄响用h行结果又比较耗时的Q务(比如发邮仉知理员)异步的扔lJMS 服务端去做,而尽快的把屏q返q给用户?
  • 服务端能够多U程排队响应高ƈ发的hQƈ保证h不丢失?
  • 可以在Java世界里达到最高的解耦。客L与服务端无需直连Q甚x需知晓Ҏ是谁、在哪里、有多少人,只要Ҏq的信息作响应就行了Q在企业应用环境复杂时作用明显?

    ActiveMQ的特性:

  • 完全支持JMS1.1和J2EE 1.4规范?JMS Provider实现Q也是Apache Geronimo默认的JMS provider?
  • POJO withdout EJB ContainerQ不需要实现EJBJ琐复杂的Message Bean接口和配|?
  • Spring BaseQ可以用Spring的各U特性如IOC、AOP ?
  • EffectiveQ基于Jencks的JCA Container实现 pool connectionQcontrol transactions and manage security?nbsp;

1.2 SpringSide 的完全POJO的JMSҎ   

  SpringSide 2.0在BookStoreCZ中,演示了用户下订单Ӟ发通知信到用户邮箱的动作,通过JMS交给JMS服务端异步完成,避免了邮件服务器的堵塞而媄响用L下订?/p>

  全部代码于examples\bookstore\src\java\org\springside\bookstore\components\activemq 目录中?/p>

  一个JMS场景通常需要三者参与:

  • 一个POJO的的Message ProducerQ负责用Spring的JMS Template发送消息?
  • 一个Message ConverterQ负责把Java对象如订?Order)转化为消息,使得Producer能够直接发送POJO?
  • 一个MDP Message ConsumerQ负责接收ƈ处理消息?

  SpringSide 2.0采用了ActiveMQ 4.1-incubator 与Spring 2.0 集成Q对比SS1.0M3Q有三个值得留意的地方,使得代码中几乎不见一丝JMS的R入代码:

  1. 采用Spring2.0的Schema式简化配|?
  2. 实现Message Converter转化消息与对象,使得Producer能够直接发送POJO而不是JMS Message?
  3. 使用了Spring2.0的DefaultMessageListenerContainer与MessageListenerAdapterQ消息接收者不用实现MessageListener 接口?
  4. 同时QSpring 2.0 的DefaultMessageListenerContainer 代替了SS1.0M3中的Jenck(JCA Container)Q充当MDP Container的角艌Ӏ?

2.引入ActiveMQ的XSD

  ActiveMQ4.1 响应Spring 2.0号召Q支持了引入XML Schema namespace的简单配|语法,化了配置的语句?nbsp;

  在ApplicationContext.xml(Spring的配|文?中引入ActiveMQ的XML Scheam 配置文g),如下:

<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:amq="http://activemq.org/config/1.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://activemq.org/config/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-incubator-SNAPSHOT.xsd">

׃ActiveMQ4.1 SnapShot的那个XSD有部分错误,因此使用的是自行修改q的XSD?/p>

先在ClassPath根目录放一个修改过的activemq-core-4.1-incubator-SNAPSHOT.xsd?/p>

在ClassPath 下面建立META-INF\spring.schemas 内容如下。这个spring.schemas是spring自定义scheam的配|文?h?http:\://"部分写法

http\://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-incubator-SNAPSHOT.xsd=/activemq-core-4.1-incubator-SNAPSHOT.xsd

3. 配置Ҏ

3.1 基础零g 

1. 配置ActiveMQ Broker  

   暂时采用在JVM中嵌入这U最单的模式Q?nbsp; 当spring初始化时候,ActiveMQ embedded Broker ׃启动了?/p>

<!--  lets create an embedded ActiveMQ Broker -->
<amq:broker useJmx="false" persistent="false">
  	<amq:transportConnectors>
    		<amq:transportConnector uri="tcp://localhost:0"/>
 	</amq:transportConnectors>
 </amq:broker>

2. 配置(A)ConnectionFactory

  ׃前面配置的Broker是JVM embedded 所以URL?vm://localhost

<!--  ActiveMQ connectionFactory to use  -->
 <amq:connectionFactory id="jmsConnectionFactory" brokerURL="vm://localhost"/>

3 配置(B)Queue

<!--  ActiveMQ destinations to use  -->
 <amq:queue name="destination" physicalName="org.apache.activemq.spring.Test.spring.embedded"/>

4. 配置(C)Converter

   配置ConveterQ得Producer能够直接发送Order对象Q而不是JMS的Message对象?/p>

<!--  OrderMessage converter  -->
 <bean id="orderMessageConverter" class="org.springside.bookstore.components.activemq.OrderMessageConverter"/>  

3.2  发送端 

1 配置JmsTemplate

   Spring提供的TemplateQ绑定了(A)ConnectionFactory?C)Converter?/p>

<!--  Spring JmsTemplate config -->
 <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
  <property name="connectionFactory">
   <!--  lets wrap in a pool to avoid creating a connection per send -->
   <bean class="org.springframework.jms.connection.SingleConnectionFactory">
    <property name="targetConnectionFactory" ref="jmsConnectionFactory"/>
   </bean>
  </property>
  <!-- custom MessageConverter -->
  <property name="messageConverter" ref="orderMessageConverter"/>
 </bean>

2.Producer

   消息发送者,使用JmsTemplate发送消息,l定了JmsTemplate (含A、C)?B)Queue?/p>

<!-- POJO which send Message uses  Spring JmsTemplateQ绑定JMSTemplate 与Queue -->
 <bean id="orderMessageProducer" class="org.springside.bookstore.components.activemq.OrderMessageProducer">
  <property name="template" ref="jmsTemplate"/>
  <property name="destination" ref="destination"/>
 </bean>

3.3 接收?/h3>

  1.接收处理?MDP)

    使用Spring的MessageListenerAdapterQ指定负责处理消息的POJO及其Ҏ名,l定(C)Converter?/p>

  <!--  Message Driven POJO (MDP)Q绑定Converter -->
 <bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
  <constructor-arg>
   <bean class="org.springside.bookstore.components.activemq.OrderMessageConsumer">
    <property name="mailService" ref="mailService"/>
   </bean>
  </constructor-arg>
  <!--  may be other method -->
  <property name="defaultListenerMethod" value="sendEmail"/>
  <!-- custom MessageConverter define -->
  <property name="messageConverter" ref="orderMessageConverter"/>
 </bean> 

2. listenerContainer

    负责调度MDPQ?nbsp;l定(A) connectionFactory, (B)Queue和MDP?/p>

<!--  this is the attendant message listener container -->
 <bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  <property name="connectionFactory" ref="jmsConnectionFactory"/>
  <property name="destination" ref="destination"/>
  <property name="messageListener" ref="messageListener"/>
 </bean>

  互相l定的关pLҎQ发送端和接收端都以不同形式l定?A) connectionFactory, (B)Queue?(C)Converter?/p>

4. 下篇


1. 说明

   请先阅读ActiveMQ4.1 +Spring2.0的POJO JMSҎ(?

   本篇补充说明了Q?/p>

   1) 使用数据库持久化消息Q保证服务器重启时消息不会丢?br />    2) 使用Jencks作正宗的JCA Container?/p>

2.持久化消?/h2>

2.1 lBroker加入Persistence 配置

在配|文件applicationContext-activemq-embedded-persitence.xml中的<amq:broker>节点加入  

<amq:persistenceAdapter>
<amq:jdbcPersistenceAdapter id="jdbcAdapter" dataSource="#hsql-ds" createTablesOnStartup="true" useDatabaseLock="false"/>
</amq:persistenceAdapter>

h意MSSQL(2000/2005)和HSQL׃不支持[SELECT  * ACTIVEMQ_LOCK FOR UPDATE ]语法,因此不能使用默认的userDatabaseLock="true",只能讄成useDatabaseLock="false"

2.2 配置多种数据?/h3>

配置多种数据?ljdbcPersistenceAdapter使用QSpringSide 中用的内嵌HSQL

 <!-- The HSQL Datasource that will be used by the Broker -->
<bean id="hsql-ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:res:hsql/activemq"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
<property name="poolPreparedStatements" value="true"/>
</bean>

2. 3 说明

   W者仅仅用了jdbcPersistenceAdapter,其实在ActiveMQ的XSD已经描述了多UPersistenceAdapter,可以参考对应的XSD文g.

  另外对于数据库的差异主要表现在设|了userDatabaseLock="true"之后QActiveMQ使用的[SELECT * ACTIVEMQ_LOCK FOR UPDATE] 上面Q会D一些数据库出错(试中MSSQL2000/2005,HSQL都会D出错)。另外HSQL的脚本请参见activemq.script?/p>

3. Jenck(JCA Container)  

   Spring 2.0本n使用DefaultMessageListenerContainer 可以充当MDP中的Container角色Q但是鉴于Jencks是JCA标准的,它不仅仅能够提供jms的jca整合,包括其他资源比如jdbc都可以做到jca理

所?同时完成了这个ActiveMQ+Spring+Jencks 配置演示,更多的针对生产系l的JCAҎ展C?会在E后的开发计划讨Z定?/p>

     此文档适用于说明?Jecncks ?使用Spring 2.0(DefaultMessageListenerContainer)  充当MDP Container时的区别Q同时演CJecnks 的Spring 2.0 新配|实例?/p>

3.1 引入ActiveMQ ResourceAdapter 和Jencks 的XSD

  在ApplicationContext.xml(Spring的配|文?中引入ActiveMQ ResourceAdapter 和Jencks 的XML Scheam 配置文g),如下:

   ActiveMQ4.1 响应Spring 2.0号召Q支持了引入XML Schema namespace的简单配|语法,化了配置的语句?nbsp;

  在ApplicationContext.xml(Spring的配|文?中引入ActiveMQ的XML Scheam 配置文g),如下:

<beans
xmlns="http://www.springframework.org/schema/beans"   xmlns:amq="http://activemq.org/config/1.0"   xmlns:ampra="http://activemq.org/ra/1.0"   xmlns:jencks="http://jencks.org/1.3"   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://activemq.org/config/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-core-4.1-incubator-SNAPSHOT.xsd
  http://activemq.org/ra/1.0 http://people.apache.org/repository/org.apache.activemq/xsds/activemq-ra-4.1-incubator-SNAPSHOT.xsd
  http://jencks.org/1.3 http://repository.codehaus.org/org/jencks/jencks/1.3/jencks-1.3.xsd">

׃ActiveMQ RA和Jencks 那个XSD 仍然有部分错误,因此使用的是自行修改q的XSD?是xs:any元素引v的错?

先在ClassPath根目录放一个修改过的activemq-ra-4.1-incubator-SNAPSHOT.xsd和jencks-1.3.xsd?/p>

同样修改 ClassPath 下面META-INF\spring.schemas 增加内容如下。这个spring.schemas是spring自定义scheam的配|文?h?http:\://"部分写法

http\://people.apache.org/repository/org.apache.activemq/xsds/activemq-ra-4.1-incubator-SNAPSHOT.xsd=/activemq-ra-4.1-incubator-SNAPSHOT.xsd
http\://repository.codehaus.org/org/jencks/jencks/1.3/jencks-1.3.xsd=/jencks-1.3.xsd

3.2  配置Ҏ

3.2.1 基础零g 

1. 配置ActiveMQ Broker  参见 ActiveMQ+Spring

2. 配置ActiveMQ Resource Adapter

<amqra:managedConnectionFactory id="jmsManagedConnectionFactory" resourceAdapter="#resourceAdapter"/><amqra:resourceAdapter id="resourceAdapter" serverUrl="vm://localhost" />

3. 配置Jencks 基础配置

   具体的配|可以参见Jencks的XSD

<!-- jencks PoolFactory config-->
<jencks:singlePoolFactory id="poolingSupport" maxSize="16" minSize="5" blockingTimeoutMilliseconds="60" idleTimeoutMinutes="60" matchOne="true" matchAll="true" selectOneAssumeMatch="true" /> <!-- jencks XATransactionFactory -->
<jencks:xATransactionFactory id="transactionSupport" useTransactionCaching="true" useThreadCaching="true" />  
<!-- jencks ConnectionManagerFactory -->
<jencks:connectionManagerFactory id="connectionManager" containerManagedSecurity="false"  poolingSupport="#poolingSupport" transactionSupport="#transactionSupport" /> <!-- jencks TransactionContextManagerFactory -->
<jencks:transactionContextManagerFactory id="transactionContextManagerFactory"/>
  

4. 配置lJmsTemplate使用的connectionFactory (主要是生成?发送?使用)

   q里注意?在配|jmsTemplate的用的targetConnectionFactory是使用jencks配置的connectionManager

<!-- spring config jms with jca-->
 <bean id="jmsManagerConnectionFactory" class="org.springframework.jca.support.LocalConnectionFactoryBean">
  <property name="managedConnectionFactory">
   <ref local="jmsManagedConnectionFactory" />
  </property>
  <property name="connectionManager">
   <ref local="connectionManager" />
  </property>
 </bean>
 
 <!--  Spring JmsTemplate config -->
 <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
  <property name="connectionFactory">
   <!--  lets wrap in a pool to avoid creating a connection per send -->
   <bean class="org.springframework.jms.connection.SingleConnectionFactory">
        <property name="targetConnectionFactory" ref="jmsManagerConnectionFactory" />
   </bean>
  </property>
  <!-- custom MessageConverter -->
  <property name="messageConverter" ref="orderMessageConverter" />
 </bean>  

5. 配置Spring 2.0的MessageListenerAdapter,保证不需要用户实现MessageListener

   ?span class="nobr">ActiveMQ+Spring

 6.配置Jecnks 充当MDP的Container

  是把上面的MessageListenerAdapter配置到Jencks里面,完成整个MDP的配|?/p>

 <!-- Jencks Container-->
 <jencks:jcaContainer>  	<jencks:bootstrapContext>
   		<jencks:bootstrapContextFactory threadPoolSize="25" />
  	</jencks:bootstrapContext>
  		<jencks:connectors>
   	   <!-- use jencks container (use spring MessageListenerAdapter)-->
   		<jencks:connector ref="messageListener">
    			<jencks:activationSpec>
     				<amqra:activationSpec destination="org.apache.activemq.spring.Test.spring.embedded" destinationType="javax.jms.Queue" />
    			</jencks:activationSpec>
   		</jencks:connector>  	</jencks:connectors> 		 <jencks:resourceAdapter>
   		<amqra:resourceAdapter serverUrl="vm://localhost" />
  	</jencks:resourceAdapter>
 </jencks:jcaContainer>



hk2000c 2008-04-12 01:37 发表评论
]]>
Servlet API ?NIO: 最l组合在一?/title><link>http://m.tkk7.com/hk2000c/archive/2008/01/03/172595.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Thu, 03 Jan 2008 14:58:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2008/01/03/172595.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/172595.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2008/01/03/172595.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/172595.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/172595.html</trackback:ping><description><![CDATA[<blockquote>您认为把 NIO ?Servlet API l合在一h不可能的Q请再好好想一下。在本文中,Java 开发h?Taylor Cowan 向您展示了如何把生?消费者模型应用到消费者非d I/OQ从而轻村֜?Servlet API 全新地兼?NIO。在q个q程中,您将会看到采用了什么来创徏实际的基?Servlet q实C NIO ?Web 服务器;您也发现在企业环境中,那个服务器是如何以标准的 Java I/O 服务器(Tomcat 5.0Qؓ基础而创建的?/blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES--> <p>NIO 是带?JDK 1.4 ?Java q_的最有名Q如果不是最的)的添加部分之一。下面的许多文章阐述?NIO 的基本知识及如何利用非阻塞通道的好处。但它们所遗漏的一件事正是Q没有充分地展示 NIO 如何可以提高 J2EE Web 层的可׾~性。对于企业开发h员来_q些信息特别密切相关Q因为实?NIO 不像把少数几?import 语句改变成一个新?I/O 包那L单。首先,Servlet API 采用d I/O 语义Q因此默认情况下Q它不能利用非阻?I/O。其ơ,不像 JDK 1.0 中那PU程不再?#8220;资源独占”Qresource hogQ,因此使用较少的线E不一定表明服务器可以处理更多的客h?/p> <p>在本文中Qؓ了创建基?Servlet q实C NIO ?Web 服务器,您将学习如何解决 Servlet API 与非d I/O 的不配合问题。我们将会看到在多元?Web 服务器环境中Q这个服务器是如何针Ҏ?I/O 服务器(Tomcat 5.0Q进行׾~的。ؓW合企业中生存期的事实,我们重Ҏ在当保持 socket q接的客h数量以指数增长ӞNIO 与标?I/O 相比较的情况如何?/p> <p>注意Q本文针Ҏ?Java 开发h员,他们已经熟悉?Java q_?I/O ~程的基知识。有关非d I/O 的介l,请参?<a >参考资?/a> 部分?</p> <p><a name="IDAYBGLB"><span id="qkmcwmg" class="atitle">U程不再昂贵</span></a></p> <p>大家都知道,U程是比较昂늚。在 Java q_的早期(JDK 1.0Q,U程的开销是一个很大负担,因此强制开发h员自定义生成解决Ҏ。一个常见的解决Ҏ是?VM 启动时创建的U程池,而不是按需创徏每个新线E。尽最q在 VM 层上提高了线E的性能Q但标准 I/O 仍然要求分配惟一的线E来处理每个新打开?socket。就短期而言Q这工作得相当不错,但当U程的数量增加超q了 1KQ标?I/O 的不_表现出来了。由于要在线E间q行上下文切换,因此 CPU 直变成了蝲?/p> <p>׃ JDK 1.4 中引入了 NIOQ企业开发h员最l有?#8220;单线E?#8221;模型的一个内|解x案:多元 I/O 使得固定数量的线E可以服务不断增长的用户数量?/p> <p><em>多\复用QMultiplexingQ?/em>指的是通过一个蝲波来同时发送多个信h。当使用手机Ӟ日常的多路复用例子就发生了。无UK率是E有的资源Q因此无UK率提供商使用多\复用技术通过一个频率发送多个呼叫。在一个例子中Q把呼叫分成一些段Q然后给q些D很短的持箋旉Qƈ在接收端重新装配。这叫?<em>时分多\复用Qtime-division multiplexingQ?/em>Q即 TDM?</p> <p>?NIO 中,接收端相当于“选择?#8221;Q参?<code>java.nio.channels.Selector</code> Q。不是处理呼叫,选择器是处理多个打开?socket。就像在 TDM 中那P选择器重新装配从多个客户机写入的数据Dc这使得服务器可以用单个U程理多个客户机?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="IDALCGLB"><span id="ek2uuog" class="atitle">Servlet API ?NIO</span></a></p> <p>对于 NIOQ非dd是必要的Q但它们q不是完全没有麻烦。除了不会阻塞之外,非阻塞读不能l呼叫方M保证。客h或服务器应用E序可能d完整信息、部分消息或者根本读取不到消息。另外,非阻塞读可能d到太多的消息Q从而强制ؓ下一个呼叫准备一个额外的~冲区。最后,不像那Pd了零字节q不表明已经完全接收了消息?/p> <p>q些因素使得没有轮询׃可能实现甚至是简单的 <code>readline</code> Ҏ。所有的 servlet 容器必须在它们的输入上提供 <code>readline</code> Ҏ。因此,许多开发h员放弃了创徏Z Servlet q实C NIO ?Web 应用E序服务器。不q这里有一个解x案,它组合了 Servlet API ?NIO 的多?I/O 的能力?</p> <p>在下面的几节中,您将学习如何使用 <code>java.io.PipedInput</code> ?<code>PipedOutputStream</code> cL把生产?消费者模型应用到消费者非d I/O。当d非阻塞通道Ӟ把它写到正由W二个线E消费的道。注意,q种分解映射U程不同于大多数Z Java 的客h/服务器应用程序。这里,我们让一个线E单独负责处理非d通道Q生产者)Q让另一个线E单独负责把数据作ؓ消费(消费者)。管道也为应用程序服务器解决了非d I/O 问题Q因?servlet 在消?I/O 时将采用d语义?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="IDAFDGLB"><span id="wqgiccm" class="atitle">CZ服务?/span></a></p> <p>CZ服务器展CZ Servlet API ?NIO 不兼容的生?消费者解x案。该服务器与 Servlet API 非常怼Q可以ؓ成熟的基?NIO 应用E序服务器提?POC (proof of concept)Q是专门~写来衡?NIO 相对于标?Java I/O 的性能的。它处理单的 HTTP <code>get</code> hQƈ支持来自客户机的 Keep-Alive q接。这是重要的Q因为多路复?I/O 只证明在要求服务器处理大量打开?scoket q接时是有意的?</p> <p>该服务器被分成两个包Q?<code>org.sse.server</code> ?<code>org.sse.http</code> 包中有提供主?<code>服务?/code> 功能的类Q比如如下的一些功能:接收新客hq接、阅L息和生成工作U程以处理请求?<code>http</code> 包支?HTTP 协议的一个子集。详l阐q?HTTP 出了本文的范围。有兛_现细节,请从 <a >参考资?/a> 部分下蝲代码CZ?</p> <p>现在让我们来看一?<code>org.sse.server</code> 包中一些最重要的类?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="IDALEGLB"><span id="ooys2sc" class="atitle">Server c?/span></a></p> <p><code>Server</code> cL有多路复用@?—?MZ NIO 服务器的核心。在清单 1 中,在服务器接收新客h或检到正把可用的字节写到打开?socket 前, <code>select()</code> 的调用阻塞了。这与标?Java I/O 的主要区别是Q所有的数据都是在这个@环中d的。通常会把从特?socket 中读取字节的d分配l一个新U程。?NIO 选择器事仉动方法,实际上可以用单个U程处理成千上万的客hQ不q,我们q会在后面看到线E仍有一个角色要扮演?</p> <p>每个 <code>select()</code> 调用q回一l事Ӟ指出新客h可用Q新数据准备qAQ可以读取;或者客h准备qAQ可以接收响应。server ?<code>handleKey()</code> Ҏ只对新客hQ?<code>key.isAcceptable()</code> Q和传入数据 ( <code>key.isReadable()</code> ) 感兴。到q里Q工作就l束了,转入 <code>ServerEventHandler</code> cR?</p> <br /> <a name="IDAQFGLB"><strong>清单 1. Server.java 选择器@?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">public void listen() { SelectionKey key = null; try { while (true) { selector.select(); Iterator it = selector.selectedKeys().iterator(); while (it.hasNext()) { key = (SelectionKey) it.next(); handleKey(key); it.remove(); } } } catch (IOException e) { key.cancel(); } catch (NullPointerException e) { // NullPointer at sun.nio.ch.WindowsSelectorImpl, Bug: 4729342 e.printStackTrace(); } } </pre> </td> </tr> </tbody> </table> <br /> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="IDA0FGLB"><span id="06sk8ku" class="atitle">ServerEventHandler c?/span></a></p> <p><code>ServerEventHandler</code> cd应服务器事g。当新客h变ؓ可用Ӟ它就实例化一个新?<code>Client</code> 对象Q该对象代表了那个客h的状态。数据是以非d方式从通道中读取的Qƈ被写?<code>Client</code> 对象中?<code>ServerEventHandler</code> 对象也维护请求队列。ؓ了处理(消费Q队列中的请求,生成了不定数量的工作U程。在传统的生产?消费者方式下Qؓ了在队列变ؓI时U程会阻塞,q在新请求可用时U程会得到通知Q需要写 <code>Queue</code> ?</p> <p>Z支持{待的线E,在清?2 中已l重写了 <code>remove()</code> Ҏ。如果列表ؓI,׃增加{待U程的数量,q塞当前线E。它实质上提供了非常单的U程池?</p> <br /> <a name="IDA1GGLB"><strong>清单 2. Queue.java</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">public class Queue extends LinkedList { private int waitingThreads = 0; public synchronized void insert(Object obj) { addLast(obj); notify(); } public synchronized Object remove() { if ( isEmpty() ) { try { waitingThreads++; wait();} catch (InterruptedException e) {Thread.interrupted();} waitingThreads--; } return removeFirst(); } public boolean isEmpty() { return (size() - waitingThreads <= 0); } } </pre> </td> </tr> </tbody> </table> <br /> <p>工作U程的数量与 Web 客户机的数量无关。不是ؓ每个打开?socket 分配一个线E,相反Q我们把所有请求放C个由一l?<code>RequestHandlerThread</code> 实例所服务的通用队列中。理x况下Q线E的数量应该Ҏ处理器的数量和请求的长度或持l时间进行调整。如果请求通过资源或处理需求花了很长时_那么通过d更多的线E,可以提高感知到的服务质量?</p> <p>注意Q这不一定提高整体的吞吐量,但确实改善了用户体验。即使在蝲的情况下Q也会给每个U程一个处理时间片。这一原则同样适用于基于标?Java I/O 的服务器Q不q这些服务器是受到限制的Q因Z <em>要求</em> 它们为每个打开?socket q接分配一个线E。NIO 服务器完全不用担心这一点,因此它们可以扩展到大量用戗最后的l果?NIO 服务器仍焉要线E,只是不需要那么多?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="IDANHGLB"><span id="4kuw2kk" class="atitle">h处理</span></a></p> <p><code>Client</code> cL两个用途。首先,通过把传入的非阻?I/O 转换成可?Servlet API 消费的阻?<code>InputStream</code> Q它解决了阻?非阻塞问题。其ơ,它管理特定客h的请求状态。因为当全部d消息Ӟ非阻塞通道没有l出M提示Q所以强制我们在协议层处理这一情况?<code>Client</code> cdL指定的时刻都指出了它是否正在参与q行中的h。如果它准备处理新请求, <code>write()</code> Ҏ׃求处理而将该客h排到队列中。如果它已经参与了请求,它就只是使用 <code>PipedInputStream</code> ?<code>PipedOutputStream</code> cL传入的字节{换成一?<code>InputStream</code> ?</p> <p>?1 展示了两个线E围l管道进行交互。主U程把从通道d的数据写到管道中。管道把相同的数据作?<code>InputStream</code> 提供l消费者。管道的另一个重要特性是Q它是进行缓冲处理的。如果没有进行缓冲处理,ȝE在试写到道时就会阻塞。因ZU程单独负责所有客h间的多\复用Q因此我们不能让它阻塞?</p> <br /> <a name="IDA0YGLB"><strong>?1. PipedInput/OutputStream</strong></a><br /> <img height="111" alt="关系的图形表C? src="http://www.ibm.com/developerworks/cn/java/j-nioserver/figure1.gif" width="454" /> <br /> <p>?<code>Client</code> 自己排队后,工作U程可以消费它了?<code>RequestHandlerThread</code> cL担了q个角色。至此,我们已经看到ȝE是如何q箋地@环的Q它要么接受新客hQ要么读取新?I/O。工作线E@环等待新h。当客户机在h队列上变为可用时Q它马上被 <code>remove()</code> Ҏ中阻塞的W一个等待线E所消费?</p> <br /> <a name="IDATZGLB"><strong>清单 3. RequestHandlerThread.java</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">public void run() { while (true) { Client client = (Client) myQueue.remove(); try { for (; ; ) { HttpRequest req = new HttpRequest(client.clientInputStream, myServletContext); HttpResponse res = new HttpResponse(client.key); defaultServlet.service(req, res); if (client.notifyRequestDone()) break; } } catch (Exception e) { client.key.cancel(); client.key.selector().wakeup(); } } } </pre> </td> </tr> </tbody> </table> <br /> <p>然后该线E创建新?<code>HttpRequest</code> ?<code>HttpResponse</code> 实例Qƈ调用 <code>defaultServlet</code> ?service Ҏ。注意, <code>HttpRequest</code> 是用 <code>Client</code> 对象?<code>clientInputStream</code> 属性构造的?<code>PipedInputStream</code> 是负责把非d I/O 转换成阻塞流?</p> <p>从现在开始,h处理׃您在 J2EE Servlet API 中期望的怼。当?servlet 的调用返回时Q工作线E在q回到池中之前,会检查是否有来自相同客户机的另一个请求可用。注意,q里用到了单?<em>?(pool)</em>。事实上Q线E会寚w列尝试另一?<code>remove()</code> 调用Qƈ变成dQ直C一个请求可用?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="IDA30GLB"><span id="iakk2oi" class="atitle">q行CZ</span></a></p> <p>CZ服务器实C HTTP 1.1 协议的一个子集。它处理普通的 HTTP <code>get</code> h。它带有两个命o行参数。第一个指定端口号Q第二个指定 HTML 文g所ȝ的目录。在解压文g后, <em>切换</em>到项目目录,然后执行下面的命令,注意要把下面?webroot 目录替换为您自己的目录: </p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">java -cp bin org.sse.server.Start 8080 "C:\mywebroot" </pre> </td> </tr> </tbody> </table> <br /> <p>q请注意Q服务器q没有实现目录清单,因此必须指定有效?URL 来指向您?webroot 目录下的文g?/p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="IDAP1GLB"><span id="aaaquwo" class="atitle">性能l果</span></a></p> <p>CZ NIO 服务器是在重负蝲下与 Tomcat 5.0 q行比较的。选择 Tomcat 是因为它是基于标?Java I/O 的纯 Java 解决Ҏ。ؓ了提高可伸羃性,一些高U的应用E序服务器是?JNI 本机代码优化的,因此它们没有提供标准 I/O ?NIO 之间的很好比较。目标是要确?NIO 是否l出了大量的性能优势Q以及是在什么条件下l出的?/p> <p>如下是一些说明:</p> <ul> <li>Tomcat 是用最大的U程数量 2000 来配|的Q而示例服务器只允许用 4 个工作线E运行?<br /> <li>每个服务器是针对相同的一l简?HTTP <code>get</code> 试的,q些 HTTP <code>get</code> 基本上由文本内容l成?<br /> <br /> <li>把加载工PMicrosoft Web Application Stress ToolQ设|ؓ使用“Keep-Alive”会话Q导致了大约要ؓ每个用户分配一?socket。然后它D了在 Tomcat 上ؓ每个用户分配一个线E,?NIO 服务器用固定数量的线E来处理相同的负载?</li> </ul> <p>?2 展示了在不断增加负蝲下的“h/U?#8221;率。在 200 个用hQ性能是相似的。但当用h量超q?600 ӞTomcat 的性能开始急剧下降。这最有可能是׃在这么多的线E间切换上下文的开销而导致的。相反,Z NIO 的服务器的性能则以U性方式下降。记住,Tomcat 必须为每个用户分配一个线E,?NIO 服务器只配置?4 个工作线E?/p> <br /> <a name="IDAG2GLB"><strong>?2. h/U?/strong></a><br /> <img height="292" alt="关系的图形表C? src="http://www.ibm.com/developerworks/cn/java/j-nioserver/graph1.gif" width="468" /> <br /> <p>?3 q一步显CZ NIO 的性能。它展示了操作的 Socket q接错误?分钟。同P在大U?600 个用hQTomcat 的性能急剧下降Q而基?NIO 的服务器的错误率保持相对较低?/p> <br /> <a name="IDAU2GLB"><strong>?3. Socket q接错误?分钟</strong></a><br /> <img height="282" alt="关系的图形表? src="http://www.ibm.com/developerworks/cn/java/j-nioserver/graph2.gif" width="531" /> <br /> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <br /> <p><a name="IDAA3GLB"><span id="k2oyyyy" class="atitle">l束?/span></a></p> <p>在本文中您已l学习了Q实际上可以使用 NIO ~写Z Servlet ?Web 服务器,甚至可以启用它的非阻塞特性。对于企业开发h员来_q是好消息,因ؓ在企业环境中QNIO 比标?Java I/O 更能够进行׾~。不像标准的 Java I/OQNIO 可以用固定数量的U程处理许多客户机。当Z Servlet ?NIO Web 服务器用来处理保持和拥有 socket q接的客hӞ会获得更好的性能?/p> <br /> <br /> <p><a name="resources"><span id="yi24m48" class="atitle">参考资?</span></a></p> <ul> <li>您可以参阅本文在 developerWorks 全球站点上的 <a >英文原文</a>. <br /> <br /> <li>下蝲本文中用的 <a >源代?/a>?<br /> <br /> <br /> <br /> <li>看看“ <a >Merlin l?Java q_带来了非d I/O</a>”Q?<em>developerWorks</em>Q?002 q?3 月)Q获?NIO 语义的进一步知识?<br /> <br /> <br /> <br /> <li>l合?developerWorks 教程“ <a >NIO 入门</a>”Q?<em>developerWorks</em>Q?003 q?11 月)从高U的概念到底层的~程l节Q详l论及了 NIO 库?<br /> <br /> <br /> <br /> <li>Merlin Hughes 的由两部分组成的文章“ <a >Turning streams inside out</a>”Q?<em>developerWorks</em>Q?002 q?9 月)?Java I/OQ标准版?NIO 版)的一些普遍的挑战提供了制作精巧的设计解决Ҏ?<br /> <br /> <br /> <br /> <li>取有?Java I/O 问题的一些背景知识,请参?Allen Holub ?#8220; <a >关于解决 Java ~程语言U程问题的徏?</a>”Q?<em>developerWorks</em>Q?000 q?10 月)?<br /> <br /> <br /> <br /> <li>讉K <a >NIO 主页</a>Q从资源中学习非d I/O?<br /> <br /> <br /> <br /> <li><a >JavaNIO.info</a> 是查找有?NIO 的资源的理想地方?<br /> <br /> <br /> <br /> <li>Z书本pȝ学习 NIOQ请参阅该领域的l典著作QRon Hitchens ?<a >Java NIO</a>QO'Reilly & AssociatesQ?002 q_?<br /> <br /> <br /> <br /> <li>?developerWorks <a >Java 技术专?/a>可以扑ֈ有关 Java ~程各个斚w的文章?<br /> <br /> <br /> <br /> <li>讉K <a >Developer Bookstore</a>Q获取技术书c的完整列表Q其中包括数百本 <a >Java 相关的图?/a>?<br /> <br /> <br /> <br /> <li>也请参阅 <a >Java 技术专区教E页</a>Q从 <em>developerWorks</em> 获取免费?Java 专门教程的完整列表?<br /> <br /> <br /> </li> </ul> <br /> <br /> <p><a name="author"><span id="wqisumq" class="atitle">关于作?/span></a></p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td colspan="3"><img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /></td> </tr> <tr valign="top" align="left"> <td> <p> </p> </td> <td><img height="5" alt="" src="http://www.ibm.com/i/c.gif" width="4" /></td> <td width="100%"> <p>Taylor Cowan 是一位Y件工E师Q也是一位专?J2EE 的自由撰Eh。他?North Texas 大学的计机U学专业获得了硕士学位,另外Q他q从 Jazz Arranging 获得了音乐学士学位?/p> </td> </tr> </tbody> </table> <img src ="http://m.tkk7.com/hk2000c/aggbug/172595.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2008-01-03 22:58 <a href="http://m.tkk7.com/hk2000c/archive/2008/01/03/172595.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 多线E入门大?/title><link>http://m.tkk7.com/hk2000c/archive/2008/01/02/172275.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Wed, 02 Jan 2008 10:14:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2008/01/02/172275.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/172275.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2008/01/02/172275.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/172275.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/172275.html</trackback:ping><description><![CDATA[<br />     一U是l承自Threadc?Thread cL一个具体的c,即不是抽象类Q该cd装了U程的行为。要创徏一个线E,E序员必dZ个从 Thread cd出的新类。程序员通过覆盖 Thread ?run() 函数来完成有用的<a onclick="javascript:tagshow(event, '%B9%A4%D7%F7');" href="javascript:;" target="_self"><u><strong><font color="#333333">工作</font></strong></u></a>?font color="#ff0000">用户q不直接调用此函敎ͼ而是通过调用 Thread ?start() 函数Q该函数再调?run()?/font><br />     <br />     例如: <p> </p> <p>    public class Test extends Thread{<br />       public Test(){<br />       }<br />       public static void main(String args[]){<br />         Test t1 = new Test();<br />         Test t2 = new Test();<br />         t1.start();<br />         t2.start();<br />       }<br />       public void run(){<br />         //do thread's things<br />       }<br />     }</p> <p> </p> <hr /> <br />     <br />     另一U是实现Runnable接口,此接口只有一个函敎ͼrun()Q此函数必须由实C此接口的cd现?br />     <br />     例如: <p> </p> <p>    public class Test implements Runnable{<br />       Thread thread1;<br />       Thread thread2;<br />       public Test(){<br />         thread1 = new Thread(this,"1");<br />         thread2 = new Thread(this,"2");<br />       }<br />       public static void main(String args[]){<br />         Test t = new Test();<br />         t.startThreads();<br />       }<br />       public void run(){<br />         //do thread's things<br />       }<br />       public void startThreads(){<br />         thread1.start();<br />         thread2.start();<br />       }<br />     }</p> <p>    两种创徏方式看v来差别不?但是弄不清楚的话Q也怼你的程序弄得一团糟。两者区别有以下几点Q?/p> <p>1.当你想承某一其它cL,你只能用后一U方?</p> <p>2.<font color="#ff0000">W一U因为承自Thread,只创Z自n对象,但是在数量上Q需要几个线E,得创徏几个自n对象Q第二种只创Z个自w对象,却创建几个Thread对象.</font>而两U方法重大的区别在于此Q请你考虑Q如果你在第一U里创徏C自n对象q且start()后,你会发现好像synchronized不v作用了,已经加锁的代码块或者方法居然同时可以有几个U程q去Q而且同样一个变量,居然可以有好几个U程同时可以L改它。(例如下面的代码)q是因ؓQ在q个E序中,虽然你v了数个线E,可是你也创徏了数个对象,而且Q每个线E对应了每个对象也就是说Q每个线E更改和占有的对象都不一P所以就出现了同时有几个U程q入一个方法的现象Q其实,那也不是一个方法,而是不同对象的相同的Ҏ。所以,q时候你要加锁的话,只能方法或者变量声明ؓ静态,static加上后,你就会发玎ͼU程又能住Ҏ了,同时不可能有两个U程q入同样一个方法,那是因ؓQ现在不是每个对象都拥有一个方法了Q而是所有的对象共同拥有一个方法,q个Ҏ是静态方法?/p> <p>    而你如果用第二种Ҏ使用U程的话Q就不会有上q的情况Q因为此Ӟ你只创徏了一个自w对象,所以,自n对象的属性和Ҏ对于U程来说是共有的?/p> <p>    因此Q我Q最好用后一U方法来使用U程?/p> <p>public class mainThread extends Thread{<br />   int i=0;<br />   public static void main(String args[]){<br />     mainThread m1 = new mainThread();<br />     mainThread m2 = new mainThread();<br />     mainThread m3 = new mainThread();<br />     mainThread m4 = new mainThread();<br />     mainThread m5 = new mainThread();<br />     mainThread m6 = new mainThread();<br />     m1.start();<br />     m2.start();<br />     m3.start();<br />     m4.start();<br />     m5.start();<br />     m6.start();<br />   }<br />   public synchronized void t1(){<br />     i=++i;<br />     try{<br />       Thread.sleep(500);<br />     }<br />     catch(Exception e){}<br />     //每个U程都进入各自的t1()ҎQ分别打印各自的i<br />     System.out.println(Thread.currentThread().getName()+" "+i);<br />   }<br />   public void run(){<br />     synchronized(this){<br />       while (true) {<br />         t1();<br />       }<br />     }<br />   }<br /> }</p> <p> </p> <p> </p> <hr /> <p> </p> <p> </p> <p>    下面我们来讲synchronized?U用法吧:</p> <p>    1.Ҏ声明时?攑֜范围操作W?public{?之后,q回cd声明(void{?之前.即一ơ只能有一个线E进入该Ҏ,其他U程要想在此时调用该Ҏ,只能排队{?当前U程(是在synchronizedҎ内部的线E?执行完该Ҏ?别的U程才能q入.<br />  <br />       例如:</p> <p>      public synchronized void synMethod() {<br />         //Ҏ?br />       }</p> <p>    2.Ҏ一代码块?synchronized后跟括号,括号里是变量,q样,一ơ只有一个线E进入该代码?例如:</p> <p>      public int synMethod(int a1){<br />         synchronized(a1) {<br />           //一ơ只能有一个线E进?br />         }<br />       }<br />     3.synchronized后面括号里是一对象,此时,U程获得的是对象?例如:</p> <blockquote dir="ltr" style="margin-right: 0px"> <blockquote dir="ltr" style="margin-right: 0px"> <blockquote dir="ltr" style="margin-right: 0px"> <p>public class MyThread implements Runnable {<br />   public static void main(String args[]) {<br />     MyThread mt = new MyThread();<br />     Thread t1 = new Thread(mt, "t1");<br />     Thread t2 = new Thread(mt, "t2");<br />     Thread t3 = new Thread(mt, "t3");<br />     Thread t4 = new Thread(mt, "t4");<br />     Thread t5 = new Thread(mt, "t5");<br />     Thread t6 = new Thread(mt, "t6");<br />     t1.start();<br />     t2.start();<br />     t3.start();<br />     t4.start();<br />     t5.start();<br />     t6.start();<br />   }</p> <p>  public void run() {<br />     synchronized (this) {<br />       System.out.println(Thread.currentThread().getName());<br />     }<br />   }<br /> } </p> </blockquote></blockquote></blockquote> <p><br />  <br />     对于3,如果U程q入,则得到对象锁,那么别的U程在该cL有对象上的Q何操作都不能q行.在对象使用锁通常是一U比较粗p的Ҏ。ؓ什么要整个对象都上锁Q而不允许<a onclick="javascript:tagshow(event, '%C6%E4%CB%FB');" href="javascript:;" target="_self"><u><strong><font color="#333333">其他</font></strong></u></a>U程短暂C用对象中其他同步Ҏ来访问共享资源?如果一个对象拥有多个资源,׃需要只Z让一个线E用其中一部分资源Q就所有线E都锁在外面。由于每个对象都有锁Q可以如下所CZ用虚拟对象来上锁Q?/p> <blockquote dir="ltr" style="margin-right: 0px"> <blockquote dir="ltr" style="margin-right: 0px"> <blockquote dir="ltr" style="margin-right: 0px"> <p>class FineGrainLock {</p> <p>   MyMemberClass x, y;<br />    Object xlock = new Object(), ylock = new Object();</p> <p>   public void foo() {<br />       synchronized(xlock) {<br />          //access x here<br />       }</p> <p>      //do something here - but don't use shared resources</p> <p>      synchronized(ylock) {<br />          //access y here<br />       }<br />    }</p> <p>   public void bar() {<br />       synchronized(this) {<br />          //access both x and y here<br />       }<br />       //do something here - but don't use shared resources<br />    }<br /> }</p> </blockquote></blockquote></blockquote> <p> </p> <p>    4.synchronized后面括号里是c?例如:</p> <blockquote dir="ltr" style="margin-right: 0px"> <blockquote dir="ltr" style="margin-right: 0px"> <blockquote dir="ltr" style="margin-right: 0px"> <p>class ArrayWithLockOrder{<br />   private static long num_locks = 0;<br />   private long lock_order;<br />   private int[] arr;</p> <p>  public ArrayWithLockOrder(int[] a)<br />   {<br />     arr = a;<br />     synchronized(ArrayWithLockOrder.class) {//-----------------------------------------q里<br />       num_locks++;             // 锁数?1?br />       lock_order = num_locks;  // 为此对象实例讄唯一?lock_order?br />     }<br />   }<br />   public long lockOrder()<br />   {<br />     return lock_order;<br />   }<br />   public int[] array()<br />   {<br />     return arr;<br />   }<br /> }</p> <p>class SomeClass implements Runnable<br /> {<br />   public int sumArrays(ArrayWithLockOrder a1,<br />                        ArrayWithLockOrder a2)<br />   {<br />     int value = 0;<br />     ArrayWithLockOrder first = a1;       // 保留数组引用的一?br />     ArrayWithLockOrder last = a2;        // 本地副本?br />     int size = a1.array().length;<br />     if (size == a2.array().length)<br />     {<br />       if (a1.lockOrder() > a2.lockOrder())  // 定q设|对象的锁定<br />       {                                     // 序?br />         first = a2;<br />         last = a1;<br />       }<br />       synchronized(first) {              // 按正的序锁定对象?br />         synchronized(last) {<br />           int[] arr1 = a1.array();<br />           int[] arr2 = a2.array();<br />           for (int i=0; i<size; i++)<br />             value += arr1[i] + arr2[i];<br />         }<br />       }<br />     }<br />     return value;<br />   }<br />   public void run() {<br />     //...<br />   }<br /> }</p> </blockquote></blockquote></blockquote> <p> </p> <p>    对于4,如果U程q入,则线E在该类中所有操作不能进?包括静态变量和静态方?实际?对于含有静态方法和静态变量的代码块的同步,我们通常?来加?</p> <p>以上4U之间的关系Q?/p> <p>    锁是和对象相兌的,每个对象有一把锁Qؓ了执行synchronized语句Q线E必能够获得synchronized语句中表辑ּ指定的对象的锁,一个对象只有一把锁Q被一个线E获得之后它׃再拥有这把锁Q线E在执行完synchronized语句后,获得锁交还l对象?br />     <font color="#ff0000"><strong>在方法前面加上synchronized修饰W即可以一个方法声明ؓ同步化方法。同步化Ҏ在执行之前获得一个锁。如果这是一个类ҎQ那么获得的锁是和声明方法的cȝ关的Classcd象的锁。如果这是一个实例方法,那么此锁是this对象的锁?/strong></font><br /> </p> <p> </p> <hr /> <p> </p> <p>  下面谈一谈一些常用的Ҏ:</p> <p>  wait(),wait(long),notify(),notifyAll(){方法是当前cȝ实例Ҏ,<br />     <br />         wait()是持有对象锁的U程释放?<br />         wait(long)是持有对象锁的U程释放锁时间ؓlong(毫秒)?再次获得?wait()和wait(0){h;<br />         notify()是唤醒一个正在等待该对象锁的U程,如果{待的线E不止一?那么被唤醒的U程由jvm定;<br />         notifyAll是唤醒所有正在等待该对象锁的U程.<br />         在这里我也重申一?我们应该优先使用notifyAll()Ҏ,因ؓ唤醒所有线E比唤醒一个线E更Ҏ让jvm扑ֈ最适合被唤醒的U程.</p> <p>    对于上述Ҏ,只有在当前线E中才能使用,否则报运行时错误<a onclick="javascript:tagshow(event, 'java');" href="javascript:;" target="_self"><u><strong><font color="#333333">java</font></strong></u></a>.lang.IllegalMonitorStateException: current thread not owner.</p> <p> </p> <hr /> <p> </p> <p>    下面,我谈一下synchronized和wait()、notify(){的关系:</p> <p>1.有synchronized的地方不一定有wait,notify</p> <p>2.有wait,notify的地方必有synchronized.q是因ؓwait和notify不是属于U程c,而是每一个对象都h的方法,而且Q这两个Ҏ都和对象锁有养I有锁的地方,必有synchronized?/p> <p>另外Q请注意一点:如果要把notify和waitҎ攑֜一L的话Q必d调用notify后调用waitQ因为如果调用完waitQ该U程已l不是current thread了。如下例Q?/p> <p>/**<br />  * Title:        Jdeveloper's Java Projdect<br />  * Description:  n/a<br />  * Copyright:    Copyright (c) 2001<br />  * Company:      soho  <a ><u><font color="#333333">http://www.ChinaJavaWorld.com</font></u></a><br />  * @author <a href="mailto:jdeveloper@21cn.com"><u><font color="#333333">jdeveloper@21cn.com</font></u></a><br />  * @version 1.0<br />  */<br /> import java.lang.Runnable;<br /> import java.lang.Thread;</p> <p>public class DemoThread<br />     implements Runnable {</p> <p>  public DemoThread() {<br />     TestThread testthread1 = new TestThread(this, "1");<br />     TestThread testthread2 = new TestThread(this, "2");</p> <p>    testthread2.start();<br />     testthread1.start();</p> <p>  }</p> <p>  public static void main(String[] args) {<br />     DemoThread demoThread1 = new DemoThread();</p> <p>  }</p> <p>  public void run() {</p> <p>    TestThread t = (TestThread) Thread.currentThread();<br />     try {<br />       if (!t.getName().equalsIgnoreCase("1")) {<br />         synchronized (this) {<br />           wait();<br />         }<br />       }<br />       while (true) {</p> <p>        System.out.println("@time in thread" + t.getName() + "=" +<br />                            t.increaseTime());</p> <p>        if (t.getTime() % 10 == 0) {<br />           synchronized (this) {<br />             System.out.println("****************************************");<br />             notify();<br />             if (t.getTime() == 100)<br />               break;<br />             wait();<br />           }<br />         }<br />       }<br />     }<br />     catch (Exception e) {<br />       e.printStackTrace();<br />     }<br />   }</p> <p>}</p> <p>class TestThread<br />     extends Thread {<br />   private int time = 0;<br />   public TestThread(Runnable r, String name) {<br />     super(r, name);<br />   }</p> <p>  public int getTime() {<br />     return time;<br />   }</p> <p>  public int increaseTime() {<br />     return++time;<br />   }</p> <p>}</p> <p>    下面我们用生产?消费者这个例子来说明他们之间的关p?</p> <blockquote dir="ltr" style="margin-right: 0px"> <blockquote dir="ltr" style="margin-right: 0px"> <blockquote dir="ltr" style="margin-right: 0px"> <p>    public class test {<br />   public static void main(String args[]) {<br />     Semaphore s = new Semaphore(1);<br />     Thread t1 = new Thread(s, "producer1");<br />     Thread t2 = new Thread(s, "producer2");<br />     Thread t3 = new Thread(s, "producer3");<br />     Thread t4 = new Thread(s, "consumer1");<br />     Thread t5 = new Thread(s, "consumer2");<br />     Thread t6 = new Thread(s, "consumer3");<br />     t1.start();<br />     t2.start();<br />     t3.start();<br />     t4.start();<br />     t5.start();<br />     t6.start();<br />   }<br /> }</p> <p>class Semaphore<br />     implements Runnable {<br />   private int count;<br />   public Semaphore(int n) {<br />     this.count = n;<br />   }</p> <p>  public synchronized void acquire() {<br />     while (count == 0) {<br />       try {<br />         wait();<br />       }<br />       catch (InterruptedException e) {<br />         //keep trying<br />       }<br />     }<br />     count--;<br />   }</p> <p>  public synchronized void release() {<br />     while (count == 10) {<br />       try {<br />         wait();<br />       }<br />       catch (InterruptedException e) {<br />         //keep trying<br />       }<br />     }<br />     count++;<br />     notifyAll(); //alert a thread that's blocking on this semaphore<br />   }</p> <p>  public void run() {<br />     while (true) {<br />       if (Thread.currentThread().getName().substring(0,8).equalsIgnoreCase("consumer")) {<br />         acquire();<br />       }<br />       else if (Thread.currentThread().getName().substring(0,8).equalsIgnoreCase("producer")) {<br />         release();<br />       }<br />       System.out.println(Thread.currentThread().getName() + " " + count);<br />     }<br />   }<br /> }</p> </blockquote></blockquote></blockquote> <p>       生者生?消费者消?一般没有冲H?但当库存??消费者要消费是不行的,但当库存Z?q里?0)?生者也不能生.请好好研M面的E序,你一定会比以前进步很?</p> <p>      上面的代码说明了synchronized和wait,notify没有l对的关p?在synchronized声明的方法、代码块?你完全可以不用wait,notify{方?但是,如果当线E对某一资源存在某种争用的情况下,你必适时得将U程攑օ{待或者唤?</p>  <br /> <img src ="http://m.tkk7.com/hk2000c/aggbug/172275.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2008-01-02 18:14 <a href="http://m.tkk7.com/hk2000c/archive/2008/01/02/172275.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实现非阻塞套接字的一U简单方?/title><link>http://m.tkk7.com/hk2000c/archive/2007/12/31/171799.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Sun, 30 Dec 2007 21:07:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/12/31/171799.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/171799.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/12/31/171799.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/171799.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/171799.html</trackback:ping><description><![CDATA[<h1 style="color: #000000"> <p>2003 q?11 ?24 ?/p> <blockquote>管 SSL d操作――当d数据的时候套接字的访问被d――与对应的非d方式相比提供了更好的 I/O 错误通知Q但是非d操作允许调用的线El运行。本文中Q作者同时就客户端和服务器端描述了如何用Java Secure Socket Extensions QJSSEQ??Java NIO Q新 I/OQ库创徏非阻塞的安全q接Qƈ且介l了创徏非阻塞套接字的传l方法,以及使用JSSE ?NIO 的一U可选的Q必需的)Ҏ?/blockquote><!--start RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--end RESERVED FOR FUTURE USE INCLUDE FILES--> <p>dQ还是非dQ这是问题所在。无论在E序员的头脑中多么高?#8230;…当然q不是莎士比亚,本文提出了Q何程序员在编?Internet 客户E序旉应该考虑的一个重要问题。通信操作应该是阻塞的q是非阻塞的Q?</p> <p>许多E序员在使用 Java 语言~写 Internet 客户E序时ƈ没有考虑q个问题Q主要是因ؓ在以前只有一U选择――阻塞通信。但是现?Java E序员有了新的选择Q因此我们编写的每个客户E序也许都应该考虑一下?</p> <p>非阻塞通信?Java 2 SDK ?1.4 版被引入 Java 语言。如果您曄使用该版本编q程序,可能会对新的 I/O 库(NIOQ留下了印象。在引入它之前,非阻塞通信只有在实现第三方库的时候才能用,而第三方库常怼l应用程序引入缺陗?</p> <p>NIO 库包含了文g、管道以及客h和服务器套接字的非阻塞功能。库中缺的一个特性是安全的非d套接字连接。在 NIO 或?JSSE 库中没有建立安全的非d通道c,但这q不意味着不能使用安全的非d通信。只不过E微ȝ一炏V?</p> <p>要完全领会本文,您需要熟悉:</p> <ul> <li>Java 套接字通信的概c您也应该实际编写过应用E序。而且不只是打开q接、读取一行然后退出的单应用程序,应该是实?POP3 ?HTTP 之类协议的客h或通信库这LE序? <li>SSL 基本概念和加密之cȝ概念。基本上是知道如何讄一个安全连接(但不必担?JSSE ――这是关于它的一?#8220;紧急教E?#8221;Q? <li>NIO 库? <li>在您选择的^C安装 Java 2 SDK 1.4 或以后的版本。(我是?Windows 98 上?1.4.1_01 版。) </li> </ul> <p>如果需要关于这些技术的介绍Q请参阅 <a >参考资?/a>部分?</p> <p>那么到底什么是d和非d通信呢? </p> <p><a name="1"><span id="aas2qaa" class="atitle">d和非d通信</span></a></p> <p>d通信意味着通信Ҏ在尝试访问套接字或者读写数据时d了对套接字的讉K。在 JDK 1.4 之前Q绕q阻塞限制的Ҏ是无限制C用线E,但这样常怼造成大量的线E开销Q对pȝ的性能和可伸羃性生媄响。java.nio 包改变了q种状况Q允许服务器有效C?I/O ,在合理的旉内处理所服务的客戯求?</p> <p>没有非阻塞通信Q这个过E就像我所喜欢说的“为所Ʋؓ”那样。基本上Q这个过E就是发送和dM能够发?d的东ѝ如果没有可以读取的东西Q它׃止读操作Q做其他的事情直到能够读取ؓ止。当发送数据时Q该q程试囑֏送所有的数据Q但q回实际发送出的内宏V可能是全部数据、部分数据或者根本没有发送数据?</p> <p>d与非d相比实有一些优点,特别是遇到错误控刉题的时候。在d套接字通信中,如果出现错误Q该讉K会自动返回标志错误的代码。错误可能是׃|络时、套接字关闭或者Q何类型的 I/O 错误造成的。在非阻塞套接字通信中,该方法能够处理的唯一错误是网l超时。ؓ了检用非d通信的网l超Ӟ需要编写稍微多一点的代码Q以定自从上一ơ收到数据以来已l多长时间了?</p> <p>哪种方式更好取决于应用程序。如果用的是同步通信Q如果数据不必在dM数据之前处理的话Q阻塞通信更好一些,而非d通信则提供了处理M已经d的数据的Z。而异步通信Q如 IRC 和聊天客h则要求非d通信以避免冻l套接字?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="2"><span id="um2smgg" class="atitle">创徏传统的非d客户机套接字</span></a></p> <p>Java NIO 库用通道而非。通道可同时用于阻塞和非阻塞通信Q但创徏旉认ؓ非阻塞版本。但是所有的非阻塞通信都要通过一个名字中包含 <code>Channel</code> 的类完成。在套接字通信中用的cL <code>SocketChannelQ?/code> 而创cȝ对象的过E不同于典型的套接字所用的q程Q如清单 1 所C?</p> <br /> <a name="listing1"><strong>清单 1. 创徏q连?SocketChannel 对象</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">SocketChannel sc = SocketChannel.open(); sc.connect("www.ibm.com",80); sc.finishConnect(); </pre> </td> </tr> </tbody> </table> <br /> <p>必须声明一?<code>SocketChannel</code> cd的指针,但是不能使用 <code>new</code> 操作W创建对象。相反,必须调用 <code>SocketChannel</code> cȝ一个静态方法打开通道。打开通道后,可以通过调用 <code>connect()</code> Ҏ与它q接。但是当该方法返回时Q套接字不一定是q接的。ؓ了确保套接字已经q接Q必L着调用 <code>finishConnect()</code> ?</p> <p>当套接字q接之后Q非d通信可以开始?<code>SocketChannel</code> cȝ <code>read()</code> ?<code>write()</code> Ҏ了。也可以把该对象强制转换成单独的 <code>ReadableByteChannel</code> ?<code>WritableByteChannel</code> 对象。无论哪U方式,都要Ҏ据?<code>Buffer</code> 对象。因?NIO 库的使用出了本文的范围Q我们不再对此进一步讨论?</p> <p>当不再需要套接字Ӟ可以使用 <code>close()</code> Ҏ其关闭Q?</p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">sc.close(); </pre> </td> </tr> </tbody> </table> <br /> <p>q样׃同时关闭套接字连接和底层的通信通道?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="3"><span id="eau84s2" class="atitle">创徏替代的非d的客h套接?/span></a></p> <p>上述Ҏ比传l的创徏套接字连接的例程E微ȝ一炏V不q,传统的例E也能用于创建非d套接字,不过需要增加几个步骤以支持非阻塞通信?</p> <p><code>SocketChannel</code> 对象中的底层通信包括两个 <code>Channel</code> c: <code>ReadableByteChannel</code> ?<code>WritableByteChannel?/code> q两个类可以分别从现有的 <code>InputStream</code> ?<code>OutputStream</code> <code>d中使用 <code>Channels</code> cȝ <code>newChannel()</code> Ҏ创徏Q如清单 2 所C: </p> <br /> <a name="listing2"><strong>清单 2. 从流中派生通道</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">ReadableByteChannel rbc = Channels.newChannel(s.getInputStream()); WriteableByteChannel wbc = Channels.newChannel(s.getOutputStream()); </pre> </td> </tr> </tbody> </table> <br /> <p><code>Channels</code> cM用于把通道转换成流或?reader ?writer。这g是把通信切换到阻塞模式,但ƈ非如此。如果试图读取从通道z的流Q读Ҏ抛?<code>IllegalBlockingModeException </code>异常?</p> <p>相反方向的{换也是如此。不能?<code>Channels</code> cL{换成通道而指望进行非d通信。如果试图读从流z的通道Q读仍然是阻塞的。但是像~程中的许多事情一Pq一规则也有例外?</p> <p>q种例外适合于实?<code>SelectableChannel</code> 抽象cȝcR?<code>SelectableChannel</code> 和它的派生类能够选择使用d或者非d模式?<code>SocketChannel</code> 是q样的一个派生类?</p> <p>但是Qؓ了能够在两者之间来回切换,接口必须作ؓ <code>SelectableChannel </code>实现。对于套接字而言Qؓ了实现这U能力必M?<code>SocketChannel</code> 而不?<code>Socket</code> ?</p> <p>回顾一下,要创建套接字Q首先必d通常使用 <code>Socket</code> c那样创Z个套接字。套接字q接之后Q?<a >清单 2</a>中的两行代码把流转换成通道?</p> <br /> <a name="listing3"><strong>清单 3. 创徏套接字的另一U方?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">Socket s = new Socket("www.ibm.com", 80); ReadableByteChannel rbc = Channels.newChannel(s.getInputStream()); WriteableByteChannel wbc = Channels.newChannel(s.getOutputStream()); </pre> </td> </tr> </tbody> </table> <br /> <p>如前所qͼq样q不能实现非d套接字通信――所有的通信仍然在阻塞模式下。在q种情况下,非阻塞通信必须模拟实现。模拟层不需要多代码。让我们来看一看?</p> <p><a name="N1015A"><span id="aueoyyq" class="smalltitle">从模拟层L?/span></a></p> <p>模拟层在试L作之前首先检查数据的可用性。如果数据可d开始读。如果没有数据可用,可能是因为套接字被关闭,则返回表CU情늚代码。在清单 4 中要注意仍然使用?<code>ReadableByteChannel</code> 读,管 <code>InputStream</code> 完全可以执行q个动作。ؓ什么这样做呢?Z造成?NIO 而不是模拟层执行通信的假象。此外,q可以模拟层与其他通道更容易结合,比如向文仉道内写入数据?</p> <br /> <a name="listing4"><strong>清单 4. 模拟非阻塞的L?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">/* The checkConnection method returns the character read when determining if a connection is open. */ y = checkConnection(); if(y <= 0) return y; buffer.putChar((char ) y); return rbc.read(buffer); </pre> </td> </tr> </tbody> </table> <br /> <p><a name="N10175"><span id="eyya2eq" class="smalltitle">向模拟层写入数据</span></a></p> <p>对于非阻塞通信Q写操作只写入能够写的数据。发送缓冲区的大和一ơ可以写入的数据多少有很大关pR缓冲区的大可以通过调用 <code>Socket</code> 对象?<code>getSendBufferSize()</code> Ҏ定。在试非阻塞写操作时必考虑到这个大。如果尝试写入比~冲块更大的数据Q必L开攑ֈ多个非阻塞写操作中。太大的单个写操作可能被d?</p> <br /> <a name="listing5"><strong>清单 5. 模拟非阻塞的写操?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">int x, y = s.getSendBufferSize(), z = 0; int expectedWrite; byte [] p = buffer.array(); ByteBuffer buf = ByteBuffer.allocateDirect(y); /* If there isn't any data to write, return, otherwise flush the stream */ if(buffer.remaining() == 0) return 0; os.flush() for(x = 0; x < p.length; x += y) { if(p.length - x < y) { buf.put(p, x, p.length - x); expectedWrite = p.length - x; } else { buf.put(p, x, y); expectedWrite = y; } /* Check the status of the socket to make sure it's still open */ if(!s.isConnected()) break; /* Write the data to the stream, flushing immediately afterward */ buf.flip(); z = wbc.write(buf); os.flush(); if(z < expectedWrite) break; buf.clear(); } if(x > p.length) return p.length; else if(x == 0) return -1; else return x + z; </pre> </td> </tr> </tbody> </table> <br /> <p>与读操作cMQ首先要查套接字是否仍然q接。但是如果把数据写入 <code>WritableByteBuffer</code> 对象Q就像清?5 那样Q该对象自动进行检查ƈ在没有连接时抛出必要的异常。在q个动作之后开始写数据之前Q流必须立即被清I,以保证发送缓冲区中有发送数据的I间。Q何写操作都要q样做。发送到块中的数据与发送缓冲区的大相同。执行清除操作可以保证发送缓冲不会溢导致写操作被阻塞?</p> <p>因ؓ假定写操作只能写入能够写的内容,q个q程q必L查套接字保证它在每个数据块写入后仍然是打开的。如果在写入数据时套接字被关闭,则必M止写操作q返回套接字关闭之前能够发送的数据量?</p> <p><code>BufferedOutputReader</code> 可用于模拟非d写操作。如果试囑ֆ入超q缓冲区两倍长度的数据Q则直接写入~冲区整倍数长度的数据(~冲余下的数据)。比如说Q如果缓冲区的长度是 256 字节而需要写?529 字节的数据,则该对象清除当前缓冲区、发?512 字节然后保存剩下?17 字节?</p> <p>对于非阻塞写而言Q这q我们所期望的。我们希望分ơ把数据写入同样大小的缓冲区中,q最l把全部数据都写完。如果发送的大块数据留下一些数据被~冲Q那么在所有数据被发送的时候,写操作就会被d?</p> <p><a name="N101A4"><span id="qs2qcco" class="smalltitle">模拟层类模板</span></a></p> <p>整个模拟层可以放C个类中,以便更容易和应用E序集成。如果要q样做,我徏议从 <code>ByteChannel </code>zq个cR这个类可以强制转换成单独的 <code>ReadableByteChannel</code> ?<code>WritableByteChannel</code> cR?</p> <p>清单 6 l出了从 <code>ByteChannel</code> z的模拟层cL板的一个例子。本文后面将一直用这个类表示通过dq接执行的非d操作?</p> <br /> <a name="listing6"><strong>清单 6. 模拟层的cL?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">public class nbChannel implements ByteChannel { Socket s; InputStream is; OutputStream os; ReadableByteChannel rbc; WritableByteChannel wbc; public nbChannel(Socket socket); public int read(ByteBuffer dest); public int write(ByteBuffer src); public void close(); protected int checkConnection(); } </pre> </td> </tr> </tbody> </table> <br /> <p><a name="N101CA"><span id="uyyssyo" class="smalltitle">使用模拟层创建套接字</span></a></p> <p>使用新徏的模拟层创徏套接字非常简单。只要像通常那样创徏 <code>Socket</code> 对象Q然后创?<code>nbChannel</code> 对象可以了Q如清单 7 所C: </p> <br /> <a name="listing7"><strong>清单 7. 使用模拟?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">Socket s = new Socket("www.ibm.com", 80); nbChannel socketChannel = new nbChannel(s); ReadableByteChannel rbc = (ReadableByteChannel)socketChannel; WritableByteChannel wbc = (WritableByteChannel)socketChannel; </pre> </td> </tr> </tbody> </table> <br /> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="4"><span id="cggiqeq" class="atitle">创徏传统的非d服务器套接字</span></a></p> <p>服务器端的非d套接字和客户端上的没有很大差别。稍微麻烦一点的只是建立接受输入q接的套接字。套接字必须通过从服务器套接字通道z一个阻塞的服务器套接字l定到阻塞模式。清?8 列出了需要做的步骤?</p> <br /> <a name="listing8"><strong>清单 8. 创徏非阻塞的服务器套接字QSocketChannelQ?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">ServerSocketChannel ssc = ServerSocketChannel.open(); ServerSocket ss = ssc.socket(); ss.bind(new InetSocketAddress(port)); SocketChannel sc = ssc.accept(); </pre> </td> </tr> </tbody> </table> <br /> <p>与客h套接字通道怼Q服务器套接字通道也必L开而不是?<code>new</code> 操作W或者构造函数。在打开之后Q必L生服务器套接字对象以便把套接字通道l定C个端口。一旦套接字被绑定,服务器套接字对象可以丢弃了?</p> <p>通道使用 <code>accept()</code> Ҏ接收到来的连接ƈ把它们{l套接字通道。一旦接收了到来的连接ƈ转给套接字通道对象Q通信可以通过 <code>read()</code> ?<code>write()</code> Ҏ开始进行了?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="5"><span id="cy2eykw" class="atitle">创徏替代的非d服务器套接字</span></a></p> <p>实际上,q真正的替代。因为服务器套接字通道必须使用服务器套接字对象l定Qؓ何不完全l开服务器套接字通道而仅使用服务器套接字对象呢?不过q里的通信不?<code>SocketChannel</code> Q而要使用模拟?<code>nbChannel?/code> </p> <br /> <a name="listing9"><strong>清单 9. 建立服务器套接字的另一U方?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">ServerSocket ss = new ServerSocket(port); Socket s = ss.accept(); nbChannel socketChannel = new nbChannel(s); ReadableByteChannel rbc = (ReadableByteChannel)socketChannel; WritableByteChannel wbc = (WritableByteChannel)socketChannel; </pre> </td> </tr> </tbody> </table> <br /> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="6"><span id="0iseuww" class="atitle">创徏 SSL q接</span></a></p> <p>创徏SSLq接Q我们要分别从客L和服务器端考察?</p> <p><a name="N10232"><span id="so28qs8" class="smalltitle">从客L</span></a></p> <p>创徏 SS Lq接的传l方法涉及到使用套接字工厂和其他一些东ѝ我不会详l讨论如何创建SSLq接Q不q有一本很好的教程Q?#8220;Secure your sockets with JSSE”Q请参阅 <a >参考资?/a>Q,从中您可以了解到更多的信息?</p> <p>创徏 SSL 套接字的默认Ҏ非常单,只包括几个很短的步骤Q?/p> <ol> <li>创徏套接字工厂? <li>创徏q接的套接字? <li>开始握手? <li>z? <li>通信?</li> </ol> <p>清单 10 说明了这些步骤:</p> <br /> <a name="listing10"><strong>清单 10. 创徏安全的客h套接?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">SSLSocketFactory sslFactory = (SSLSocketFactory)SSLSocketFactory.getDefault(); SSLSocket ssl = (SSLSocket)sslFactory.createSocket(host, port); ssl.startHandshake(); InputStream is = ssl.getInputStream(); OutputStream os = ssl.getOutputStream(); </pre> </td> </tr> </tbody> </table> <br /> <p>默认Ҏ不包括客户验证、用戯书和其他特定q接可能需要的东西?</p> <p><a name="N10264"><span id="smmeygs" class="smalltitle">从服务器?/span></a></p> <p>建立SSL服务器连接的传统ҎE微ȝ一点,需要加上一些类型{换。因些超Z本文的范_我将不再q一步介l,而是说说支持SSL服务器连接的默认Ҏ?</p> <p>创徏默认?SSL 服务器套接字也包括几个很短的步骤Q?/p> <ol> <li>创徏服务器套接字工厂? <li>创徏q绑定服务器套接字? <li>接受传入的连接? <li>开始握手? <li>z? <li>通信?</li> </ol> <p>管看v来似乎与客户端的步骤怼Q要注意q里L了很多安全选项Q比如客户验证?</p> <p>清单 11 说明q些步骤Q?/p> <br /> <a name="listing11"><strong>清单 11. 创徏安全的服务器套接?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">SSLServerSocketFactory sslssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); SSLServerSocket sslss = (SSLServerSocket)sslssf.createServerSocket(port); SSLSocket ssls = (SSLSocket)sslss.accept(); ssls.startHandshake(); InputStream is = ssls.getInputStream(); OutputStream os = ssls.getOutputStream(); </pre> </td> </tr> </tbody> </table> <br /> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="7"><span id="k2qqkke" class="atitle">创徏安全的非dq接</span></a></p> <p>要精心实现安全的非阻塞连接,也需要分别从客户端和服务器端来看?</p> <p><a name="N1029E"><span id="egys2aa" class="smalltitle">从客L</span></a></p> <p>在客L建立安全的非dq接非常单: </p> <ol> <li>创徏q连?<code>Socket</code> 对象? <li>?<code>Socket</code> 对象d到模拟层上? <li>通过模拟层通信?</li> </ol> <p>清单 12 说明了这些步骤:</p> <br /> <a name="listing12"><strong>清单 12. 创徏安全的客hq接</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">/* Create the factory, then the secure socket */ SSLSocketFactory sslFactory = (SSLSocketFactory)SSLSocketFactory.getDefault(); SSLSocket ssl = (SSLSocket)sslFactory.createSocket(host, port); /* Start the handshake. Should be done before deriving channels */ ssl.startHandshake(); /* Put it into the emulation layer and create separate channels */ nbChannel socketChannel = new nbChannel(ssl); ReadableByteChannel rbc = (ReadableByteChannel)socketChannel; WritableByteChannel wbc = (WritableByteChannel)socketChannel; </pre> </td> </tr> </tbody> </table> <br /> <p>利用前面l出?<a >模拟层类</a> 可以实现非d的安全连接。因为安全套接字通道不能使用 <code>SocketChannel</code> cL开Q?Java API 中又没有完成q项工作的类Q所以创Z一个模拟类。模拟类可以实现非阻塞通信Q无Z用安全套接字q接q是非安全套接字q接?</p> <p>列出的步骤包括默认的安全讄。对于更高的安全性,比如用户证书和客户验证, <a >参考资?/a> 部分提供了说明如何实现的文章?</p> <p><a name="N102DA"><span id="w2ue8ee" class="smalltitle">从服务器?/span></a></p> <p>在服务器端徏立套接字需要对默认安全E加讄。但是一旦套接字被接收和路由Q设|必M客户端的讄完全相同Q如清单 13 所C: </p> <br /> <a name="listing13"><strong>清单 13. 创徏安全的非d服务器套接字</strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">/* Create the factory, then the socket, and put it into listening mode */ SSLServerSocketFactory sslssf = (SSLServerSocketFactory)SSLServerSocketFactory.getDefault(); SSLServerSocket sslss = (SSLServerSocket)sslssf.createServerSocket(port); SSLSocket ssls = (SSLSocket)sslss.accept(); /* Start the handshake on the new socket */ ssls.startHandshake(); /* Put it into the emulation layer and create separate channels */ nbChannel socketChannel = new nbChannel(ssls); ReadableByteChannel rbc = (ReadableByteChannel)socketChannel; WritableByteChannel wbc = (WritableByteChannel)socketChannel; </pre> </td> </tr> </tbody> </table> <br /> <p>同样Q要Cq些步骤使用的是默认安全讄?</p> <br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br /> <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td> </tr> </tbody> </table> <table class="no-print" cellspacing="0" cellpadding="0" align="right"> <tbody> <tr align="right"> <td><img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" /><br /> <table cellspacing="0" cellpadding="0" border="0"> <tbody> <tr> <td valign="middle"><img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" /><br /> </td> <td valign="top" align="right"><a class="fbox" ><strong>回页?/strong></a></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> <br /> <br /> <p><a name="8"><span id="ogy2oog" class="atitle">集成安全的和非安全的客户?/span></a></p> <p>多数 Internet 客户机应用程序,无论使用 Java 语言q是其他语言~写Q都需要提供安全和非安全连接。Java Secure Socket Extensions 库得这工作非常容易,我最q在~写一?HTTP 客户库时׃用了q种Ҏ?</p> <p><code>SSLSocket</code> cL生自 <code>Socket?/code> 您可能已l猜到我要怎么做了。所需要的只是该对象的一?<code>Socket</code> 指针。如果套接字q接不用SSLQ则可以像通常那样创徏套接字。如果要使用 SSLQ就E微ȝ一点,但此后的代码很单了。清?14 l出了一个例子: </p> <br /> <a name="listing14"><strong>清单 14. 集成安全的和非安全的客户?/strong></a><br /> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td class="code-outline"> <pre class="displaycode">Socket s; ReadableByteChannel rbc; WritableByteChannel wbc; nbChannel socketChannel; if(!useSSL) s = new Socket(host, port); else { SSLSocketFactory sslsf = SSLSocketFactory.getDefault(); SSLSocket ssls = (SSLSocket)SSLSocketFactory.createSocket(host, port); ssls.startHandshake(); s = ssls; } socketChannel = new nbChannel(s); rbc = (ReadableByteChannel)socketChannel; wbc = (WritableByteChannel)socketChannel; ... s.close(); </pre> </td> </tr> </tbody> </table> <br /> <p>创徏通道之后Q如果套接字使用了SSLQ那么就是安全通信Q否则就是普通通信。如果用了 SSLQ关闭套接字导致握手中止?/p> <p>q种讄的一U可能是使用两个单独的类。一个类负责处理通过套接字沿着与非安全套接字的q接q行的所有通信。一个单独的cd该负责创建安全的q接Q包括安全连接的所有必要设|,无论是否是默认的。安全类应该直接插入通信c,只有在用安全连接时被调用?</p> </code></h1> <img src ="http://m.tkk7.com/hk2000c/aggbug/171799.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-12-31 05:07 <a href="http://m.tkk7.com/hk2000c/archive/2007/12/31/171799.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2SE APIdProperties文g六种Ҏ http://m.tkk7.com/hk2000c/archive/2007/12/27/170763.htmlhk2000chk2000cWed, 26 Dec 2007 16:00:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/12/27/170763.htmlhttp://m.tkk7.com/hk2000c/comments/170763.htmlhttp://m.tkk7.com/hk2000c/archive/2007/12/27/170763.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/170763.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/170763.html 

使用J2SEAPIdProperties文g的六U方?br />


  1。用java.util.Propertiescȝload()ҎCZQInputStreamin=lnewBufferedInputStream(newFileInputStream(name));Propertiesp=newProperties();p.load(in);

  2。用java.util.ResourceBundlecȝgetBundle()ҎCZQResourceBundlerb=ResourceBundle.getBundle(name,Locale.getDefault());

  3。用java.util.PropertyResourceBundlecȝ构造函数示例:InputStreamin=newBufferedInputStream(newFileInputStream(name));ResourceBundlerb=newPropertyResourceBundle(in);

  4。用class变量的getResourceAsStream()ҎCZQInputStreamin=JProperties.class.getResourceAsStream(name);Propertiesp=newProperties();p.load(in);

  5。用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()ҎCZQInputStreamin=JProperties.class.getClassLoader().getResourceAsStream(name);Propertiesp=newProperties();p.load(in);

  6。用java.lang.ClassLoadercȝgetSystemResourceAsStream()静态方法示例:InputStreamin=ClassLoader.getSystemResourceAsStream(name);Propertiesp=newProperties();p.load(in);

  补充

  Servlet中可以用javax.servlet.ServletContext的getResourceAsStream()ҎCZQInputStreamin=context.getResourceAsStream(path);Propertiesp=newProperties();p.load(in);

 




hk2000c 2007-12-27 00:00 发表评论
]]>
java 多线E?wait() 以及 notirfy() ?/title><link>http://m.tkk7.com/hk2000c/archive/2007/12/19/168761.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Wed, 19 Dec 2007 07:20:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2007/12/19/168761.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/168761.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2007/12/19/168761.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/168761.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/168761.html</trackback:ping><description><![CDATA[<p>class ThreadA <br /> {<br />   public static void main(String[] args) <br />   {<br />     ThreadB b=new ThreadB();<br />     b.start();<br />     System.out.println("b is start....");<br />     synchronized(b)//括号里的b是什么意?起什么作?<br />     {<br />       try<br />       {<br />  System.out.println("Waiting for b to complete...");<br />  b.wait();//q一句是什么意思,I竟让谁wait?<br />         System.out.println("Completed.Now back to main thread");<br />       }catch (InterruptedException e){}<br />     }<br />     System.out.println("Total is :"+b.total);<br />    }<br /> } </p> <p><br /> class ThreadB extends Thread<br /> {<br />   int total;<br />   public void run()<br />   {<br />     synchronized(this)<br />     {<br />       System.out.println("ThreadB is running..");<br />       for (int i=0;i<100;i++ )<br />       {<br />         total +=i;<br />         System.out.println("total is "+total);<br />       }<br />       notify();<br />     }<br />   }<br /> }</p> <p>要分析这个程?首先要理解notify()和wait(),Z么在前几天纪录线E的时候没有纪录这两个Ҏ?因ؓq两个方法本来就不属于Threadc?而是属于最底层的object基础cȝ,也就是说不光是ThreadQ每个对象都有notify和wait的功能,Z么?因ؓ他们是用来操U锁?而每个对象都有锁,锁是每个对象的基,既然锁是基础?那么操纵锁的Ҏ当然也是最基础?</p> <p> 再往下看之前?首先最好复习一下Think in Java?4.3.1中第3部分内容Q等待和通知,也就是wait()和notify?</p> <p>按照Think in Java中的解释:"wait()允许我们线E置?#8220;睡眠”状态,同时?#8220;U极”地等待条件发生改?而且只有在一个notify()或notifyAll()发生变化的时候,U程才会被唤醒,q检查条件是否有?"</p> <p>  我们来解释一下这句话.<br />   "wait()允许我们线E置?#8220;睡眠”状?,也就是说,wait也是让当前线E阻塞的,q一点和sleep或者suspend是相同的.那和sleep,suspend有什么区别呢?</p> <p>   区别在于"(wait)同时?#8220;U极”地等待条件发生改?,q一点很关键,sleep和suspend无法做到.因ؓ我们有时候需要通过同步QsynchronizedQ的帮助来防止线E之间的冲突Q而一旦用同?p锁定对象Q也是获取对象?其它要用该对象锁的U程都只能排队等着,{到同步Ҏ或者同步块里的E序全部q行完才有机?在同步方法和同步块中,无论sleep()q是suspend()都不可能自己被调用的时候解除锁?他们都霸占着正在使用的对象锁不放.<br />    而wait却可?它可以让同步Ҏ或者同步块暂时攑ּ对象?而将它暂时让l其它需要对象锁的h(q里应该是程序块,或线E??q意味着可在执行wait()期间调用U程对象中的其他同步Ҏ!在其它情况下(sleep?suspend?,q是不可能的.<br />    但是注意我前面说?只是暂时攑ּ对象?暂时l其它线E?我wait所在的U程q是要把q个对象锁收回来的呀.wait什?是wait别h用完了还l我啊!<br />    ?那怎么把对象锁收回来呢?<br />    W一U方?限定借出ȝ旉.在wait()中设|参?比如wait(1000),以毫Uؓ单位,p明我只借出?U中,一U钟之后,我自动收?<br />    W二U方?让借出ȝ人通知?他用完了,要还l我?q时,我马上就收回??假如我设?时之后收回,别h只用了半时完?那怎么办呢??当然用完了就收回?q管我设的是多长旉?</p> <p>   那么别h怎么通知我呢?怿大家都可以想C,notify(),q就是最后一句话"而且只有在一个notify()或notifyAll()发生变化的时候,U程才会被唤?的意思了.<br />    因此,我们可将一个wait()和notify()|入M同步Ҏ或同步块内部Q无论在那个c里是否准备q行涉及U程的处理。而且实际?我们也只能在同步Ҏ或者同步块里面调用wait()和notify().</p> <p>   q个时候我们来解释上面的程?直是易如反掌?</p> <p>   synchronized(b){...}Q的意思是定义一个同步块,使用b作ؓ资源锁。b.wait();的意思是临时释放锁,q塞当前线E?好让其他使用同一把锁的线E有Z执行,在这里要用同一把锁的就是bU程本n.q个U程在执行到一定地方后用notify()通知wait的线E?锁已l用?待notify()所在的同步块运行完之后,wait所在的U程可以l执?</p> <img src ="http://m.tkk7.com/hk2000c/aggbug/168761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2007-12-19 15:20 <a href="http://m.tkk7.com/hk2000c/archive/2007/12/19/168761.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java单例延迟加蝲http://m.tkk7.com/hk2000c/archive/2007/12/18/168619.htmlhk2000chk2000cTue, 18 Dec 2007 15:58:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/12/18/168619.htmlhttp://m.tkk7.com/hk2000c/comments/168619.htmlhttp://m.tkk7.com/hk2000c/archive/2007/12/18/168619.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/168619.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/168619.html     // 似有静态内部类, 只有当有引用? 该类才会被装?br />     private static class LazyFoo {
       public static Foo foo = new Foo();
    }

    public static Foo getInstance() {
       return LazyFoo.foo;
    }
}



hk2000c 2007-12-18 23:58 发表评论
]]>
how to debug with webshpere 5 6 in intellijhttp://m.tkk7.com/hk2000c/archive/2007/11/20/161947.htmlhk2000chk2000cTue, 20 Nov 2007 13:56:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/20/161947.htmlhttp://m.tkk7.com/hk2000c/comments/161947.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/20/161947.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/161947.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/161947.htmlHow to configure remote JSP debugging
under WebSphere Application Servers

Introduction

This article describes how you can create a run and debug configuration in IntelliJ IDEA 5.1 (or higher) to allow your Web modules with JSP files to be remotely debugged under WebSphere 5.1 and WebSphere 6.0 application servers. It also describes how to configure these application servers to enable integration with IntelliJ IDEA, and provides you with step-by-step instructions for application deployment.

Requirements

Before making any settings, make sure that the following requirements are met:

  1. WebSphere 5.1 or 6.0 application server is installed (full or express version). IntelliJ IDEA does not have any bundled servers, so you need to install them yourself.
  2. JDK (Sun Java2TM Standard Edition SDK) 1.4 or less is installed. Although IntelliJ IDEA supports JDK 5.0, WebSphere application servers require JDK 1.4 or less.
  3. WebSphere application server is started.

You can find the full documentation on how to install, start, and initially configure the server at http://www-306.ibm.com/software/websphere/.

Configuring WebSphere Application Server

To enable remote debugging on the server, perform the following steps:

  1. Start the server's Administrative Console.
  2. Expand Servers > Application Servers.
    screenshot


    Note:

    WebSphere Application Server V6.0: Administrative Console

  3. Click the server name and clic the Configuration tab
  4. Navigate to the Additional Properties group and click the Debugging Service link.
  5. Make sure that the debugging service is enabled at server startup.
    • For the WebSphere 5.1 application server, select the Startup check box.
      screenshot


      Note:

      WebSphere Application Server - Express 5.1: enabling debugging

    • For the WebSphere 6.0 application server, select the Enable service at server startup check box.

      To the JVM Debug arguments field add the following line before the existing set of arguments: -Dwas.debug.mode=true

      screenshot


      Note:

      WebSphere Application Server 6.0: enabling debugging

  6. Click the Apply button. Then save the settings (for example, using the notification message)
    screenshot


    Note:

    WebSphere Application Server 6.0: notification message

  7. Restart the server using WebSphere's or operating system's administration tools.

Generating the Application Archive File

IntelliJ IDEA can generate the WAR, EAR, or JAR file for your application automatically. For this purpose, you need to configure your module (Web, J2EE Application, or EJB).

  1. In IntelliJ IDEA, click File > Settings (Ctrl + Alt + S), and then select Modules.
  2. In the Modules list, click the module for which you need to generate the archive file.
  3. Click the J2EE Build Settings tab.
  4. Select the Create web module war/ear/jar file check box, and specify the location of the file. This path will be required later, on the application deployment stage.

Apply the changes, and make the project (click the Build > Make Project menu or press Ctrl + F9).

The application is now ready for deployment.

Deploying Application

You deploy the application using the WebSphere application server's tools.

  1. Start the server's Administrative Console.
  2. Click Applications > Install New Application, and then click your server.
  3. Select Local file system or Remote file system depending on your server installation, and then specify the path to your WAR, EAR, or JAR file (usually, it corresponds to the path you specified when generating the application archive file in IntelliJ IDEA).
  4. In the Context Root text box, specify the context (e.g. "myContext").
    screenshot


    Note:

    WebSphere Application Server 6.0: enabling debugging

  5. Click Next. Skip the next screen and click Next again. Note:

    The Security Warning may appear. It displays the content of the was.policy file. You can simply click Continue.

  6. On the first step of the Install New Application wizard, select the Enable class reloading check box, and then click Next. This allows you to redeploy the application without reinstalling it
    screenshot


    Note:

    WebSphere Application Server 6.0: selecting installation options.

  7. On the second step, select the check box next to your Web module to map it to the server. Then click Next.
  8. On the third step, select the check box next to your Web module to map the virtual host to it, and then click Next.
  9. On the last step, just click Finish. The deployment will start. Note:

    The server may not always notify you when the deployment is complete. If the operation takes too long, click Enterprise Applications. If your application is present in the enterprise applications list with the KStoppedK?status (red cross icon), the deployment is complete, and you can move to the next step.

  10. When the deployment is finished, the server console will show you the installation results page. Save the configuration, for example using the Save to Master Configuration link on this page.
  11. Click Applications > Enterprise Applications. In the list of applications your application should be displayed with the KStoppedK?status (red cross icon).
  12. Select the check box next to your application, and then click Start.
screenshot


Note:

WebSphere Application Server 6.0: starting the application

Creating Run/Debug Configuration

WebSphere 5.1/6.0 application servers are supported by means of the general IntelliJ IDEA integration with the JSR compatible servers and do not have a server-specific type of Run/Debug configuration. You need to create a configuration for a JSR45 compatible server and then modify it according to WebSphere application server's needs.

  1. In IntelliJ IDEA, click the Run > Edit Configurations menu, and then click the JSR45 Compatible Server tab.
  2. Click the plus sign or press Insert to add a new configuration, and then click Remote. Specify some configuration name.
  3. Click the Configure button to add an application server.
  4. In the Application Servers dialog box, click Add, and then specify some server name.
  5. Click the Attach Classes button, and find the j2ee.jar file for your version of WebSphere Application server (<installation folder>\lib\j2ee.jar).
    screenshot


    Note:

    IntelliJ IDEA 5.1: configuring application servers

  6. In the Application Servers dialog box, click Apply to save the changes, and then in the configuration, in the Application Server list, select the added server.
  7. In the Startup page text box, specify the home page of your web application in the following format:
    • WebSphere Application Server 5.1
      http://localhost:7080/<ContextRoot>/<home page>
    • WebSphere Application Server 6.0
      http://localhost:9080/<ContextRoot>/<home page>

    "7080" and "9080" are default ports for the WebSphere 5.1 and 6.0 servers, respectively. If you have changed the default port, specify the actual port number instead.

    <ContextRoot> is name of web context used during application deployment, e.g. "myContext".
    <home page> can be any page from your Web module.

  8. Optionally, you can configure the application server log to display its content in the IntelliJ IDEA's Run tool window, in the console.

    Click the Add button, and then in the Edit Log Files Aliases dialog specify some alias name (e.g. "activity"). In the Log File Location text box, specify the location of the activity.log file. By default, this file is located in the <home>\logs folder.

  9. In the JSP package text box, enter one of the following:
    • WebSphere Application Server 5.1
      org.apache.jsp
    • WebSphere Application Server 6.0
      com.ibm._jsp
  10. In the VM options variable text box, type DEBUG.
  11. If you use WebSphere Application Server 5.1, select to use the specific JSP's line mapping model. For the WebSphere Application Server 6.0 this check box is ignored, but it is recommended to clear it.
  12. In the Port text box, specify the port number of the corresponding application server (it should be the same as specified for the startup page).
    screenshot


    Note:

    IntelliJ IDEA 5.0: Run/Debug configuration for WebSphere Application Server 6.0

  13. Click the Startup/Connection tab, and then click Debug. Check that the Socket option is selected, and the Port number is 7777.

Debugging Application

To start debugging the application in IntelliJ IDEA, just click Run > Debug or press Shift + F9. You can use all the power of the IntelliJ IDEA debugger for the JSP files running on the WebSphere Application Server, including breakpoints, stepping commands, watches, etc.

Note:

To apply any changes in the web module, you will need to redeploy the application as described earlier in this article. The "Build on frame deactivation" feature is not supported for remote debugging.

Troubleshooting

The server crashes during the debug session

Such problems may appear if you use the IBM's virtual machine supplied with the WebSphere server. Possible solutions in this case are:

  • Run IntelliJ IDEA with the command line option:
    -Didea.debugger.keep.temp.objects=false
    In this case IntelliJ IDEA will avoid calling certain methods from debug API.
  • Use Sun's JDK 1.4 or less

IntelliJ IDEA is unable to open the debugger port

In most cases, it is an internal WebSphere server error. Try to restart the WebSphere application server.

Conclusion

We hope that this article helped you to configure remote debugging successfully. If you have encountered any problems that are not described in the Troubleshooting section, don't hesitate to contact our technical support: support@jetbrains.com.



hk2000c 2007-11-20 21:56 发表评论
]]>
intellij 7 sn http://m.tkk7.com/hk2000c/archive/2007/11/20/161920.htmlhk2000chk2000cTue, 20 Nov 2007 11:07:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/20/161920.htmlhttp://m.tkk7.com/hk2000c/comments/161920.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/20/161920.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/161920.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/161920.htmlDaniel
Your key is: 22457-MWPIW-INDLX-2PU2X-WBHSX-C4YK0



hk2000c 2007-11-20 19:07 发表评论
]]>
用java调用oracle存储q程ȝ http://m.tkk7.com/hk2000c/archive/2007/11/16/161075.htmlhk2000chk2000cFri, 16 Nov 2007 09:15:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/16/161075.htmlhttp://m.tkk7.com/hk2000c/comments/161075.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/16/161075.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/161075.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/161075.htmlq段旉开始学习写存储q程Q主要原因还是因为工作需要吧Q本来以为很单的Q但几经挫折Q豪气消殆,但ȝ搞通了Qؓ了避免后来者少走弯路,特记qC此,同时亦对自己q行鼓励?/span>

一Q无q回值的存储q程

存储q程为:

CREATE OR REPLACE PROCEDURE TESTA(PARA1 IN VARCHAR2,PARA2 IN VARCHAR2) AS

BEGIN

   INSERT INTO HYQ.B_ID (I_ID,I_NAME) VALUES (PARA1, PARA2);

END TESTA;

然后呢,?/span>java里调用时q下面的代码:

package com.hyq.src;

import java.sql.*;

import java.sql.ResultSet;

public class TestProcedureOne {

 public TestProcedureOne() {

 }

 public static void main(String[] args ){

    String driver = "oracle.jdbc.driver.OracleDriver";

    String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521: hyq ";

    Statement stmt = null;

    ResultSet rs = null;

    Connection conn = null;

    CallableStatement cstmt = null;

    try {

      Class.forName(driver);

      conn = DriverManager.getConnection(strUrl, " hyq ", " hyq ");

      CallableStatement proc = null;

      proc = conn.prepareCall("{ call HYQ.TESTA(?,?) }");

      proc.setString(1, "100");

      proc.setString(2, "TestOne");

      proc.execute();

    }

    catch (SQLException ex2) {

      ex2.printStackTrace();

    }

    catch (Exception ex2) {

      ex2.printStackTrace();

    }

    finally{

      try {

        if(rs != null){

          rs.close();

          if(stmt!=null){

            stmt.close();

          }

          if(conn!=null){

            conn.close();

          }

        }

      }

      catch (SQLException ex1) {

      }

    }

 }

}

当然了,q就先要求要建张?/span>TESTTB,里面两个字段Q?/span>I_IDQ?/span>I_NAMEQ?/span>

二:有返回值的存储q程Q非列表Q?/span>

存储q程为:

CREATE OR REPLACE PROCEDURE TESTB(PARA1 IN VARCHAR2,PARA2 OUT VARCHAR2) AS

BEGIN

   SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1;

END TESTB;

?/span>java里调用时q下面的代码:

package com.hyq.src;

public class TestProcedureTWO {

 public TestProcedureTWO() {

 }

 public static void main(String[] args ){

    String driver = "oracle.jdbc.driver.OracleDriver";

    String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";

    Statement stmt = null;

    ResultSet rs = null;

    Connection conn = null;

    try {

      Class.forName(driver);

      conn = DriverManager.getConnection(strUrl, " hyq ", " hyq ");

      CallableStatement proc = null;

      proc = conn.prepareCall("{ call HYQ.TESTB(?,?) }");

      proc.setString(1, "100");

      proc.registerOutParameter(2, Types.VARCHAR);

      proc.execute();

      String testPrint = proc.getString(2);

      System.out.println("=testPrint=is="+testPrint);

    }

    catch (SQLException ex2) {

      ex2.printStackTrace();

    }

    catch (Exception ex2) {

      ex2.printStackTrace();

    }

    finally{

      try {

        if(rs != null){

          rs.close();

          if(stmt!=null){

            stmt.close();

          }

          if(conn!=null){

            conn.close();

          }

        }

      }

      catch (SQLException ex1) {

      }

    }

 }

}

}

注意Q这里的proc.getString(2)中的数?/span>2qL的,而是和存储过E中?/span>out列对应的Q如?/span>out是在W一个位|,那就?/span>proc.getString(1)Q如果是W三个位|,是proc.getString(3)Q当然也可以同时有多个返回|那就是再多加几个out参数了?/span>

三:q回列表

׃oracle存储q程没有q回|它的所有返回值都是通过out参数来替代的Q列表同样也不例外,但由于是集合Q所以不能用一般的参数Q必要?/span>pagkage?/span>.所以要分两部分Q?/span>

1Q?nbsp;Z个程序包。如下:

CREATE OR REPLACE PACKAGE TESTPACKAGE  AS

 TYPE Test_CURSOR IS REF CURSOR;

end TESTPACKAGE;

2Q徏?/span>存储q程Q存储过EؓQ?/span>

CREATE OR REPLACE PROCEDURE TESTC(p_CURSOR out TESTPACKAGE.Test_CURSOR) IS

BEGIN

    OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB;

END TESTC;

可以看到Q它是把游标Q可以理解ؓ一个指针)Q作Z?/span>out 参数来返回值的?/span>

?/span>java里调用时q下面的代码:

package com.hyq.src;

import java.sql.*;

import java.io.OutputStream;

import java.io.Writer;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import oracle.jdbc.driver.*;

public class TestProcedureTHREE {

 public TestProcedureTHREE() {

 }

 public static void main(String[] args ){

    String driver = "oracle.jdbc.driver.OracleDriver";

    String strUrl = "jdbc:oracle:thin:@127.0.0.1:1521:hyq";

    Statement stmt = null;

    ResultSet rs = null;

    Connection conn = null;

    try {

      Class.forName(driver);

      conn = DriverManager.getConnection(strUrl, "hyq", "hyq");

      CallableStatement proc = null;

      proc = conn.prepareCall("{ call hyq.testc(?) }");

      proc.registerOutParameter(1,oracle.jdbc.OracleTypes.CURSOR);

      proc.execute();

      rs = (ResultSet)proc.getObject(1);

      while(rs.next())

      {

          System.out.println("<tr><td>" + rs.getString(1) + "</td><td>"+rs.getString(2)+"</td></tr>");

      }

    }

    catch (SQLException ex2) {

      ex2.printStackTrace();

    }

    catch (Exception ex2) {

      ex2.printStackTrace();

    }

    finally{

      try {

        if(rs != null){

          rs.close();

          if(stmt!=null){

            stmt.close();

          }

          if(conn!=null){

            conn.close();

          }

        }

      }

      catch (SQLException ex1) {

      }

    }

 }

}

在这里要注意Q在执行前一定要先把oracle的驱动包攑ֈclass路径里,否则会报错的?/span>

 



hk2000c 2007-11-16 17:15 发表评论
]]>
SSO(Single Sign-on) in Action(上篇) http://m.tkk7.com/hk2000c/archive/2007/11/16/161048.htmlhk2000chk2000cFri, 16 Nov 2007 08:27:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/16/161048.htmlhttp://m.tkk7.com/hk2000c/comments/161048.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/16/161048.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/161048.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/161048.html阅读全文

hk2000c 2007-11-16 16:27 发表评论
]]>
JA-SIG CAS 资料 http://m.tkk7.com/hk2000c/archive/2007/11/16/161033.htmlhk2000chk2000cFri, 16 Nov 2007 07:50:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/11/16/161033.htmlhttp://m.tkk7.com/hk2000c/comments/161033.htmlhttp://m.tkk7.com/hk2000c/archive/2007/11/16/161033.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/161033.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/161033.htmlCAS (Central Authentication Service) ?Yale 大学?ITS 开发的一?JAVA 实现的开?/p>

?SSO(single sign-on) 的服?主要?.0Q到3.0为ja-sig)?/p>

关键?/p>

TGC(ticket-granting cookie)--------- 受权的票据证?/p>

KDC( Key Distribution Center ) ---------- 密钥发放中心

Service ticket(ST) --------- 服务据Q??KDC ?TGS 发放?M一?Workstation 都需要拥有一张有效的 Service Ticket 才能讉K域内部的应用 (Applications) ?如果能正接?Service Ticket Q说明在 CASClient-CASServer 之间的信dpdl被正确建立h , 通常Z张数字加密的证书

Ticket Granting tieckt(TGT) --------- 据授权据Q由 KDC ?AS 发放。即获取q样一张票据后Q以后申请各U其他服务票?(ST) 便不必再?KDC 提交w䆾认证信息 ( 准确术语?Credentials) ?/p>

authentication service (AS) --------- 认证用服务,索取 Crendential Q发?TGT

ticket-granting service (TGS) --------- 据授权服务Q烦?TGT Q发?ST

CAS 单点服务器的认证q程Q所有应用服务器收到应用h后,?ST ?TGT Q如果没有或不对Q{?CAS 认证服务器登陆页面,通过安全认证后得?ST ?TGT 再重定向到相兛_用服务器Q在会话生命周期之内如果再定向到别的应用Q将出示

ST ?TGT q行认证 , 注意 , 取得 TGT 的过E是通过 SSL 安全协议?( 换句话说是如果不用 ssl 协议 , 每访问一个应用服务,得重新到认证服务中心认证一?) Q关?SSL 的相xq可以查看附?.

白话描述 :

单点登陆 , 无非是提供l用户一ơ登?, 多个pȝ׃n用户信息的操?.

q个是怎么操作的呢 ? 有简单的Ҏ , 当用戯问其他系l的时?, 写个 URL 带上用户?ID ?PASS 提交到相应的pȝ可以了 . q也是一U方?/p>

?CAS 是怎么操作的呢 ? 或则?KRB(Kerberos 是一个加密认证协议,允许|络用户不用明文密码访问服务,一个普?
的协议实现包?LOGIN 服务存在伪造欺骗对 Key Distribution Center 的响??/p>

) 怎么操作的呢 ?

他ƈ不是很复?, 他先是徏立一?专门认证用户?服务 (SERVER) q个服务只做一件事 , 负责验证用户?ID ?PASS 是否是正?, 在正的情况提供用户一个名?TGT 的票?,

相当你要L乐场?, 首先你要在门口检查你的n?( ?CHECK 你的 ID ?PASS), 如果你通过验证 , 怹场的门卫 (AS) x供给你一张门?(TGT).

q张卡片的用处就是告?怹场的各个场所 , 你是通过正门q来 , 而不是后门偷爬进来的 , q且也是获取q入场所一把钥?.

好的 , 现在你有张卡 , 但是q对你来不重?, 因ؓ你来怹Z是ؓ了拿q张卡的 , 好的 , 我们向你的目的出?, ?, 你来C个摩天楼 , 你想q入玩玩 ,

q时摩天轮的服务?(client) 拦下?, 向你要求摩天轮的 (ST) 据 , 你说你只有一个门?(TGT), 好的 , 那你只要?TGT 攑֜一旁的据授权?(TGS) 上刷一?,

据授权?(TGS) 根据你现在所在的摩天?, l你一张摩天轮的票?(ST), ?, 你有摩天轮的据 , 现在你可以畅通无ȝq入摩天轮里游玩?.

当然如果你玩完摩天轮?, 惛_怹园的咖啡厅休息下 , 那你一样只要带着那张门卡 (TGT). 到相应的咖啡厅的据授权?(TGS) 刷一?, 得到咖啡厅的据 (ST) 可以进入咖啡厅

当你d怹场后 , 想用q张 TGT d打的回家的费?, 呵呵 , 对不?, 你的 TGT 已经q期?, 在你d怹场那d?, 你的 TGT 已l销毁了 ~

Yale CAS Server 的配|过E?/p>

CAS (Central Authentication Service) ?Yale 大学?ITS 开发的一?JAVA 实现的开?/p>

?SSO(single sign-on) 的服务。该服务是以一?java web app(eg:cas.war) 来进行服务的Q?/p>

使用旉要将 cas.war 发布C?servlet2.3 兼容的服务器上,q且服务器需要支?SSL Q?/p>

在需要用该服务的其他服务器Q客PQ只要进行简单的配置可以实?SSO 了?/p>

CAS 的客L可以有很多种Q因为验证的l果是以 XML 的格式返回的Q?CAS 的客L?/p>

打包q去的有 java,perl,python,asp,apache module {好几种客户端示例,你还可以Ҏ

需要实C个自q客户端,非常?!~

下面我们?tomcat 5.0 作ؓ CAS Server(server1) Q另外一?tomcat5.0 ?client(client1)

Zq行说明?/p>

1. 下蝲 cas-server ?cas-client( 可选,使用Q?/p>

http://www.ja-sig.org/downloads/cas/cas-server-3.0.5.zip

http://www.ja-sig.org/downloads/cas-clients/cas-client-java-2.1.1.zip

2. ?cas-server-3.0.5.zip 解压Qƈ?lib/cas.war 拯?server1 ?webapps ?/p>

3. 产生 SERVER 的证?/p>

PS: 参数与各pȝ本n一?/p>

%JAVA_HOME%\bin\keytool -delete -alias tomcat -keypass changeit

%JAVA_HOME%\bin\keytool -genkey -alias tomcat -keypass changeit -keyalg RSA

%JAVA_HOME%\bin\keytool -export -alias tomcat -keypass changeit -file %FILE_NAME%

%JAVA_HOME%\bin\keytool -import -file server.crt -keypass changeit -keystore %JAVA_HOME%/jre/lib/security/cacerts

%JAVA_HOME%\bin\keytool -import -file server.crt -keystore %JAVA_HOME%\jre\lib\security\cacerts

4. ?server1 配置 tomcat 使用 HTTPS

$CATALINA_HOME/conf/server.xml ?/p>

<Connector className="org.apache.coyote.tomcat5.CoyoteConnector"

port="8443" minProcessors="5" maxProcessors="75"

enableLookups="true" disableUploadTimeout="true"

acceptCount="100" debug="0" scheme="https"

secure="true">

<Factory className="org.apache.coyote.tomcat5.CoyoteServerSocketFactory"

keystoreFile="/path/to/your/keystore-file"

keystorePass="your-password" clientAuth="false" protocol="TLS" />

</Connector>

5. 在要使用 CAS 的客L client1 里设|(?servlets-examples q个 APP ZQ,我们使用

ServletFilter(CAS client 里提供的 ) 来实?SSO 的检查?/p>

修改 servlets-examples/WEB-INF/web.xml

<filter>

<filter-name>CASFilter</filter-name>

<filter-class>edu.yale.its.tp.cas.client.filter.CASFilter</filter-class>

<init-param>

<param-name>edu.yale.its.tp.cas.client.filter.loginUrl</param-name>

<param-value>https://your.cas.server.name(eg:server1):port/cas/login</param-value>

</init-param>

<init-param>

<param-name>edu.yale.its.tp.cas.client.filter.validateUrl</param-name>

<param-value>https://your.cas.server.name(eg:server1):port/cas/proxyValidate</param-value>

</init-param>

<init-param>

<param-name>edu.yale.its.tp.cas.client.filter.serviceUrl</param-name>

<param-value>your.client.server.ip(eg:127.0.0.1):port</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>CASFilter</filter-name>

<url-pattern>/servlet/*</url-pattern>

</filter-mapping>

PS: ?client 端配|?filter ?, 需要将 CAS ?filter 攑֜ web.xml 最上端 ,. 如果在你?web.xml 有类?encodingFilter ?filter 也需要将q个 filter 攑֜ CAS filter 下面 , 否则你会发现每次讉K旉需要你q行验证 .

6. ?cas-client-java-2.1.1.zip 解压Q把 java/lib/casclient.jar 拯?client1 服务器上?/p>

webapps/servlets-examples/WEB-INF/lib 目录下(如果没有徏一个)

7. 导出 SERVER 的证书,用来l所有需要用到的客户端导?/p>

keytool -export -file server.crt -alias my-alias-name -keystore keystore-file

8. 在客L?JVM 里导入信ȝ SERVER 的证?( Ҏ情况有可能需要管理员权限 )

keytool -import -keystore $JAVA_HOME/jre/lib/security/cacerts -file server.crt -alias my-alias-name

9.test & done.

?server1 ?client1 分别hQ检查启动的 LOG 是否正常Q如果一?OK Q就讉K

http://client1:8080/servlets-examples/servlet/HelloWorldExample

pȝ会自动蟩转到一个验证页面,随便输入一个相同的账号 , 密码Q严正通过之后׃讉K

到真正的 HelloWorldExample q个 servlet ?/p>

实现自已的认证代?(java 代码和相x?, 需?cas-server-3.0.5.jar ?)


package com.mcm.sso;

 

import org.jasig.cas.authentication.handler.support.AbstractUsernamePasswordAuthenticationHandler;

import org.jasig.cas.authentication.principal.UsernamePasswordCredentials;

import org.springframework.util.StringUtils;

 

public class MyUsernamePasswordAuthenticationHandler extends

AbstractUsernamePasswordAuthenticationHandler {

 

public boolean authenticateUsernamePasswordInternal(

final UsernamePasswordCredentials credentials) {

final String username = credentials.getUsername();

final String password = credentials.getPassword();

 

// 此处实现你的登陆验证代码

if (StringUtils.hasText(username) && StringUtils.hasText(password) ) {

getLog().debug(

" User [ " + username + " ] was successfully authenticated with ucix. " );

return true ;

}

 

getLog().debug( " User [ " + username + " ] failed authentication " );

 

return false ;

}

 

protected void afterPropertiesSetInternal() throws Exception {

super .afterPropertiesSetInternal();

}

}

 

然后这个类配置?deployerConfigContext.xml 文g?, 替代 <bean class="org.jasig.cas.authentication.handler.support.SimpleTestUsernamePasswordAuthenticationHandler" />

可能要用到数据库q接之类的配|,具体可参?spring framework 相关文档

?client 端取到登陆相关信息及dpȝ

1. 取得用用?ID

以下两种方式都可?/p>

session.getAttribute(CASFilter.CAS_FILTER_USER);

session.getAttribute("edu.yale.its.tp.cas.client.filter.user");

也可以直接取得认?java 对象

session.getAttribute(CASFilter.CAS_FILTER_RECEIPT);

session.getAttribute("edu.yale.its.tp.cas.client.filter.receipt");

JSP2.0 标准写法

<c:out value="${sessionScope['edu.yale.its.tp.cas.client.filter.user']}"/>

?jsp 中?CAS Tag Library 标签

除实C上功能完q可以实现登Zcȝ相关功能Q具体参?cas 官方文档

http://www.ja-sig.org/products/cas/client/jsp/index.html

附录

1 Q?SSL(Server Socket Layer) ?/p>

在网l上信息在源 - 宿的传递过E中会经q其它的计算机。一般情况下Q中间的计算Z会监听\q的信息。但在用网上银行或者进行信用卡交易的时候有可能被监视,从而导致个人隐U的泄露。由?Internet ?Intranet 体系l构的原因,L某些够读取ƈ替换用户发出的信息。随着|上支付的不断发展,Z对信息安全的要求来高。因?Netscape 公司提出?SSL 协议Q旨在达到在开攄l?(Internet) 上安全保密地传输信息的目的,q种协议?WEB 上获得了q泛的应用?之后 IETF(ietf.org) ?SSL 作了标准化,?RFC2246 Qƈ其UCؓ TLS Q?Transport Layer Security Q,从技术上Ԍ TLS1.0 ?SSL3.0 的差别非常微?/p>

2 Q?SSL 工作原理

SSL 协议使用不对U加密技术实C话双方之间信息的安全传递。可以实C息传递的保密性、完整性,q且会话双方能鉴别对方n份。不同于常用?http 协议Q我们在与网站徏?SSL 安全q接时?https 协议Q即采用 https://ip:port/ 的方式来讉K。当我们与一个网站徏?https q接Ӟ我们的浏览器?Web Server 之间要经q一个握手的q程来完成n份鉴定与密钥交换Q从而徏立安全连接。具体过E如下:

用户览器将?SSL 版本受加密设|参数、与 session 有关的数据以及其它一些必要信息发送到服务器?/p>

服务器将?SSL 版本受加密设|参数、与 session 有关的数据以及其它一些必要信息发送给览器,同时发给览器的q有服务器的证书。如果配|服务器?SSL 需要验证用戯n份,q要发出h要求览器提供用戯书?/p>

客户端检查服务器证书Q如果检查失败,提示不能建立 SSL q接。如果成功,那么l箋。客L览器ؓ本次会话生成 pre-master secret Qƈ其用服务器公钥加密后发送给服务器。如果服务器要求鉴别客户w䆾Q客Lq要再对另外一些数据签名后q将其与客户端证书一起发送给服务器?/p>

如果服务器要求鉴别客戯n份,则检查签|客戯书的 CA 是否可信。如果不在信d表中Q结束本ơ会话。如果检查通过Q服务器用自qU钥解密收到?pre-master secret Qƈ用它通过某些法生成本次会话?master secret ?/p>

客户端与服务器均使用?master secret 生成本次会话的会话密?( 对称密钥 ) 。在双方 SSL 握手l束后传递Q何消息均使用此会话密钥。这样做的主要原因是对称加密比非对称加密的运量低一个数量以上Q能够显著提高双方会话时的运速度?/p>

客户端通知服务器此后发送的消息都用这个会话密钥进行加密。ƈ通知服务器客L已经完成本次 SSL 握手?/p>

服务器通知客户端此后发送的消息都用这个会话密钥进行加密。ƈ通知客户端服务器已经完成本次 SSL 握手?/p>

本次握手q程l束Q会话已l徏立。双方用同一个会话密钥分别对发送以及接受的信息q行加、解密?



hk2000c 2007-11-16 15:50 发表评论
]]>
Request tomcat 包装c?org.apache.catalina.connector.Request 分析http://m.tkk7.com/hk2000c/archive/2007/10/27/156388.htmlhk2000chk2000cSat, 27 Oct 2007 11:52:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/10/27/156388.htmlhttp://m.tkk7.com/hk2000c/comments/156388.htmlhttp://m.tkk7.com/hk2000c/archive/2007/10/27/156388.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/156388.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/156388.html
JSESSIONID = 当前session L

org/apache/coyote/Request.java

基本装c,包括基本request 信息

其源代码在此可以查看 http://www.docjar.com/html/api/org/apache/coyote/Request.java.html

 public Request() {
72 
73          parameters.setQuery(queryMB);
74          parameters.setURLDecoder(urlDecoder);
75          parameters.setHeaders(headers);
76 
77          methodMB.setString("GET");
78          uriMB.setString("/");
79          queryMB.setString("");
80          protoMB.setString("HTTP/1.0");
81 
82      }
83 

开始初始化

回收
 // -------------------- Recycling --------------------
459
460
461     public void recycle() {
462         bytesRead=0;
463
464         contentLength = -1;
465         contentTypeMB = null;
466         charEncoding = null;
467         headers.recycle();
468         serverNameMB.recycle();
469         serverPort=-1;
470         localPort = -1;
471         remotePort = -1;
472
473         cookies.recycle();
474         parameters.recycle();
475
476         unparsedURIMB.recycle();
477         uriMB.recycle();
478         decodedUriMB.recycle();
479         queryMB.recycle();
480         methodMB.recycle();
481         protoMB.recycle();
482         //remoteAddrMB.recycle();
483         //remoteHostMB.recycle();
484
485         // XXX Do we need such defaults ?
486         schemeMB.recycle();
487         methodMB.setString("GET");
488         uriMB.setString("/");
489         queryMB.setString("");
490         protoMB.setString("HTTP/1.0");
491         //remoteAddrMB.setString("127.0.0.1");
492         //remoteHostMB.setString("localhost");
493
494         instanceId.recycle();
495         remoteUser.recycle();
496         authType.recycle();
497         attributes.clear();
498     }

伟大的method() Ҏ


 public MessageBytes method() {
184         return methodMB;
185     }
186     

  getMethod() Ҏ是从这里搞来的?br />
q有 org.apache.tomcat.util.http.MimeHeader 存放了所有的Header 信息


=== MimeHeaders ===
accept = image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
referer = http://localhost/user/userRegister.html
accept-language = zh-CN,en-US;q=0.5
content-type = application/x-www-form-urlencoded
ua-cpu = x86
accept-encoding = gzip, deflate
user-agent = Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; MAXTHON 2.0)
host = localhost
content-length = 70
connection = Keep-Alive
cache-control = no-cache
cookie = JSESSIONID=06820B9CA579BF64CC89C5E041864459









hk2000c 2007-10-27 19:52 发表评论
]]>
Design an e-commerce system data diagramhttp://m.tkk7.com/hk2000c/archive/2007/02/27/100976.htmlhk2000chk2000cTue, 27 Feb 2007 10:25:00 GMThttp://m.tkk7.com/hk2000c/archive/2007/02/27/100976.htmlhttp://m.tkk7.com/hk2000c/comments/100976.htmlhttp://m.tkk7.com/hk2000c/archive/2007/02/27/100976.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/100976.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/100976.htmlToday, I design an e-commerce system data diagram. Beacause of I using hibernate and XDoclet, I use the Class diagram instead of Data structure and ERP diagram. My strategy in J2EE system design is to clear the bussiness logic first, and design POJOs and their relations, finally, implement it with mature 3 or more tier web architecture.




hk2000c 2007-02-27 18:25 发表评论
]]>
SOA 技?/title><link>http://m.tkk7.com/hk2000c/archive/2006/08/10/62806.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Thu, 10 Aug 2006 07:49:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2006/08/10/62806.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/62806.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2006/08/10/62806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/62806.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/62806.html</trackback:ping><description><![CDATA[ <p>听到SOA很久了,军_ȝ?SOA ?br />研究一下,毕竟是好的?br /><br />资源<br /><br /><a >http://www.umlchina.com/News/Content/39.htm</a><br /><br /><br /><br />一些感惻I<br /><br />旧酒换新Ӟ像Web2.0。SOA 感觉上就像WebService 技术的再包装。加入了一些面向业务分割的理念Q应用pȝ能够以SOA理念开发?br /><br />q是一U实验中的东ѝ企业根本不兛_什么SOA技术如何,企业只关心,SOA能给他们带来什么?SOA q不是银弹,L功还有很长的一D\要走。期待更有h值的SOA 2.0 出现?br /><br /><br /><br /><br /><br /><br /><br /><br /></p> <img src ="http://m.tkk7.com/hk2000c/aggbug/62806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2006-08-10 15:49 <a href="http://m.tkk7.com/hk2000c/archive/2006/08/10/62806.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>全面从liferay的portal研究 转向 jetspeed2 ?liferay 的研I?/title><link>http://m.tkk7.com/hk2000c/archive/2006/08/08/62463.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Tue, 08 Aug 2006 15:05:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2006/08/08/62463.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/62463.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2006/08/08/62463.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/62463.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/62463.html</trackback:ping><description><![CDATA[Liferay 二次开发太困难Q花了N*N个小Ӟ除了搭徏了一套可以调试部|的环境之外Q部|了几个CZ实例之外Q几乎毫无徏树?br />liferay代码可读性是我见q最差的Q乍看觉得可能是反编译的代码。昏q去Q我要骂娘了。什么编码规范!呕了Q!Q?br />|上support 的效率非怽Q几乎没人帮忙,遇到问题直就是灾难。l下ȝ信心直快要破灭了?br /><br />Jetspeed 2 比较好?Q?源代码,文档Q二ơ开发比较容易?br />而且国内弄得Z多,可以怺交流支持Q不像liferay 一条小道走不到底的感觉?br /><br />不过Liferay q是比较好的一个项目,速度比jetspeed2 不知道快多少Q而且拥有很多很实用的portlet .<br />但愿 Jetspeed2 会做得更好。毕竟开源需要众人去做,才会有生命力?br /><br /><img src ="http://m.tkk7.com/hk2000c/aggbug/62463.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2006-08-08 23:05 <a href="http://m.tkk7.com/hk2000c/archive/2006/08/08/62463.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java技术经验积?/title><link>http://m.tkk7.com/hk2000c/archive/2006/08/08/62360.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Tue, 08 Aug 2006 07:25:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2006/08/08/62360.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/62360.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2006/08/08/62360.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/62360.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/62360.html</trackback:ping><description><![CDATA[准备每个知识点的几个例子Q梳理一下自q知识树结构,避免旉长了Q技术生?br /><br />暂时需要整理的知识点例子有<br /><br />tag<br /><br />jms<br /><br />oscache<br /><br />hiberante<br /><br />spring<br /><br />SWF spring web flow<br /><br />struts tiles<br /><br />axis webservice<br /><br />准备阅读相关的JSR标准<br />~写一个Axis的例?br /><br /><br />pdf liberay<br /><br />nutch search<br /><br />SSO<br /><br /><br /><img src ="http://m.tkk7.com/hk2000c/aggbug/62360.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2006-08-08 15:25 <a href="http://m.tkk7.com/hk2000c/archive/2006/08/08/62360.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSR-168 Portal 规范译 W??译节?/title><link>http://m.tkk7.com/hk2000c/archive/2006/07/12/jsr_168_s_ch8.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Wed, 12 Jul 2006 03:01:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2006/07/12/jsr_168_s_ch8.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/57761.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2006/07/12/jsr_168_s_ch8.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/57761.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/57761.html</trackback:ping><description><![CDATA[ <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US">Portlet </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的Ş态直白的_是</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">功能的表现Ş式。通常Q?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ他们自己功能的不同,执行不同的Q务以及生成不同的内容?/span> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态直接预C着他们担Q什么样的功能ƈ且将会显CZ么样的内宏V当</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">被调用的时候,</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器会ؓ其提供的一个的当前</span> <span lang="EN-US">portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态?/span> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">可以很方便的在处理一?/span> <span lang="EN-US">action</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">h的时候改变它的Ş态?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span>Portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">规范定义?/span> <span lang="EN-US">3</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态。他们分别是</span> <span lang="EN-US">VIEW</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Q?/span> <span lang="EN-US">EDIT</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以及</span> <span lang="EN-US">HELP</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">PortletMode</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">cd义了q些形态的帔R?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span>Portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态还用于对用L权限功能控制Q比方说一个未认证用户只能察看</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">VIEW</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以及</span> <span lang="EN-US">HELP</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态,而认证用户则能访?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">EDIT</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US">8.1 Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">VIEW</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span>Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">VIEW</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态的主要功能是通过生成标记语言来显C?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的当前状态。比方说Q一?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">VIEW</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态可能包含一C个页面,用户可以览或者做某些操作。它也可能仅仅是一张静态页面而不做Q何事情?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开发者可以简单的通过重蝲</span> <span lang="EN-US">GenericPortlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">doView()</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ来获得这功?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span>Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">必须支持</span> <span lang="EN-US">VIEW</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US">8.2 EDIT </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">EDIT</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态下面,</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应该提供相关的内容以及逻辑l用P以便能够让用户可以自定义</span> <span lang="EN-US">portlet </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">行ؓ。一?/span> <span lang="EN-US">EDIT </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态的</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应该?/span> <span lang="EN-US">1</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">到多个窗口,q样用户p从这些窗口进入他们自p定义的数据了?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通常Q?/span> <span lang="EN-US">EDIT</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态的</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会设|或者更?/span> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">参数。参?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">参数一节获得更多的l节?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开发者可以简单的通过重蝲</span> <span lang="EN-US">GenericPortlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">doEdit()</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ来获得这功?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不必支持</span> <span lang="EN-US">EDIT</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US">8.3 HELP</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">help</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态下面,</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应该提供</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">本n的相兛_助信息。一?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的帮助信息可以是介绍</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的完整帮助或者是内容相关的帮助文本?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">开发者可以简单的通过重蝲</span> <span lang="EN-US">GenericPortlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">doHelp()</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ来获得这功?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">不必支持</span> <span lang="EN-US">HELP</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US">8.4 portlet </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">自定义Ş?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span>Portlal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">的提供者可以自定义</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态用来提供自己指定的功能</span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">要用自定义</span> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态,首先需要在部v描述器中d</span> <span lang="EN-US">custom-portlet-mode</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">元素</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Q其ơ需要在q行期找到该形态的</span> <span lang="EN-US">portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现。如果在q行期间找不到该自定义Ş态的</span> <span lang="EN-US">portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">实现Q这?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">׃应该被调?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">打个比方Q?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">应用需要支?/span> <span lang="EN-US">clipsboard</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以及</span> <span lang="EN-US">config </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态的</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Q那么部|描q器里面可能q么写:</span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><portlet-app><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier">... </span> <span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><custom-portlet-mode><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><description>Creates content for Cut and Paste</description><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><name>clipboard</name><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"></custom-portlet-mode><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><custom-portlet-mode><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><description>Provides administration functions</description><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><name>config</name><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"></custom-portlet-mode><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier">... </span> <span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"></portlet-app><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在《扩?/span> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态》附录中列出了徏议的</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态的命名参考以及他们的使用参考。如?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在部|描q器中定义了一个自定义的Ş态,q且</span> <span lang="EN-US">portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器实现了这UŞ态的话,那么</span> <span lang="EN-US">Portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器可以立即自动地映这U支持Ş态?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US">8.5 GenericPorlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">渲染Ҏ的处?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <span style="mso-tab-count: 1">       </span>GenericPorlet </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过</span> <span lang="EN-US">render</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ来分发用Lhl?/span> <span lang="EN-US">doView , doEdit , doHelp </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ。这个指定Ş态分发的动作?/span> <span lang="EN-US">doDispatch</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里面都会指明。如?/span> <span lang="EN-US">portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器提供者需要支持一U新的Ş态,那么必须重蝲</span> <span lang="EN-US">doDispatch</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt; TEXT-INDENT: -21pt; mso-list: l0 level2 lfo1; tab-stops: list 21.0pt"> <span lang="EN-US" style="mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">8.6<span style="FONT: 7pt 'Times New Roman'">     </span></span> </span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">定义</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt"> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">通过在它的部|描q器内配|?/span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态来获得它能使用?/span> <span lang="EN-US">portal</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">容器支持的Ş态。每?/span> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">都必L?/span> <span lang="EN-US">VIEW</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态,而且</span> <span lang="EN-US">VIEW</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态无需特别指定?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">下面的例子显CZ一个配|?/span> <span lang="EN-US">Portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态的hQ?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier">...<o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><supports><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><mime-type>text/html</mime-type><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><portlet-mode>edit</portlet-mode><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><portlet-mode>help</portlet-mode><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier">... </span> <span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"></supports><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><supports><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><mime-type>text/vnd.wap.wml</mime-type><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><portlet-mode>help</portlet-mode><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier">... </span> <span lang="EN-US" style="FONT-SIZE: 12pt; mso-font-kerning: 0pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"></supports><o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-layout-grid-align: none" align="left"> <span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier">...<o:p></o:p></span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以上的配|说明了Q该</span> <span lang="EN-US">portlet</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> <span lang="EN-US">html</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标记语言下支?/span> <span lang="EN-US">edit ,help</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态,当然q支持默认的</span> <span lang="EN-US">view</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态。在</span> <span lang="EN-US">wml</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">语言环境下,支持</span> <span lang="EN-US">help</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">以及</span> <span lang="EN-US">view</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">形态?/span> <span lang="EN-US" style="mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US" style="mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> ===<br /></o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US"> <o:p> <br />以上是翻译节选,以后会陆l刊出其它章?br />Ƣ迎转蝲共同交流<br /><br /> </o:p> </span> </p> <img src ="http://m.tkk7.com/hk2000c/aggbug/57761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2006-07-12 11:01 <a href="http://m.tkk7.com/hk2000c/archive/2006/07/12/jsr_168_s_ch8.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JBoss装蝲应用出现log4j 装蝲错误http://m.tkk7.com/hk2000c/archive/2006/04/28/56714.htmlhk2000chk2000cFri, 28 Apr 2006 15:21:00 GMThttp://m.tkk7.com/hk2000c/archive/2006/04/28/56714.htmlhttp://m.tkk7.com/hk2000c/comments/56714.htmlhttp://m.tkk7.com/hk2000c/archive/2006/04/28/56714.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/56714.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/56714.html装蝲JBoss 应用的时候出现经典log错误 org.apache.commons.logging.LogConfigurationException: Class org.apache. commons.logging.impl.Log4JCategoryLog does not implement Log

查应用\?%App_path%/WEB-INF/lib Q把下面 log4j.jar以及 commons-logging.jar 均删除,问题解决

原理解释文章在以下位|?/p>

http://www.qos.ch/logging/thinkAgain.jsp

以前也遇到类似问?/p>

如果是tomcat 5.x 版本Q需要这样处?/p>

删除tomcat/webapps/%apps%/WEB-INF/lib/下面?br />commons-logging-api-1.0.4.jar ?br />然后换成

log4j.jar以及 commons-logging.jar



hk2000c 2006-04-28 23:21 发表评论
]]>
JAVA 安全三部曲之一 JAAS~程指南Q前)http://m.tkk7.com/hk2000c/archive/2006/03/23/jaas.htmlhk2000chk2000cThu, 23 Mar 2006 00:07:00 GMThttp://m.tkk7.com/hk2000c/archive/2006/03/23/jaas.htmlhttp://m.tkk7.com/hk2000c/comments/56715.htmlhttp://m.tkk7.com/hk2000c/archive/2006/03/23/jaas.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/56715.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/56715.html阅读全文

hk2000c 2006-03-23 08:07 发表评论
]]>
JDOM真的比DOM4j要慢么?http://m.tkk7.com/hk2000c/archive/2005/03/21/jdom.htmlhk2000chk2000cSun, 20 Mar 2005 21:00:00 GMThttp://m.tkk7.com/hk2000c/archive/2005/03/21/jdom.htmlhttp://m.tkk7.com/hk2000c/comments/56716.htmlhttp://m.tkk7.com/hk2000c/archive/2005/03/21/jdom.html#Feedback0http://m.tkk7.com/hk2000c/comments/commentRss/56716.htmlhttp://m.tkk7.com/hk2000c/services/trackbacks/56716.html阅读全文

hk2000c 2005-03-21 05:00 发表评论
]]>
使XML~程更简?--JDOM介绍及编E指?/title><link>http://m.tkk7.com/hk2000c/archive/2003/09/27/jdom_introduce.html</link><dc:creator>hk2000c</dc:creator><author>hk2000c</author><pubDate>Fri, 26 Sep 2003 23:19:00 GMT</pubDate><guid>http://m.tkk7.com/hk2000c/archive/2003/09/27/jdom_introduce.html</guid><wfw:comment>http://m.tkk7.com/hk2000c/comments/56720.html</wfw:comment><comments>http://m.tkk7.com/hk2000c/archive/2003/09/27/jdom_introduce.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/hk2000c/comments/commentRss/56720.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/hk2000c/services/trackbacks/56720.html</trackback:ping><description><![CDATA[ <p align="center"> <strong> <font size="5">JDOM 介绍及用指?/font> </strong> </p> <p> <strong> <font size="4">一、JDOM ?/font> </strong> <br />JDOM是一个开源项目,它基于树型结构,利用UJAVA的技术对XML文档实现解析、生成、序列化以及多种操作?br />JDOM 直接为JAVA~程服务。它利用更ؓ强有力的JAVA语言的诸多特性(Ҏ重蝲、集合概念以及映)Q把SAX和DOM的功能有效地l合h?br />在用设计上可能地隐藏原来使用XMLq程中的复杂性。利用JDOM处理XML文档是一件轻松、简单的事?br />JDOM ?000q的春天被Brett McLaughlin和Jason Hunter开发出来,以I补DOM及SAX在实际应用当中的不之处?br />q些不之处主要在于SAX没有文档修改、随问以及输出的功能Q而对于DOM来说QJAVAE序员在使用时来用v来总觉得不太方ѝ?br />DOM的缺点主要是来自于由于Dom是一个接口定义语aQIDLQ?它的d是在不同语言实现中的一个最低的通用标准Qƈ不是为JAVA特别设计的。JDOM的最新版本ؓJDOM Beta 9。最qJDOM被收录到JSR-102内,q标志着JDOM成ؓ了JAVAq_l成的一部分?/p> <p> <font size="5"> </font> <br /> <strong> <font size="4">二、JDOM 包概?/font> </strong> <br />JDOM是由以下几个包组成的<br />org.JDOM<br />org.JDOM.input<br />org.JDOM.output<br />org.JDOM.adapters<br />org.JDOM.transform</p> <p> <strong> <font size="4">三、JDOM c说?/font> </strong> </p> <p>org.JDOM<br />q个包里的类是你解析xml文g后所要用到的所有数据类型?br />Attribute<br />CDATA<br />Coment<br />DocType<br />Document<br />Element<br />EntityRef<br />Namespace<br />ProscessingInstruction<br />Text</p> <p>org.JDOM.transform<br />在涉及xslt格式转换时应使用下面?个类<br />JDOMSource<br />JDOMResult</p> <p>org.JDOM.input<br />输入c,一般用于文档的创徏工作<br />SAXBuilder<br />DOMBuilder<br />ResultSetBuilder</p> <p>org.JDOM.output<br />输出c,用于文档转换输出<br />XMLOutputter<br />SAXOutputter<br />DomOutputter<br />JTreeOutputter</p> <p>使用前注意事:<br />1.JDOM对于JAXP 以及 TRax 的支?br />JDOM 支持JAXP1.1Q你可以在程序中使用M的parser工具c?默认情况下是JAXP的parser?br />制定特别的parser可用如下形式<br />SAXBuilder parser <br />  = new SAXBuilder("org.apache.crimson.parser.XMLReaderImpl");<br /> Document doc = parser.build("<a _fcksavedurl="http://www.cafeconleche.org/">http://www.cafeconleche.org/</a>");<br /> // work with the document...<br />JDOM也支持TRaXQXSLT可通过JDOMSource以及JDOMResultcL转换Q参见以后章节)<br />2.注意在JDOM里文档(DocumentQ类由org.JDOM.Document 来表C。这要与org.w3c.dom中的Document区别开Q这2U格式如何{换在后面会说明?br />以下如无Ҏ均指JDOM里的Document?/p> <p> <br /> <strong> <font size="4">四、JDOM主要使用Ҏ</font> </strong> <br /> <strong>1.Ducumentc?/strong> <br />(1)Document的操作方法:<br />Element root = new Element("GREETING");<br />Document doc = new Document(root);<br />root.setText("Hello JDOM!");<br />或者简单的使用Document doc = new Document(new Element("GREETING").setText("Hello JDOM!t"));</p> <p>q点和DOM不同。Dom则需要更为复杂的代码Q如下:<br />DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();<br />DocumentBuilder builder =factory.newDocumentBuilder();<br />Document doc = builder.newDocument();<br />Element root =doc.createElement("root");<br />Text text = doc.createText("This is the root");<br />root.appendChild(text);<br />doc.appendChild(root);</p> <p> <br />注意事项QJDOM不允许同一个节点同时被2个或多个文档相关联,要在W?个文档中使用原来老文档中的节点的话。首先需要用detach()把这个节点分开来?br /><br />(2)从文件、流、系lID、URL得到Document对象Q?br />DOMBuilder builder = new DOMBuilder();<br />Document doc = builder.build(new File("jdom_test.xml"));</p> <p>SAXBuilder builder = new SAXBuilder();<br />Document doc = builder.build(url);<br />在新版本中DOMBuilder 已经Deprecated?DOMBuilder.builder(url)Q用SAX效率会比较快?/p> <p>q里举一个小例子Qؓ了简单v见,使用String对象直接作ؓxml数据源:</p> <p> public jdomTest() {<br />    String textXml = null;<br />    textXml = "<note>";<br />    textXml = textXml +<br />        "<to>aaa</to><from>bbb</from><heading>ccc</heading><body>ddd</body>";<br />    textXml = textXml + "</note>";<br />    SAXBuilder builder = new SAXBuilder();<br />    Document doc = null;<br />    Reader in= new StringReader(textXml);<br />    try {<br />      doc = builder.build(in);<br />      Element root = doc.getRootElement();<br />      List ls = root.getChildren();//注意此处取出的是root节点下面的一层的Element集合<br />      for (Iterator iter = ls.iterator(); iter.hasNext(); ) {<br />        Element el = (Element) iter.next();<br />        if(el.getName().equals("to")){<br />         System.out.println(el.getText());<br />        }<br />      }<br />    }<br />    catch (IOException ex) {<br />      ex.printStackTrace();<br />    }<br />    catch (JDOMException ex) {<br />      ex.printStackTrace();<br />    }<br />  }</p> <p>很简单把?/p> <p> <br />(3)DOM的document和JDOM的Document之间的相互{换用方法,单!<br />DOMBuilder builder = new DOMBuilder();<br />org.jdom.Document jdomDocument = builder.build(domDocument);<br />// work with the JDOM document?/p> <p>DOMOutputter converter = new DOMOutputter();<br />org.w3c.dom.Document domDocument = converter.output(jdomDocument);<br />// work with the DOM document?/p> <p> <strong>2.XML文档输出</strong> <br />XMLOutPutterc:<br />JDOM的输出非常灵z?支持很多Uio格式以及风格的输?br />Document doc = new Document(...);<br />XMLOutputter outp = new XMLOutputter();<br />// Raw output<br />outp.output(doc, fileOutputStream);<br />// Compressed output<br />outp.setTextTrim(true);<br />outp.output(doc, socket.getOutputStream());<br />// Pretty output<br />outp.setIndent(" ");<br />outp.setNewlines(true);<br />outp.output(doc, System.out);<br />......<br />详细请参阅最新的JDOM API手册</p> <p> <br /> <strong>3.Element c:</strong> <br />(1)览Element?br />//获得根元素element<br />Element root = doc.getRootElement();<br />// 获得所有子元素的一个list<br />List allChildren = root.getChildren();<br />// 获得指定名称子元素的list<br />List namedChildren = root.getChildren("name");<br />//获得指定名称的第一个子元素<br />Element child = root.getChild("name");<br />Q这里的List是java.util.ListQ?/p> <p>JDOMl了我们很多很灵zȝ使用Ҏ来管理子元素<br />List allChildren = root.getChildren();<br />// 删除W四个子元素<br />allChildren.remove(3);<br />// 删除叫“jack”的子元?br />allChildren.removeAll(root.getChildren("jack"));</p> <p>root.removeChildren("jack"); // 便捷写法<br />// 加入<br />allChildren.add(new Element("jane"));</p> <p>root.addContent(new Element("jane")); // 便捷写法<br />allChildren.add(0, new Element("first"));</p> <p> <br />(2)UdElements:<br />在JDOM里很?br />Element movable = new Element("movable");<br />parent1.addContent(movable); // place<br />parent1.removeContent(movable); // remove<br />parent2.addContent(movable); // add</p> <p>在Dom?br />Element movable = doc1.createElement("movable");<br />parent1.appendChild(movable); // place<br />parent1.removeChild(movable); // remove<br />parent2.appendChild(movable); // 出错!</p> <p>补充Q?br />U错?br />JDOM的Element构造函敎ͼ以及它的其他函数Q会查element是否合法?br />而它的add/removeҎ会检查树l构Q检查内容如下:<br />1.在Q何树中是否有回环节点<br />2.是否只有一个根节点<br />3.是否有一致的命名I间QNamespacesQ?/p> <p> </p> <p>(3)Element的text内容d<br /><description><br />A cool demo<br /></description></p> <p>// The text is directly available<br />// Returns "\n A cool demo\n"<br />String desc = element.getText();</p> <p>// There's a convenient shortcut<br />// Returns "A cool demo"<br />String desc = element.getTextTrim();</p> <p>(4)Elment内容修改<br />element.setText("A new description");<br />3.可正解释特D字W?br />element.setText("<xml> content");<br />4.CDATA的数据写入、读?br />element.addContent(new CDATA("<xml> content"));<br />String noDifference = element.getText();</p> <p>混合内容<br />element可能包含很多U内容,比如?/p> <p><table><br /><!-- Some comment --><br />Some text<br /><tr>Some child element</tr><br /></table></p> <p>取table的子元素tr<br />String text = table.getTextTrim();<br />Element tr = table.getChild("tr");</p> <p>也可使用另外一个比较简单的Ҏ<br />List mixedCo = table.getContent();<br />Iterator itr = mixedCo.iterator();<br />while (itr.hasNext()) {<br />Object o = i.next();<br />if (o instanceof Comment) {<br />...<br />}<br />// q里可以写成Comment, Element, Text, CDATA,ProcessingInstruction, 或者是EntityRef的类?br />}<br />// 现在U除Comment,注意q里游标应ؓ1。这是由于回车键也被解析成Textcȝ~故,所以Comment应??br />mixedCo.remove(1);</p> <p> </p> <p> <strong>4.Attributec?/strong> <br /><table width="100%" border="0"> </table><br />//获得attribute<br />String width = table.getAttributeValue("width");<br />int border = table.getAttribute("width").getIntValue();<br />//讄attribute<br />table.setAttribute("vspace", "0");<br />// 删除一个或全部attribute<br />table.removeAttribute("vspace");<br />table.getAttributes().clear();</p> <p> </p> <p> <strong>5.处理指o(Processing Instructions)操作</strong> <br />一个Pls的例?br /><?br?><br /><?cocoon-process type="xslt"?><br />          |        |<br />          |        |<br />        目标     数据</p> <p>处理目标名称(Target)<br />String target = pi.getTarget();<br />获得所有数据(dataQ,在目标(targetQ以后的所有数据都会被q回?br />String data = pi.getData();<br />获得指定属性的数据<br />String type = pi.getValue("type");<br />获得所有属性的名称<br />List ls = pi.getNames();</p> <p> <strong>6.命名I间操作<br /></strong><xhtml:html <br /> xmlns:xhtml="<a _fcksavedurl="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>"><br /><xhtml:title>Home Page</xhtml:title><br /></xhtml:html></p> <p>Namespace xhtml = Namespace.getNamespace("xhtml", "<a _fcksavedurl="http://www.w3.org/1999/xhtml">http://www.w3.org/1999/xhtml</a>");<br />List kids = html.getChildren("title", xhtml);<br />Element kid = html.getChild("title", xhtml);<br />kid.addContent(new Element("table", xhtml));</p> <p> <strong>7.XSLT格式转换</strong> <br />使用以下函数可对XSLT转换<br />最后如果你需要用w3c的Document则需要{换一下?br />public static Document transform(String stylesheetQDocument in)<br />                                        throws JDOMException {<br />     try {<br />       Transformer transformer = TransformerFactory.newInstance()<br />                             .newTransformer(new StreamSource(stylesheet));<br />       JDOMResult out = new JDOMResult();<br />       transformer.transform(new JDOMSource(in), out);<br />       return out.getDeocument();<br />     }<br />     catch (TransformerException e) {<br />       throw new JDOMException("XSLT Trandformation failed", e);<br />     }<br />   }</p> <p>参考书目:</p> <p>1.JDOM官方|站Q?<a _fcksavedurl="http://www.jdom.org">http://www.jdom.org</a></p> <p>2.<<Processing XML with Java>> Elliotte Rusty Harold 2002</p> <p>3.JDOM API Documentation</p> <p>4.<<JDOM Makes XML Easy>>Jason Hunter Co-Creator JDOM Project</p> <p>5.WSDP Tutorial </p> <p> </p> <p> </p> <p> </p> <p> </p> <a > </a> <img src ="http://m.tkk7.com/hk2000c/aggbug/56720.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/hk2000c/" target="_blank">hk2000c</a> 2003-09-27 07:19 <a href="http://m.tkk7.com/hk2000c/archive/2003/09/27/jdom_introduce.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://m.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://13813855.com" target="_blank">˾Ʒձרһ</a>| <a href="http://tccqdy.com" target="_blank">޾Ʒmv߹ۿ</a>| <a href="http://haiholr.com" target="_blank">www޾Ʒþþ</a>| <a href="http://wua72.com" target="_blank">Ʒһ߹ۿ</a>| <a href="http://szyxfhm.com" target="_blank">ƬӰԺۿ</a>| <a href="http://www003924.com" target="_blank">ҰƵ</a>| <a href="http://km9c.com" target="_blank">һɫþۺ޾Ʒ </a>| <a href="http://48eh.com" target="_blank">ĻͼƬ</a>| <a href="http://hn-hshb.com" target="_blank">þù߳׽ѹۿ</a>| <a href="http://bjdxpx.com" target="_blank">޾ƷŮþ7777777</a>| <a href="http://pchbgs.com" target="_blank">AV˾Ʒ߹ۿ</a>| <a href="http://paweax.com" target="_blank">vaƷѹۿ</a>| <a href="http://gzmandala.com" target="_blank">ƵַѲ</a>| <a href="http://sjmthanks.com" target="_blank">Ļһȥ̨</a>| <a href="http://tzfzs.com" target="_blank">2020Ʒۺ</a>| <a href="http://mmstom.com" target="_blank">޹Ʒ߹ۿ</a>| <a href="http://55118885.com" target="_blank">ţƷ޳avƬ</a>| <a href="http://gdbobo.com" target="_blank">ɫwwwƵ߹ۿ</a>| <a href="http://hljjlhl.com" target="_blank">һëƬƬƵֻ</a>| <a href="http://www045888.com" target="_blank">ĻӰӾþþ</a>| <a href="http://wo93xyz.com" target="_blank">Ļѹۿ</a>| <a href="http://1992zyzp.com" target="_blank">һ߲߲</a>| <a href="http://26cgw.com" target="_blank">avƬ߹ۿ</a>| <a href="http://35469642.com" target="_blank">ɫϰƵ߹</a>| <a href="http://1000hu.com" target="_blank">޾Ʒ߹ۿ</a>| <a href="http://xmllhb.com" target="_blank">˳ɵӰԺ߹ۿ</a>| <a href="http://hssw1688.com" target="_blank">AV뾫ƷһٶӰԺ</a>| <a href="http://jiayila.com" target="_blank">AVպAV</a>| <a href="http://56aaaa.com" target="_blank">պĻպ </a>| <a href="http://222dv.com" target="_blank">˳ӰԺ߸</a>| <a href="http://masfd.com" target="_blank">޵һ</a>| <a href="http://qzllw.com" target="_blank">˸һþ</a>| <a href="http://xiaoduanfa.com" target="_blank">޹ۺרߵӰ</a>| <a href="http://583s.com" target="_blank">޾Ʒ</a>| <a href="http://cxljdz.com" target="_blank">߹ۿ</a>| <a href="http://ytsp88.com" target="_blank">ִִֺƵ</a>| <a href="http://626393.com" target="_blank">˳վ߹ۿ</a>| <a href="http://siqingsizu.com" target="_blank">þþ97ɫ</a>| <a href="http://pecbj.com" target="_blank">þþƷƵ</a>| <a href="http://zjfxjy.com" target="_blank">޸Ļ</a>| <a href="http://9akk.com" target="_blank">91۲޾Ʒ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>