??xml version="1.0" encoding="utf-8" standalone="yes"?>精品国产亚洲AV麻豆,2048亚洲精品国产,亚洲A∨精品一区二区三区http://www.tkk7.com/sheldonsun/zh-cnSun, 11 May 2025 17:52:27 GMTSun, 11 May 2025 17:52:27 GMT60struts2 基础http://www.tkk7.com/sheldonsun/archive/2011/03/29/347181.htmlSheldon SunSheldon SunTue, 29 Mar 2011 04:07:00 GMThttp://www.tkk7.com/sheldonsun/archive/2011/03/29/347181.htmlhttp://www.tkk7.com/sheldonsun/comments/347181.htmlhttp://www.tkk7.com/sheldonsun/archive/2011/03/29/347181.html#Feedback0http://www.tkk7.com/sheldonsun/comments/commentRss/347181.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/347181.html
  • action extends ActionSupport abstract class, because it already provide some default operation(input, createErrorMessage).
  • property is set by reflect to action, and pass to jsp(jsp is filled with these properties, jsp is a servlet, what it returned to user is HTML file)
  • static validate happened in action method(override ActionSupport method), dynamic validation happened in action layer.
  • change dynamic property file value in this way : thankyou=Thank you for registerling %{personBean.firstName}, Resource file can be deployed in action layer, package layer and global layer
  • exception can be configured in bellow way:  <global-exception-mappings>
     <exception-mapping exception="org.apache.struts.register.exceptions.SecurityBreachException" result="securityerror" />
      <exception-mapping exception="java.lang.Exception" result="error" />
       </global-exception-mappings>
     
      <global-results>
            <result name="securityerror">/securityerror.jsp</result>
       <result name="error">/error.jsp</result>
       </global-results>
  • Wildcard Method Selection: flexible but not useful(<action name="*Person" class="org.apache.struts.tutorials.wildcardmethod.action.PersonAction" method="{1}">)
  • integrate spring & struts 2 way: use spring plugin, main point is who to maintain action creation(spring || action), better choice is spring, you can enjoy great function of spring.
  • Add Convention Plugin to so that you can use annotation
  • intercepter can be configured in action level and package level.


  • Sheldon Sun 2011-03-29 12:07 发表评论
    ]]>
    ?用Spring快速开发jms应用QJBOSS服务器)http://www.tkk7.com/sheldonsun/archive/2011/03/23/346859.htmlSheldon SunSheldon SunWed, 23 Mar 2011 06:49:00 GMThttp://www.tkk7.com/sheldonsun/archive/2011/03/23/346859.htmlhttp://www.tkk7.com/sheldonsun/comments/346859.htmlhttp://www.tkk7.com/sheldonsun/archive/2011/03/23/346859.html#Feedback0http://www.tkk7.com/sheldonsun/comments/commentRss/346859.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/346859.html 异步q程通信是面向服务架?SOA)一个重要的l成部分Q因Z业里很多pȝ通信Q特别是与外部组l间的通信Q实质上都是异步的?a style="color: rgb(52,104,164)" target="_blank">Java消息服务(JMS)是用于编写用异步消息传递的JEE应用E序的API。传l的使用JMS APIq行消息传递的实现包括多个步骤Q例如JNDI查询队列q接工厂和Queue资源Q在实际发送和接收消息前创Z个JMS会话?

       Spring框架则简化了使用JEElg(包括JMS)的Q务。它提供的模板机刉藏了典型的JMS实现的细节,q样开发h员可以集中精力放在处理消息的实际工作中,而不用担心如何去创徏Q访问或清除JMS资源?/p>

       本文对Spring JMS API作一个概qͼq过一个运行在JBoss MQ服务器上的web例程来介l如何用Spring JMS API来异步处理(发送和接收Q消息。我通过传统JMS实现和Spring JMS实现两者间的比较,来展CZ用Spring JMS处理消息是如何的单和灉|?/p>

    异步消息传递和面向服务架构

      在现实中Q大多数webh都是同步处理的。例如,当用戯d一个网站,首先输入用户名和密码Q然后服务器验证d合法性。如果验证成功,E序允许该用户q入|站。这里,dh在从客户端接收以后被x处理了。信用卡验证是另一个同步处理的例子Q只有服务器证实输入的信用卡h有效的,同时客户在帐户上有够的存款Q客h被允许l操作。但是让我们思考一下在序处理pȝ上的支付l算步骤。一旦系l证实该用户信用卡的信息是准的Qƈ且在帐户上有_的资金,׃必等到所有的支付l节落实、{账完成。支付结可以异步方式进行,q样客户可以l箋q行核查操作?/p>

       需要比典型同步h耗费更长旉的请求,可以使用异步处理。另一个异步处理的例子是,在本地贷Ƒ֤理程序中Q提交至自动扉KpȝQAUSQ的信用h处理q程。当借方提交h甌后,抉|公司会向AUS发送请求,以获取信用历史记录。由于这个请求要求得到全面而又详细的信用报告,包括借方C和过ȝ帐户Q最q的付款和其他胦务资料,服务器需要耗费较长的时_几小时或着有时甚至是几天)来对q些h作出响应。客LE序Q应用)要与服务器连接ƈ耗费如此长的旉来等待结果,q是毫无意义的。因此通信应该是异步发生的Q也是Q一旦请求被提交Q它p攄在队列中Q同时客L与服务器断开q接。然后AUS服务从指定的队列中选出hq行处理Qƈ处理得到的消息攄在另一个消息队列里。最后,客户端程序从q个队列中选出处理l果Q紧接着处理q个信用历史数据?/p>

    JMS

       如果您用过JMS代码Q您会发现它与JDBC或JCA很像。它所包含的样本代码创建或JMS资源对象回溯Q得每一ơ您需要写一个新cL发送和接收消息Ӟ都具有更好的代码密集性和重复性。以下序列显CZ传统JMS实现所包括的步骤:

    1. 创徏JNDI初始上下文(contextQ?/li>
    2. 从JNDI上下文获取一个队列连接工厂?/li>
    3. 从队列连接工厂中获取一个Quene?/li>
    4. 创徏一个Session对象?/li>
    5. 创徏一个发送者(senderQ或接收者(receiverQ对象?/li>
    6. 使用步骤5创徏的发送者或接收者对象发送或接收消息?/li>
    7. 处理完消息后Q关闭所有JMS资源?/li>

    您可以看刎ͼ步骤6是处理消息的唯一地方。其他步骤都只是理与实际业务要求无关的JMS资源Q但是开发h员必ȝ写ƈl护q些额外步骤的代码?/p>

    Spring JMS

       Spring框架提供了一个模板机制来隐藏Java APIs的细节。JEE开发h员可以用JDBCTemplate和JNDITemplatecL分别讉K后台数据库和JEE资源Q数据源Q连接池Q。JMS也不例外。Spring提供JMSTemplatec,因此开发h员不用ؓ一个JMS实现ȝ写样本代码。接下来是在开发JMS应用E序时Spring所h一些的优势?/p>

    1. 提供JMS抽象APIQ简化了讉K目标Q队列或主题Q和向指定目标发布消息时JMS的用?/li>
    2. JEE开发h员不需要关心JMS不同版本Q例如JMS 1.0.2与JMS 1.1Q之间的差异?/li>
    3. 开发h员不必专门处理JMS异常Q因为Spring为所有JMS异常提供了一个未l检查的异常Qƈ在JMS代码中重新抛出?/li>

    CZE序

            说明Q因为只是ؓ了演C如何用spring~写jms的应用,所以本例没有什么实际用途?/p>

            E序功能QMessageProducer.javaҎ一用户信息产生一个消息发送到 JMS ProviderQ由MessageConsumer.java接收?/p>

    1.在Jboss里配|XML文g创徏一个新的JMS provider?br /> 打开位于%JBOSS_HOME%server\default\deploy\jms文g夹下的jbossmq-destinations-service.xml文gQ加入以下代码片断:
     <!--  Register User Send/Receive Queue  -->
     <mbean code="org.jboss.mq.server.jmx.Queue"
       name="jboss.mq.destination:service=Queue,name=registerUserQueue">
       <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
     </mbean>
     <!--  Register User Send/Receive Topic  -->
     <mbean code="org.jboss.mq.server.jmx.Topic"
      name="jboss.mq.destination:service=Topic,name=registerUserTopic">
       <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
     </mbean>
    2.在spring的配|文件中配置JMSlg的具体细节?br />  Q?QJNDI上下文是取得JMS资源的v始位|,因此首先我们要配|JNDI模板Q?br />     <!-- JNDI上下?它是取得JMS资源的v始位|? -->
       <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
        <property name="environment">
         <props>
          <prop key="java.naming.factory.initial">
           org.jnp.interfaces.NamingContextFactory
          </prop>
          <prop key="java.naming.provider.url">localhost</prop>
          <prop key="java.naming.factory.url.pkgs">
           org.jnp.interfaces:org.jboss.naming
          </prop>
         </props>
        </property>
       </bean>
       注意Q此JNDI模板用到了org.jnp.interfaces.NamingContextFactory所以要?JBOSS_HOME%\client下的jbossall-client.jar加到你的目的classpath中?br /> Q?Q配|连接工厂:
       <!-- JMSq接工厂 -->
         <bean id="jmsConnectionFactory"class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiTemplate">
         <ref bean="jndiTemplate" />
        </property>
        <property name="jndiName">
         <value>XAConnectionFactory</value>
        </property>
       </bean>
       注意QXAConnectionFactoryq个JNDI名字是在%JBOSS_HOME%server\default\deploy\jms文g夹下的jms-ds.xml中定义的(它是由JBoss指定??br />  Q?Q配|JmsTemplatelg。在例程中我们用JmsTemplate102。同时用defaultDestination属性来指定JMS目标?br />   <!-- JMS模板配置 -->
      <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate102">
       <property name="connectionFactory" ref="jmsConnectionFactory" />
       <property name="defaultDestination" ref="destination" />
       <property name="pubSubDomain">
        <value>true</value>
       </property>
       <!-- {待消息的时?ms) -->
       <property name="receiveTimeout">
             <value>30000</value>
          </property>
      </bean>
      注意Q如果用topic-subscribe(主题订阅)模式Q该模板的pubSubDomain属性gؓtrue;若用PToP(点对?模式QpubSubDomain属性gؓfalse或不配置该属性?br />  (4)定义一个JMS目标来发送和接收消息:
      <bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">
       <property name="jndiTemplate">
        <ref bean="jndiTemplate" />
       </property>
       <property name="jndiName">
        <value>topic/registerUserTopic</value>
       </property>
      </bean>
     (5)配置发送者和接收者组?
      <!-- 消息发布?-->
      <bean id="msgProducer" class="com.boco.jms.MessageProducer">
       <property name="jmsTemplate" ref="jmsTemplate" />
      </bean>
      <!-- 消息接收?-->
      <bean id="msgConsumer" class="com.boco.jms.MessageConsumer">
       <property name="jmsTemplate" ref="jmsTemplate" />
      </bean>
    3.相应的类:
     (1). User对象?br />    /**
       *  User.java
       *  created on Jul 2, 2006
       *  Copyrights 2006 BOCO,Inc. All rights reserved.
       */
      package com.boco.dto;
      
      import java.io.Serializable;
      
      /**
       * desc: 用户信息 Bean
       * @author qiujy
       */
      public class User {
       private int id;
       private String username;
       private String password;
       private String email;
       
       public User(){}
       
       //以下为Getter,setterҎ?br />    ......
      }
      
     (2).消息生者:
       /**
       *  MessageProducer.java
       *  created on Jul 22, 2006
       *  Copyrights 2006 BOCO,Inc. All rights reserved.
       */
      package com.boco.jms;
      
      import javax.jms.JMSException;
      import javax.jms.MapMessage;
      import javax.jms.Message;
      import javax.jms.Session;
      
      import org.springframework.jms.core.JmsTemplate;
      import org.springframework.jms.core.MessageCreator;
      
      import com.boco.dto.User;
      
      /**
       * desc:消息生?br />    * @author qiujy
       *
       */
      public class MessageProducer {
       /** JMS模板 */
       private JmsTemplate jmsTemplate;
       
       public void setJmsTemplate(JmsTemplate jmsTemplate){
        this.jmsTemplate = jmsTemplate;
       }
       
       public void sendMessage(final User user){
        //调用模板的send来发送消?br />     jmsTemplate.send(new MessageCreator(){
      
         public Message createMessage(Session session) throws JMSException {
          //构造一个要发送的消息
          MapMessage message = session.createMapMessage();
           message.setInt("id", user.getId());
           message.setString("username", user.getUsername());
           message.setString("password", user.getPassword());
           message.setString("email", user.getEmail());
          System.out.println("send success!!");
          return message;
         }
        });
       }
      }
      
     (3).消息消费者:
      /**
       *  MessageConsumer.java
       *  created on Jul 22, 2006
       *  Copyrights 2006 BOCO,Inc. All rights reserved.
       */
      package com.boco.jms;
      
      import javax.jms.JMSException;
      import javax.jms.MapMessage;
      
      import org.springframework.jms.core.JmsTemplate;
      
      import com.boco.dto.User;
      
      /**
       * desc:消息消费?br />    * @author qiujy
       *
       */
      public class MessageConsumer {
       /** JMS模板 */
       private JmsTemplate jmsTemplate;
       
       public void setJmsTemplate(JmsTemplate jmsTemplate){
        this.jmsTemplate = jmsTemplate;
       }
       
       public User receiveMessage(){
        //参数为Destination的JNDI名字L前面的模式类型标?br />     //MapMessage msg = (MapMessage)jmsTemplate.receive("registerUserQueue");
        MapMessage msg = (MapMessage)jmsTemplate.receive("registerUserTopic");
        User user = new User();
        
        try {
         user.setId(msg.getInt("id"));
         user.setUsername(msg.getString("username"));
         user.setPassword(msg.getString("password"));
         user.setEmail(msg.getString("email"));
        } catch (JMSException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
        
        return user;
       }
      }

     (4).试用例Q?br />    //======== 生者测试用?===============
       /**
       *  TestMsgProducer.java
       *  created on Jul 22, 2006
       *  Copyrights 2006 BOCO,Inc. All rights reserved.
       */
      package com.boco.jms;
      
      import junit.framework.TestCase;
      
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      import com.boco.dto.User;
      
      /**
       * desc:
       * @author qiujy
       *
       */
      public class TestMsgProducer extends TestCase {
      
       private ApplicationContext context;
       /**
        * @param arg0
        */
       public TestMsgProducer(String arg0) {
        super(arg0);
        context = new ClassPathXmlApplicationContext("applicationContext_jms.xml");
       }
      
       /* (non-Javadoc)
        * @see junit.framework.TestCase#setUp()
        */
       protected void setUp() throws Exception {
        super.setUp();
       }
      
       /* (non-Javadoc)
        * @see junit.framework.TestCase#tearDown()
        */
       protected void tearDown() throws Exception {
        super.tearDown();
       }
      
       /**
        * Test method for {@link com.boco.jms.MessageProducer#sendMessage(com.boco.dto.User)}.
        */
       public void testSendMessage() {
        User user = new User();
        user.setId(132);
        user.setUsername("JMSTest");
        user.setPassword("password");
        user.setEmail("support@boco.com.cn");
        
        MessageProducer producer = (MessageProducer)context.getBean("msgProducer");
        
        producer.sendMessage(user);
        
       }
      
      }

      //============ 消费者测试用?===============
      /**
       *  TestMsgConsumer.java
       *  created on Jul 22, 2006
       *  Copyrights 2006 BOCO,Inc. All rights reserved.
       */
      package com.boco.jms;
      
      import junit.framework.TestCase;
      
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      import com.boco.dto.User;
      
      /**
       * desc:
       * @author qiujy
       *
       */
      public class TestMsgConsumer extends TestCase {
       private ApplicationContext context;
       /**
        * @param arg0
        */
       public TestMsgConsumer(String arg0) {
        super(arg0);
        context = new ClassPathXmlApplicationContext("applicationContext_jms.xml");
       }
      
       /* (non-Javadoc)
        * @see junit.framework.TestCase#setUp()
        */
       protected void setUp() throws Exception {
        super.setUp();
       }
      
       /* (non-Javadoc)
        * @see junit.framework.TestCase#tearDown()
        */
       protected void tearDown() throws Exception {
        super.tearDown();
       }
      
       /**
        * Test method for {@link com.boco.jms.MessageConsumer#receiveMessage()}.
        */
       public void testReceiveMessage() {
        MessageConsumer consumer = (MessageConsumer)context.getBean("msgConsumer");
        User user = consumer.receiveMessage();
        assertNotNull(user);
        System.out.println( "id========" + user.getId()
            + "\nname======" + user.getUsername()
            + "\npassword==" + user.getPassword()
            + "\nemail=====" + user.getEmail());
       }
      
      }



    Sheldon Sun 2011-03-23 14:49 发表评论
    ]]>
    concurrenthttp://www.tkk7.com/sheldonsun/archive/2011/03/23/346852.htmlSheldon SunSheldon SunWed, 23 Mar 2011 05:25:00 GMThttp://www.tkk7.com/sheldonsun/archive/2011/03/23/346852.htmlhttp://www.tkk7.com/sheldonsun/comments/346852.htmlhttp://www.tkk7.com/sheldonsun/archive/2011/03/23/346852.html#Feedback0http://www.tkk7.com/sheldonsun/comments/commentRss/346852.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/346852.htmlAVA后台E序设计及UTIL.CONCURRENT包的应用


    摘要 : 在很多Y仉目中QJAVA语言常常被用来开发后台服务程序。线E池技术是提高q类E序性能的一个重要手Dc在实践中,该技术已l被q泛的用。本文首?对设计后台服务程序通常需要考虑的问题进行了基本的论qͼ随后介绍了JAVAU程池的原理、用和其他一些相关问题,最后对功能强大的JAVA开放源码线 E池包util.concurrent 在实际编E中的应用进行了详细介绍?br /> 关键? JAVAQ线E池Q后台服务程序;util.concurrent



    1 引言
    在Y仉目开发中Q许多后台服务程序的处理动作程都具有一个相同点Q就是:接受客户端发来的hQ对hq行一些相关的处理Q最后将处理l果q回l客?端。这些请求的来源和方式可能会各不相同Q但是它们常帔R有一个共同点Q数量巨大,处理旉短。这cL务器在实际应用中h较大的普遍性,如web服务 器,短信服务器,DNS服务器等{。因此,研究如何提高此类后台E序的性能Q如何保证服务器的稳定性以及安全性都h重要的实用h倹{?br />
    2 后台服务E序设计
    2.1 关于设计原型
    构徏服务器应用程序的一个简单的模型是:启动一个无限@环,循环里放一个监听线E监听某个地址端口。每当一个请求到辑ְ创徏一个新U程Q然后新U程求服务,监听U程q回l箋监听?br /> 单D例如下:
    import java.net.*;
    public class MyServer extends Thread{
    public void run(){
    try{
    ServerSocket server=null;
    Socket clientconnection=null;
    server = new ServerSocket(8008);//监听某地址端口?br /> while(true){q入无限循环
    clientconnection =server.accept();//收取h
    new ServeRequest(clientconnection).start();//启动一个新服务U程q行服务
    ……
    }
    }catch(Exception e){
    System.err.println("Unable to start serve listen:"+e.getMessage());
    e.printStackTrace();
    }
    }
    }
    实际上,q只是个单的原型Q如果试N|以q种方式q行的服务器应用E序Q那么这U方法的严重不很明显?br /> 首先Qؓ每个h创徏一个新U程的开销很大Qؓ每个h创徏新线E的服务器在创徏和销毁线E上p的时间和消耗的pȝ资源, 往往有时候要比花在处理实际的用户h的时间和资源更多。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后q行垃圾回收。所以提 高服务程序效率的一个手D就是尽可能减少创徏和销毁对象的ơ数。这L合看来,pȝ的性能瓉在于线E的创徏开销?br /> 其次Q除了创建和销毁线E的开销之外Q活动的U程也消耗系l资源。在一?JVM 里创建太多的U程可能会导致系l由于过度消耗内存而用完内存或“切换q度”。ؓ了防止资源不I服务器应用程序需要一些办法来限制Ml定时刻q行的处?U程数目Q以防止服务器被“压死”的情况发生。所以在设计后台E序的时候,一般需要提前根据服务器的内存、CPU{硬件情况设定一个线E数量的上限倹{?br /> 如果创徏和销毁线E的旉相对于服务时间占用的比例较大Q那末假讑֜一个较短的旉内有成千上万的请求到达,惌一下,服务器的旉和资源将会大量的花在 创徏和销毁线E上Q而真正用于处理请求的旉却相对较,q种情况下,服务器性能瓉在于创建和销毁线E的旉。按照这个模型写一个简单的E序试一?卛_看出Q由于篇q关p,此处略。如果把Q服务时?创徏和销毁线E的旉Q作量服务器性能的一个参敎ͼ那末q个比D大,服务器的性能p高?br /> 应此Q解xc问题的实质是量减少创徏和销毁线E的旉Q把服务器的资源可能多地用到处理请求上来,从而发挥多U程的优点(q发Q,避免多线E的~点Q创建和销毁的时空开销Q?br /> U程池ؓU程生命周期开销问题和资源不问题提供了解决Ҏ。通过对多个Q务重用线E,U程创徏的开销被分摊到了多个Q务上。其好处是,因ؓ在请求到达时 U程已经存在Q所以无意中也消除了U程创徏所带来的gq。这P可以立即ؓh服务Q应用E序响应更快。而且Q通过适当地调整线E池中的U程数目Q也 是当请求的数目过某个阈值时Q就强制其它M新到的请求一直等待,直到获得一个线E来处理为止Q从而可以防止资源不?br />
    3    JAVAU程池原?br /> 3.1 原理以及实现
    在实践中Q关于线E池的实现常常有不同的方法,但是它们的基本思\大都是相似的Q服务器预先存放一定数目的“?#8221;的线E,q发E序需要用线E的时候,?服务器取用一条已l创建好的线E(如果U程池ؓI则{待Q,使用该线E对h服务Q用结束后Q该U程q不删除Q而是q回U程池中Q以备复用,q样可以?免对每一个请求都生成和删除线E的昂贵操作?br /> 一个比较简单的U程池至应包含U程池管理器、工作线E、Q务队列、Q务接口等部分。其中线E池理器(ThreadPool ManagerQ的作用是创建、销毁ƈ理U程池,工作线E放入线E池中;工作U程是一个可以@环执行Q务的U程Q在没有d时进行等待;d队列的作 用是提供一U缓冲机Ӟ没有处理的d攑֜d队列中;d接口是每个Q务必d现的接口Q主要用来规定Q务的入口、Q务执行完后的收尾工作、Q务的?行状态等Q工作线E通过该接口调度Q务的执行。下面的代码实现了创Z个线E池Q?br /> public class ThreadPool
    { 
    private Stack threadpool = new Stack();
    private int poolSize;
    private int currSize=0;
    public void setSize(int n)
    { 
    poolSize = n;
    }
    public void run()
    {
    for(int i=0;i

    (发帖旉:2003-11-30 11:55:56) 
    ---岑心 J

    回复(1): 

    4.2    框架与结?br /> 下面让我们来看看util.concurrent的框架结构。关于这个工具包概述的e文原版链接地址是http: //gee.cs.oswego.edu/dl/cpjslides/util.pdf。该工具包主要包括三大部分:同步、通道和线E池执行器。第一部分 主要是用来定刉Q资源管理,其他的同步用途;通道则主要是为缓冲和队列服务的;U程池执行器则提供了一l完善的复杂的线E池实现?br /> --主要的结构如下图所C?br />
    4.2.1 Sync
    acquire/release协议的主要接?br /> - 用来定制锁,资源理Q其他的同步用?br /> - 高层抽象接口
    - 没有区分不同的加锁用?br />
    实现
    -Mutex, ReentrantLock, Latch, CountDown,Semaphore, WaiterPreferenceSemaphore, FIFOSemaphore, PrioritySemaphore
    q有Q有几个单的实现Q例如ObservableSync, LayeredSync

    举例Q如果我们要在程序中获得一独占锁,可以用如下简单方式:
    try {
    lock.acquire();
    try {
    action();
    }
    finally {
    lock.release();
    }
    }catchQException eQ{
    }

    E序?使用lock对象的acquire()Ҏ获得一独占锁,然后执行您的操作Q锁用完后,使用release()Ҏ释放之即可。呵呵,单吧Q想 想看Q如果您亲自撰写独占锁,大概会考虑到哪些问题?如果关键的锁得不到怎末办?用v来是不是会复杂很多?而现在,以往的很多细节和Ҏ异常情况在这里都 无需多考虑Q您可以把_֊花在解决您的应用问题上去?br />
    4.2.2 通道(Channel)
    为缓Ԍ队列{服务的L?br />
    具体实现
    LinkedQueue, BoundedLinkedQueue,BoundedBuffer, BoundedPriorityQueue, SynchronousChannel, Slot

    通道例子
    class Service { // ...
    final Channel msgQ = new LinkedQueue();
    public void serve() throws InterruptedException {
    String status = doService();
    msgQ.put(status);
    }
    public Service() { // start background thread
    Runnable logger = new Runnable() {
    public void run() {
    try {
    for(;;)
    System.out.println(msqQ.take());
    }
    catch(InterruptedException ie) {} }
    };
    new Thread(logger).start();
    }
    }
    在后台服务器中,~冲和队列都是最常用到的。试惻I如果Ҏ有远端的h不排个队列,让它们一拥而上的去争夺cpu、内存、资源,那服务器瞬间不当掉才怪。而在q里Q成熟的队列和缓冲实现已l提供,您只需要对其进行正初始化q用即可,大大~短了开发时间?br />
    4.2.3执行?Executor)
    Executor是这里最重要、也是我们往往最l写E序要用到的Q下面重点对其进行介l?br /> cMU程的类的主接口
    - U程?br /> - 轻量U运行框?br /> - 可以定制调度法

    只需要支持execute(Runnable r)
    - 同Thread.startcM

    实现
    - PooledExecutor, ThreadedExecutor, QueuedExecutor, FJTaskRunnerGroup

    PooledExecutorQ线E池执行器)是个最常用到的c,以它ZQ?br /> 可修改得属性如下:
    - d队列的类?br /> - 最大线E数
    - 最线E数
    - 预热(预分?和立?分配)U程
    - 保持z跃直到工作U程l束
    -- 以后如果需要可能被一个新的代?br /> - 饱和(Saturation)协议
    -- dQ丢弃,生者运行,{等

    可不要小看上面这数条属性,对这些属性的讄完全可以{同于您自己撰写的线E池的成百上千行代码。下面以W者撰写过得一个GIS服务器ؓ例:
    该GIS服务器是一个典型的“hQ服?#8221;cd的服务器Q遵循后端程序设计的一般框架。首先对所有的h按照先来先服务排入一个请求队列,如果瞬间到达?h过了请求队列的定wQ则溢出的h转移至一个旉列。如果旉列也排满了,则对以后辑ֈ的请求给予一?#8220;服务器忙”的提C后其单抛弃。这 个就够忙zM늚了?br /> 然后Q结合链表结构实C个线E池Q给池一个初始容量。如果该池满Q以x2的策略将池的定w动态增加一倍,依此cLQ直到ȝE数服务辑ֈpȝ能力上限Q?之后U程池容量不在增加,所有请求将{待一个空余的q回U程。每从池中得C个线E,该线E就开始最hq行GIS信息的服务,如取坐标、取地图Q等{?服务完成后,该线E返回线E池l箋求队列离地后l请求服务,周而复始。当时用矢量链表来暂存请求,用wait()?notify() ?synchronized{原语结合矢量链表实现线E池QdU?00行程序,而且在运行时间较长的情况下服务器不稳定,U程池被取用的线E有异常消失?情况发生。而用util.concurrent相关cM后,仅用了几十行E序完成了相同的工作而且服务器运行稳定,U程池没有丢qE的情况发生。由 此可见util.concurrent包极大的提高了开发效率,为项目节省了大量的时间?br /> 使用PooledExecutor例子
    import java.net.*;
    /**
    *

    Title:


    *

    Description: 负责初始化线E池以及启动服务?/span>


    *

    Copyright: Copyright (c) 2003


    *

    Company:


    * @author not attributable
    * @version 1.0
    */
    public class MainServer {
    //初始化常?br /> public static final int MAX_CLIENT=100; //pȝ最大同时服务客h
    //初始化线E池
    public static final PooledExecutor pool =
    new PooledExecutor(new BoundedBuffer(10), MAX_CLIENT); //chanel定w?0,
    //在这里ؓU程池初始化了一?br /> //长度?0的Q务缓冲队列?br />
    public MainServer() {
    //讄U程池运行参?br /> pool.setMinimumPoolSize(5); //讄U程池初始容量ؓ5个线E?br /> pool.discardOldestWhenBlocked();//对于出队列的请求,使用了抛弃策略?br /> pool.createThreads(2); //在线E池启动的时候,初始化了h一定生命周期的2?#8220;?#8221;U程
    }

    public static void main(String[] args) {
    MainServer MainServer1 = new MainServer();
    new HTTPListener().start();//启动服务器监听和处理U程
    new manageServer().start();//启动理U程
    }
    }

    cHTTPListener
    import java.net.*;
    /**
    *

    Title:


    *

    Description: 负责监听端口以及Q务交l线E池处理


    *

    Copyright: Copyright (c) 2003


    *

    Company:


    * @author not attributable
    * @version 1.0
    */

    public class HTTPListener extends Thread{
    public HTTPListener() {
    }
    public void run(){
    try{
    ServerSocket server=null;
    Socket clientconnection=null;
    server = new ServerSocket(8008);//服务套接字监听某地址端口?br /> while(true){//无限循环
    clientconnection =server.accept();
    System.out.println("Client connected in!");
    //使用U程池启动服?br /> MainServer.pool.execute(new HTTPRequest(clientconnection));//如果收到一个请求,则从U程池中取一个线E进行服务,d完成后,该线E自动返q线E池
    }
    }catch(Exception e){
    System.err.println("Unable to start serve listen:"+e.getMessage());
    e.printStackTrace();
    }
    }
    }

    关于util.concurrent工具包就有选择的介l到q,更详l的信息可以阅读q些java源代码的API文档。Doug Lea是个很具?#8220;open”_的作者,他将util.concurrent工具包的java源代码全部公布出来,有兴的读者可以下载这些源代码q细 l品呟?span class="Apple-converted-space"> 


    5    l束?br /> 以上内容介绍了线E池基本原理以及设计后台服务E序应考虑到的问题Qƈl合实例详细介绍了重要的多线E开发工具包util.concurrent的构架和使用。结合用已有完善的开发包Q后端服务程序的开发周期将大大~短Q同时程序性能也有了保障?br />


    Sheldon Sun 2011-03-23 13:25 发表评论
    ]]>
    JAVA事务,JTA,JDBC,JDO,DAO,JNDI概念http://www.tkk7.com/sheldonsun/archive/2011/03/22/346767.htmlSheldon SunSheldon SunTue, 22 Mar 2011 09:35:00 GMThttp://www.tkk7.com/sheldonsun/archive/2011/03/22/346767.htmlhttp://www.tkk7.com/sheldonsun/comments/346767.htmlhttp://www.tkk7.com/sheldonsun/archive/2011/03/22/346767.html#Feedback1http://www.tkk7.com/sheldonsun/comments/commentRss/346767.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/346767.html引用http://dyldragon.javaeye.com/blog/789374

    一、什么是Java事务

    通常的观念认为,事务仅与数据库相兟?/span> 
    事务必须服从ISO/IEC所制定?/span>ACID原则?/span>

    ACID是原子性(atomicityQ、一致性(consistencyQ、隔L(isolationQ和持久性(durabilityQ的~写?/span>

    事务的原子性表CZ务执行过E中的Q何失败都导致事务所做的M修改失效?/span>

    一致性表C当事务执行p|Ӟ所有被该事务媄响的数据都应该恢复到事务执行前的状态?/span>

    隔离性表C在事务执行q程中对数据的修改,在事务提交之前对其他事务不可见?/span>

    持久性表C已提交的数据在事务执行p|Ӟ数据的状态都应该正确?/span>


         
    通俗的理解,事务是一l原子操作单元,从数据库角度_是一l?/span>SQL指oQ要么全部执行成功,若因为某个原因其中一条指令执行有错误Q则撤销先前执行q的所有指令。更{的说就是:要么全部执行成功Q要么撤销不执行?/span>


    既然事务的概念从数据库而来Q那Java事务是什么?之间有什么联p?  实际上,一?/span>Java应用pȝQ如果要操作数据库,则通过JDBC来实现的。增加、修攏V删除都是通过相应Ҏ间接来实现的Q事务的控制也相应{UdJavaE序代码中。因此,数据库操作的事务习惯上就UCؓJava事务?/span>


    二、ؓ什么需要事?/span>

    事务是ؓ解决数据安全操作提出的,事务控制实际上就是控制数据的安全讉K。具一个简单例子:比如银行转帐业务Q̎?/span>A要将自己账户上的1000 元{?/span>B账户下面Q?/span>A账户余额首先要减?/span>1000元,然后B账户要增?/span>1000元。假如在中间|络出现了问题,A账户减去1000元已l结束,B因ؓ|络中断而操作失败,那么整个业务p|Q必d出控Ӟ要求A账户转帐业务撤销。这才能保证业务的正性,完成q个操走需要事务,?/span>A账户资金减少?/span>B账户资金增加方到一个事务里面,要么全部执行成功Q要么操作全部撤销Q这样就保持了数据的安全性?/span>


    三?/span>Java事务的类?/span> 
        Java 
    事务的类型有三种Q?/span>JDBC事务?/span>JTA(Java Transaction API)事务、容器事务?/span> 
    1
    ?/span>JDBC事务 
    JDBC 
    事务是用 Connection 对象控制的?/span>JDBC Connection 接口( java.sql.Connection )提供了两U事务模式:自动提交和手工提交?/span> java.sql.Connection 提供了以下控制事务的ҎQ?/span>

    public void setAutoCommit(boolean) 
    public boolean getAutoCommit() 
    public void commit() 
    public void rollback() 
    使用 JDBC 事务界定Ӟ您可以将多个 SQL 语句l合C个事务中?/span>JDBC 事务的一个缺Ҏ事务的范围局限于一个数据库q接。一?/span> JDBC 事务不能跨越多个数据库?/span> 
    2
    ?/span>JTA(Java Transaction API)事务 
        JTA 
    是一U高层的Q与实现无关的,与协议无关的APIQ应用程序和应用服务器可以?/span>JTA来访问事务?/span> 
    JTA
    允许应用E序执行分布式事务处?/span>--在两个或多个|络计算源上讉Kq且更新数据Q这些数据可以分布在多个数据库上?/span>JDBC驱动E序?/span>JTA支持极大地增Z数据讉K能力?/span> 
    如果计划?/span> JTA 界定事务Q那么就需要有一个实?/span> javax.sql.XADataSource ?/span> javax.sql.XAConnection ?/span> javax.sql.XAResource接口?/span> JDBC 驱动E序。一个实Cq些接口的驱动程序将可以参与 JTA 事务。一?/span> XADataSource 对象是一?/span>XAConnection 对象的工厂?/span> XAConnection s 是参?/span> JTA 事务?/span> JDBC q接?/span> 
    您将需要用应用服务器的理工具讄 XADataSource 。从应用服务器和 JDBC 驱动E序的文档中可以了解到相关的指导?/span> 
    J2EE 
    应用E序?/span> JNDI 查询数据源。一旦应用程序找C数据源对象,它就调用 javax.sql.DataSource.getConnection() 以获得到数据库的q接?/span> 
         XA 
    q接与非 XA q接不同。一定要C XA q接参与?/span> JTA 事务。这意味着 XA q接不支?/span> JDBC 的自动提交功能。同Ӟ应用E序一定不要对 XA q接调用 java.sql.Connection.commit() 或?/span> java.sql.Connection.rollback() 。相反,应用E序应该使用 UserTransaction.begin()?/span> UserTransaction.commit() ?/span> serTransaction.rollback() ?/span>

    3、容器事?/span> 
         
    容器事务主要?/span>J2EE应用服务器提供的Q容器事务大多是ZJTA完成Q这是一个基?/span>JNDI的,相当复杂?/span>API实现。相对编码实?/span>JTA 事务理Q我们可以通过EJB容器提供的容器事务管理机ӞCMTQ完成同一个功能,q项功能?/span>J2EE应用服务器提供。这使得我们可以单的指定哪个方法加入事务,一旦指定,容器负责事务管理Q务。这是我们土建的解决方式Q因为通过q种方式我们可以事务代码排除在逻辑~码之外Q同时将所有困难交l?/span> J2EE容器去解冟뀂?/span>EJB CMT的另外一个好处就是程序员无需兛_JTA API的编码,不过Q理Z我们必须使用EJB?/span> 
    四、三U事务差?/span> 
    1
    ?/span>JDBC事务控制的局限性在一个数据库q接内,但是其用简单?/span> 
    2
    ?/span>JTA事务的功能强大,事务可以跨越多个数据库或多个DAOQ用也比较复杂?/span> 
    3
    、容器事务,主要指的?/span>J2EE应用服务器提供的事务理Q局限于EJB应用使用?/span> 


    JTA

    Java事务APIQJTAQJava Transaction APIQ和它的同胞Java事务服务(JTSQJava Transaction Service)QؓJ2EEq_提供了分布式事务服务。一个分布式事务Qdistributed transactionQ包括一个事务管理器Qtransaction managerQ和一个或多个资源理?resource manager)。一个资源管理器Qresource managerQ是Lcd的持久化数据存储。事务管理器Qtransaction managerQ承担着所有事务参与单元者的怺通讯的责仅R下图显CZ事务理器和资源理的间的关pR?/span>


    JTA事务比JDBC事务更强大。一个JTA事务可以有多个参与者,而一个JDBC事务则被限定在一个单一的数据库q接?/span>下列M个Javaq_的组仉可以参与C个JTA事务中:

    JDBCq接

    • JDO PersistenceManager 对象
    • JMS 队列
    • JMS 主题
    • 企业JavaBeansQEJBQ?/span>
    • 一个用J2EE Connector Architecture 规范~译的资源分配器?/span>


    DAO

    DAO是Data Access Object数据讉K接口Q数据访问:֐思义是与数据库打交道。夹在业务逻辑与数据库资源中间。对数据库进行CURDQ增删查Ҏ作)?/span>

     

      在核?/span>J2EE模式中是q样介绍DAO模式的:Z建立一个健壮的J2EE应用Q应该将所有对数据源的讉K操作抽象装在一个公共API中。用E序设计的语a来说Q就是徏立一个接口,接口中定义了此应用程序中会用到的所有事务方法。在q个应用E序中,当需要和数据源进行交互的时候则使用q个接口Qƈ且编写一个单独的cL实现q个接口在逻辑上对应这个特定的数据存储?/span>


    JDBC

    JDBCQJava Data Base Connectivity,java数据库连接)是一U用于执行SQL语句的Java APIQ可以ؓ多种关系数据库提供统一讉KQ它׃l用Java语言~写的类和接口组成。JDBC为工?数据库开发h员提供了一个标准的APIQ据此可以构建更高的工具和接口Q数据库开发h员能够用U?Java API ~写数据库应用程序,同时QJDBC也是个商标名?/span>

     

    有了JDBCQ向各种关系数据发送SQL语句是一件很Ҏ的事。换a之,有了JDBC APIQ就不必问Sybase数据库专门写一个程序,问Oracle数据库又专门写一个程序,或ؓ讉KInformix数据库又~写另一个程序等{,E序员只需用JDBC API写一个程序就够了Q它可向相应数据库发送SQL调用。同ӞJava语言和JDBCl合h使程序员不必Z同的q_~写不同的应用程序,只须写一遍程序就可以让它在Q何^Cq行Q这也是Java语言“~写一ơ,处处q行”的优ѝ?/span>


    单地_JDBC 可做三g事:与数据库建立q接、发?操作数据库的语句q处理结果?/span>


    JDO

    JDO(Java Data Object )是一个JAVA用于存取某种数据仓库中的对象的标准化API。JDO提供了透明的对象存储,因此对开发h员来_存储数据对象完全不需要额外的代码Q如JDBC API的用)。这些繁琐的例行工作已经转移到JDO产品提供商n上,使开发h员解脱出来,从而集中时间和_֊在业务逻辑上。另外,JDO很灵z,因ؓ它可以在M数据底层上运行。JDBC只是面向关系数据库(RDBMSQJDO更通用Q提供到M数据底层的存储功能,比如关系数据库、文件、XML以及对象数据库(ODBMSQ等{,使得应用可移植性更强?/span>


    JNDI

    英文全称?Java Naming and Directory Interface

    术语解释Q一l帮助做多个命名和目录服务接口的API?/span>

    JNDI(Java Naming and Directory Interface)是SUN公司提供的一U标准的Java命名pȝ接口QJNDI提供l一的客LAPIQ通过不同的访问提供者接口JNDI SPI的实玎ͼq理者将JNDI API映射为特定的命名服务和目录系l,使得Java应用E序可以和这些命名服务和目录服务之间q行交互。集JNDI实现了高可靠性JNDI[8]Q通过服务器的集群Q保证了JNDI的负载^衡和错误恢复。在全局׃n的方式下Q集中的一个应用服务器保证本地JNDI树的独立性,q拥有全局的JNDI树。每个应用服务器在把部v的服务对象绑定到自己本地的JNDI树的同时Q还l定C个共享的全局JNDI树,实现全局JNDI和自wJNDI的联pR?/span>


     

    JNDI(Java Naming and Directory Interface)是一个应用程序设计的APIQؓ开发h员提供了查找和访问各U?/span>

     

    命名和目录服务的通用、统一的接口,cMJDBC都是构徏在抽象层上?/span>

     

    JNDI可访问的现有的目录及服务有:DNS、XNam 、Novell目录服务、LDAP(Lightweight Directory Access Protocol d目录讉K协议)?CORBA对象服务、文件系l、Windows XP/2000/NT/Me/9x的注册表、RMI?/span>

     


     

    DSML v1&v2、NIS?/span>

     


    JNDI与JDBC

    JNDI提供了一U统一的方式,可以用在|络上查扑֒讉K服务。通过指定一个资源名Uͼ该名U对应于数据库或命名服务中的一个记录,同时q回数据库连接徏立所必须的信息?/span>

    JNDI主要有两部分l成Q应用程序编辑接口和服务供应商接口。应用程序编E接口提供了Java应用E序讉K各种命名和目录服务的功能Q服务供应商接口提供了Q意一U服务的供应商用的功能?/span>

     

     

    Java代码  收藏代码
    1. try{  
    2.   Context cntxt = new InitialContext();  
    3.   DataSource ds = (DataSource) cntxt.lookup("jdbc/dpt");  
    4. }  
    5.   catch(NamingException ne){  
    6.   ...  
    7. }  


    Sheldon Sun 2011-03-22 17:35 发表评论
    ]]>
    Restarthttp://www.tkk7.com/sheldonsun/archive/2008/06/11/207174.htmlSheldon SunSheldon SunWed, 11 Jun 2008 10:27:00 GMThttp://www.tkk7.com/sheldonsun/archive/2008/06/11/207174.htmlhttp://www.tkk7.com/sheldonsun/comments/207174.htmlhttp://www.tkk7.com/sheldonsun/archive/2008/06/11/207174.html#Feedback0http://www.tkk7.com/sheldonsun/comments/commentRss/207174.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/207174.html
    Technology - Hibernate collection:
    Maybe i used to write sth related before.
    Several points as follows:
    1. Define interface as property, for Hibernate will use its own implementation during runtime.
    2. <key> element is used to identiry foreign key for specified table.
    3. <element> and <composite-element> is used for value type definition while <one-to-many> and <many-to-many> is used for entities type.
    4. indexed-collections contain : map, list, index is used to record position for certain record in the container.<map-key> for map while <index-list> for list.
    Next two items is for bidirection:
    5. inverse can be set in either sides for many-to-many relation.
    6. For one-to-many,  many sides will mantain relationship between object. exception happened when many side is index container.in this situation, it is not a completely "bidirectoinal".

    7. Sort is done in memory while order by is down in DB.
    8. <Bag> is used when property is defined as list, but <index-list> is not welcome.
    9. <idbag> is a list which can generate an id for primary key.


    Sheldon Sun 2008-06-11 18:27 发表评论
    ]]>
    Interpret and command patternhttp://www.tkk7.com/sheldonsun/archive/2007/11/22/162406.htmlSheldon SunSheldon SunThu, 22 Nov 2007 08:56:00 GMThttp://www.tkk7.com/sheldonsun/archive/2007/11/22/162406.htmlhttp://www.tkk7.com/sheldonsun/comments/162406.htmlhttp://www.tkk7.com/sheldonsun/archive/2007/11/22/162406.html#Feedback0http://www.tkk7.com/sheldonsun/comments/commentRss/162406.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/162406.html解释器模式:
    ~译器用的比较多?br /> 针对某一特定语法的分析, 解释Q?q进行处理!
    E.g: Expression = expression1 | expression2 | repeatableExpresson|Literal
    针对整个ExpressionQ?分析出其每个l成的expresion1Q?expression2Q?Ҏ个分析出的结果, 都有相应的处理类Q?q初始化出处理类的实例进行处理!
    Literal代表元数?Q?br /> 如果对一个汽车组件的各个生厂商q行解释器模式分析的话: 汽R = 轮胎 Q 发动?Q 框架 那么首先建立一个分析程序,分析汽R的组成, qҎ个部件初始化一个不见对应的对象Q?来匹配该部gQ?q调用部件的ҎҎQ?处理部gQ?q回生厂家的名Uͼ

    q个例子好失败, Interpret 模式优点在表辑ּ的租成有很多模块Q?每个模块重复的包含其他模块的情况下, 辑ֈ代码重用的目的! 所以除了正则表辑ּQ?~译器以外, 暂时想不Z么好的例子来Q?br />
    命o行模式:
    Struts 应用是典型的命o行模式?br /> 1?把请求参数话?br /> 2?Ҏ个请求配|相应的处理cR处理类有统一的接口?br /> 3?配置h与处理类的对应关pR?br /> 4?调用处理cȝ一接口?br />
    没什么好说的Q?br />



    今天比较凡, 感觉自己职业发展已经到达了一个瓶颈, 不知道怎么发展才好Q?
    感觉自己交流能力比较差, 大家在一L时候都是听别h_ 自己很少发言Q?做编码已l感觉没有太大意思了Q?因ؓ现在的公司只注重l果Q?不看中代码的质量Q开发出来很ҎQ?但开发好的代码很难! 周围的同事开发出来代码的水^比我都差很多Q?也一样通过Q?搞得自己x高自己都没有动力Q?br /> x高一下交能力, 不知道{行做QA会不会有Ҏ善, 或者还家公司?
    比较qQ?br />



    Sheldon Sun 2007-11-22 16:56 发表评论
    ]]>
    Chain of responsibilityhttp://www.tkk7.com/sheldonsun/archive/2007/11/21/162123.htmlSheldon SunSheldon SunWed, 21 Nov 2007 08:49:00 GMThttp://www.tkk7.com/sheldonsun/archive/2007/11/21/162123.htmlhttp://www.tkk7.com/sheldonsun/comments/162123.htmlhttp://www.tkk7.com/sheldonsun/archive/2007/11/21/162123.html#Feedback1http://www.tkk7.com/sheldonsun/comments/commentRss/162123.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/162123.html
    职责链主要是Z一个请求, 可能有很多个处理者, q些处理者数目ƈ不固定而设计的Q?br />
    ҎU处理, 都会有一个处理类来对应! 没个具体的处理类都会有一个后l: succorQ?q个后比处理类更广泛! 如果当前的处理类可以处理改请求, 则处理,否则使用后的处理方法!

    感觉最关键的一点就是对后者的定义Q?那ؓ什么不用承机制呢Q?Q?br />


    Sheldon Sun 2007-11-21 16:49 发表评论
    ]]>
    Validate xmlhttp://www.tkk7.com/sheldonsun/archive/2007/08/08/135163.htmlSheldon SunSheldon SunWed, 08 Aug 2007 01:53:00 GMThttp://www.tkk7.com/sheldonsun/archive/2007/08/08/135163.htmlhttp://www.tkk7.com/sheldonsun/comments/135163.htmlhttp://www.tkk7.com/sheldonsun/archive/2007/08/08/135163.html#Feedback0http://www.tkk7.com/sheldonsun/comments/commentRss/135163.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/135163.html
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.Serializable;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;

    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.dom4j.Namespace;
    import org.dom4j.io.SAXReader;
    import org.dom4j.tree.DefaultNamespace;

    import org.iso_relax.verifier.Schema;
    import org.iso_relax.verifier.Verifier;
    import org.iso_relax.verifier.VerifierConfigurationException;
    import org.iso_relax.verifier.VerifierFactory;
    import org.iso_relax.verifier.VerifierFilter;
    import org.xml.sax.EntityResolver;
    import org.xml.sax.ErrorHandler;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;
    import org.xml.sax.SAXParseException;

    import com.sun.msv.verifier.jarv.TheFactoryImpl;

    public class ValidateXML {
       
        public Document validate(InputStream stream, String xsdName) throws IOException{
       
        Document result = null;
        InputStream xmlStream = stream;
        InputStream schemaStream = this.getClass().getResourceAsStream(xsdName);
        SAXReader reader;
        try {
            reader = createSAXReader(schemaStream);
            result = reader.read(xmlStream);
            xmlStream.close();
            schemaStream.close();
        } catch (DocumentException e) {
            System.out.println("Validate failed !");
            e.printStackTrace();           
        } catch(IOException e) {
            System.out.println("Xsd file does not exist !");
            e.printStackTrace();           
        }
        catch (Exception e) {
            System.out.println("Xsd file format error !");
            e.printStackTrace();
        }
       
        return result;
    }

    private SAXReader createSAXReader(InputStream xsdStream) throws VerifierConfigurationException, SAXException, IOException {
        VerifierFactory factory = new TheFactoryImpl();
    Schema schema = factory.compileSchema(xsdStream);

    Verifier verifier = schema.newVerifier();
    verifier.setErrorHandler(new ErrorHandler() {
        public void error(SAXParseException e) {
        System.out.println("ERROR: " + e);
        }

        public void fatalError(SAXParseException e) {
        System.out.println("FATAL: " + e);
        }

        public void warning(SAXParseException e) {
        System.out.println("WARNING: " + e);
        }
    });

    // now install the verifying filter
    VerifierFilter filter = verifier.getVerifierFilter();
    SAXReader reader = new SAXReader();
    reader.setXMLFilter(filter);
    return reader;
    }


    public static void main(String[] args) throws IOException {
        ValidateXML validateXML = new ValidateXML();
    //    InputStream schemaStream = validateXML.getClass().getResourceAsStream("Response.xml");
    //    validateXML.validate(schemaStream, "BAK-Response.xsd");
        validateXML.validateByDtd("hibernate-configuration-3.0.dtd", "src\\testSchema\\hibernate.cfg.xml");
    }

    public Document validateByDtd(String dtdFile, String xmlFile) {
        List errors = new ArrayList();
        SAXReader saxReader = new SAXReader();
        saxReader.setEntityResolver(new DTDEntityResolver(dtdFile));
        saxReader.setErrorHandler(new ErrorLogger(xmlFile, errors));
        saxReader.setValidation(true);
        Document doc = null;
        try {
        doc = saxReader.read(xmlFile);
        } catch (DocumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
       
        return doc;
    }

    public static class ErrorLogger implements ErrorHandler {
        private String file;
        private List errors;
        ErrorLogger(String file, List errors) {
            this.file=file;
            this.errors = errors;
        }
        public void error(SAXParseException error) {
            System.err.println( "Error parsing XML: " + file + '(' + error.getLineNumber() + ") " + error.getMessage() );
            errors.add(error);
        }
        public void fatalError(SAXParseException error) {
            System.err.println(error);
        }
        public void warning(SAXParseException warn) {
            System.err.println( "Warning parsing XML: " + file + '(' + warn.getLineNumber() + ") " + warn.getMessage() );
        }
    }


    public static class DTDEntityResolver implements EntityResolver, Serializable {

        private static final Log log = LogFactory.getLog( DTDEntityResolver.class );

       
        private String dtdFile;
        public DTDEntityResolver(String dtdFile) {
            this.dtdFile = dtdFile;
        }
        public InputSource resolveEntity(String publicId, String systemId) {
            if ( systemId != null ) {
                InputStream dtdStream = this.getClass().getResourceAsStream(dtdFile);
                InputSource source = new InputSource( dtdStream );
                source.setPublicId( publicId );
                source.setSystemId( systemId );
                       
                return source;
            }
            // use default behavior
            return null;
        }

    }

    }


    Sheldon Sun 2007-08-08 09:53 发表评论
    ]]>
    Hibernate - Componenthttp://www.tkk7.com/sheldonsun/archive/2007/06/19/125046.htmlSheldon SunSheldon SunTue, 19 Jun 2007 01:31:00 GMThttp://www.tkk7.com/sheldonsun/archive/2007/06/19/125046.htmlhttp://www.tkk7.com/sheldonsun/comments/125046.htmlhttp://www.tkk7.com/sheldonsun/archive/2007/06/19/125046.html#Feedback0http://www.tkk7.com/sheldonsun/comments/commentRss/125046.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/125046.html2. Declaration for mapping under component element.
    3. When storing in set(or other collection type), use composite-element.
    4. When using as primary key, use composite-id.
    5. Dynamic component.





    Sheldon Sun 2007-06-19 09:31 发表评论
    ]]>
    Hibernate - Persistent classhttp://www.tkk7.com/sheldonsun/archive/2007/06/14/124256.htmlSheldon SunSheldon SunThu, 14 Jun 2007 03:12:00 GMThttp://www.tkk7.com/sheldonsun/archive/2007/06/14/124256.htmlhttp://www.tkk7.com/sheldonsun/comments/124256.htmlhttp://www.tkk7.com/sheldonsun/archive/2007/06/14/124256.html#Feedback0http://www.tkk7.com/sheldonsun/comments/commentRss/124256.htmlhttp://www.tkk7.com/sheldonsun/services/trackbacks/124256.htmlBut a no-argument constuctor is requeried for hibernate to instiante an object of the class by refection.

    2. Indentifier property if optional too, but needed if we want to use the full feature set of hibernate, for hibernate will distinguish object by identifiers while some special operation. e.g:  merge(), saveOrUpdate.

    3. Equals() and hasdCode() mehtod is recommanded to implenent when you want to store persisntent class in a Set or manipulate object span sessions.

    4. There are other 2 ways to define enity object except java class, Map and xml, the defect maybe can not do compile check, metrit is more flexisble than java.

    5. Tuplizier!!!!

    Hibernate integrated with J2EE infrastructure:
    Two main point:
    1. Hidden Configuration.config().buildSessionFacotory operation.
    2. Bound session factory to jndi namespace through many way. e.g: MBean
     



    Sheldon Sun 2007-06-14 11:12 发表评论
    ]]>
    վ֩ģ壺 ĻӰӾþþ| 91ƷѾþþþþþþ| ޳aƬ߹ۿ| ѹۿ˾þѹۿ| ޾Ʒ߹ۿ| ձһ| Ƭѹۿȫ| һ| ߹ۿaëƬ| þƵ99| ޾Һ| ޳߲va| ޾ƷƵ߹ۿ| þҹ޾Ʒ| þþƷavĻ| þWWW˳Ƭ| ߹ۿavվ| ɫվWWWվ| ŷƷһ| ëƬaëƬѹۿƷ| ȫ߹ۿ| av뾫Ʒ| 鶹avŮһ| AV| һѸ߹ۿ| aëƬ߹ۿ| AVһ| ޾Ʒ˳߲| ޾ƷþþþþĻ| ҳվ߿| 99պƷ| ҹƷ| ..ŷ| ޾Ʒѹۿ| Ļ޾Ʒ| ҹӰӴȫѹۿ| 18վڵ| ߵƵ߹ۿ| ˳Ƶ߹ۿ| ɫվWWW| ۺɫ|