<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    hk2000c技術(shù)專欄

    技術(shù)源于哲學(xué),哲學(xué)來源于生活 關(guān)心生活,關(guān)注健康,關(guān)心他人

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      111 隨筆 :: 1 文章 :: 28 評論 :: 0 Trackbacks

    #

    這是總結(jié)以前使用spring調(diào)用Oracle存儲過程,并用cursor返回結(jié)果集的一個完整實例,希望能對大家有幫助。

    1. 創(chuàng)建表:

    代碼
    1. create table TEST_USERS    
    2. (    
    3.   USER_ID  VARCHAR2(10) not null,    
    4.   NAME     VARCHAR2(10) not null,    
    5.   PASSWORD VARCHAR2(20) not null    
    6. )  

     

    2. 創(chuàng)建存儲過程:

    代碼
    1. create or replace package display_users_package is    
    2.      type search_results is ref cursor;    
    3.      procedure display_users_proc(results_out out search_results, userId in test_users.user_id%type);    
    4. end display_users_package;    
    5.   
    6. create or replace package body display_users_package is    
    7.      procedure display_users_proc(results_out out search_results, userId in test_users.user_id%type)    
    8.           is    
    9.           begin    
    10.           if userId is not null then    
    11.               open results_out for select * from test_users where user_id like userId || '%';    
    12.           else    
    13.               open results_out for  select * from test_users;    
    14.           end if;    
    15.       end display_users_proc;    
    16. end display_users_package;  

     

    這個results_out是一個游標(biāo)類型,用來返回查找的結(jié)果集。

    3. 完整實現(xiàn)代碼:

    代碼
    1. import java.sql.CallableStatement;   
    2. import java.sql.Connection;   
    3. import java.sql.ResultSet;   
    4. import java.sql.SQLException;   
    5. import java.util.ArrayList;   
    6. import java.util.HashMap;   
    7. import java.util.List;   
    8. import java.util.Map;   
    9.   
    10. import javax.sql.DataSource;   
    11.   
    12. import oracle.jdbc.OracleTypes;   
    13.   
    14. import org.springframework.dao.DataAccessException;   
    15. import org.springframework.jdbc.core.CallableStatementCallback;   
    16. import org.springframework.jdbc.core.CallableStatementCreator;   
    17. import org.springframework.jdbc.core.JdbcTemplate;   
    18.   
    19. import com.spring.stored.procedure.util.DataContextUtil;   
    20.   
    21. /**  
    22.  * @author Jane Jiao  
    23.  *  
    24.  */  
    25. public class SpringStoredProce {   
    26.        
    27.     public List<Map> execute(String storedProc, String params){   
    28.         List<Map> resultList = null;   
    29.         try{   
    30.             final DataSource ds = DataContextUtil.getInstance().getDataSource();   
    31.             final JdbcTemplate template = new JdbcTemplate(ds);   
    32.             resultList = (List<Map>)template.execute(new ProcCallableStatementCreator(storedProc, params),   
    33.                                                      new ProcCallableStatementCallback());   
    34.         }catch(DataAccessException e){   
    35.             throw new RuntimeException("execute method error : DataAccessException " + e.getMessage());   
    36.         }   
    37.          return resultList;   
    38.     }   
    39.        
    40.        
    41.     /**  
    42.      * Create a callable statement in this connection.  
    43.      */  
    44.     private class ProcCallableStatementCreator implements CallableStatementCreator {   
    45.         private String storedProc;   
    46.         private String params;   
    47.            
    48.        
    49.         /**  
    50.          * Constructs a callable statement.  
    51.          * @param storedProc                  The stored procedure's name.  
    52.          * @param params                      Input parameters.  
    53.          * @param outResultCount              count of output result set.  
    54.          */  
    55.         public ProcCallableStatementCreator(String storedProc, String params) {   
    56.             this.params = params;   
    57.             this.storedProc = storedProc;   
    58.         }   
    59.            
    60.         /**  
    61.          * Returns a callable statement  
    62.          * @param conn          Connection to use to create statement  
    63.          * @return cs           A callable statement  
    64.          */  
    65.         public CallableStatement createCallableStatement(Connection conn) {   
    66.             StringBuffer storedProcName = new StringBuffer("call ");   
    67.             storedProcName.append(storedProc + "(");   
    68.             //set output parameters   
    69.             storedProcName.append("?");   
    70.             storedProcName.append(", ");   
    71.                
    72.             //set input parameters   
    73.             storedProcName.append("?");   
    74.             storedProcName.append(")");   
    75.   
    76.             CallableStatement cs = null;   
    77.             try {   
    78.                 // set the first parameter is OracleTyep.CURSOR for oracel stored procedure   
    79.                 cs = conn.prepareCall(storedProcName.toString());   
    80.                 cs.registerOutParameter (1, OracleTypes.CURSOR);   
    81.                // set the sencond paramter   
    82.                 cs.setObject(2, params);   
    83.             } catch (SQLException e) {   
    84.                 throw new RuntimeException("createCallableStatement method Error : SQLException " + e.getMessage());   
    85.             }   
    86.             return cs;   
    87.         }   
    88.            
    89.     }   
    90.        
    91.     /**  
    92.      *   
    93.      * The ProcCallableStatementCallback return a result object,   
    94.      * for example a collection of domain objects.  
    95.      *  
    96.      */  
    97.     private class ProcCallableStatementCallback implements CallableStatementCallback {   
    98.            
    99.         /**  
    100.          * Constructs a ProcCallableStatementCallback.  
    101.          */  
    102.         public ProcCallableStatementCallback() {   
    103.         }   
    104.   
    105.         /**  
    106.          * Returns a List(Map) collection.  
    107.          * @param cs                       object that can create a CallableStatement given a Connection  
    108.          * @return resultsList             a result object returned by the action, or null  
    109.          */  
    110.         public Object doInCallableStatement(CallableStatement cs){   
    111.             List<Map> resultsMap =  new ArrayList<Map>();   
    112.             try {   
    113.                 cs.execute();    
    114.                 ResultSet rs = (ResultSet) cs.getObject(1);   
    115.                 while (rs.next()) {   
    116.                     Map<String, String> rowMap = new HashMap<String, String>();   
    117.                     rowMap.put("userId", rs.getString("USER_ID"));   
    118.                     rowMap.put("name", rs.getString("NAME"));   
    119.                     rowMap.put("password", rs.getString("PASSWORD"));   
    120.                     resultsMap.add(rowMap);   
    121.                 }      
    122.                 rs.close();   
    123.             }catch(SQLException e) {   
    124.                 throw new RuntimeException("doInCallableStatement method error : SQLException " + e.getMessage());   
    125.             }   
    126.             return resultsMap;   
    127.        }   
    128.     }   
    129. }   

     

    4. 測試代碼,在這里使用了Junit4測試:

    代碼
    1. import static org.junit.Assert.assertNotNull;    
    2. import static org.junit.Assert.assertTrue;    
    3.   
    4. import java.util.List;    
    5. import java.util.Map;    
    6.   
    7. import org.junit.After;    
    8. import org.junit.Before;    
    9. import org.junit.Test;    
    10.   
    11. /**   
    12.  * @author Jane Jiao   
    13.  *   
    14.  */    
    15. public class SpringStoredProceTest {    
    16.        
    17.    private SpringStoredProce springStoredProce;    
    18.   
    19.    /**   
    20.     * @throws java.lang.Exception   
    21.     */    
    22.    @Before    
    23.    public void setUp() throws Exception {    
    24.       springStoredProce = new SpringStoredProce();    
    25.    }    
    26.   
    27.    /**   
    28.     * @throws java.lang.Exception   
    29.     */    
    30.    @After    
    31.    public void tearDown() throws Exception {    
    32.       springStoredProce = null;    
    33.    }    
    34.   
    35.    /**   
    36.     * Test method for {@link com.hactl.listingframework.dao.SpringStoredProce#execute(java.lang.String, java.lang.String)}.   
    37.     */    
    38.    @Test    
    39.    public void testExecute() {    
    40.       final String storedProcName = "display_users_package.display_users_proc";    
    41.       final String param = "test";    
    42.       List<Map> resultList = springStoredProce.execute(storedProcName, param);    
    43.       assertNotNull(resultList);    
    44.       assertTrue(resultList.size() > 0);    
    45.       for (int i = 0; i < resultList.size(); i++) {    
    46.          Map rowMap = resultList.get(i);    
    47.          final String userId = rowMap.get("userId").toString();    
    48.          final String name = rowMap.get("name").toString();    
    49.          final String password = rowMap.get("password").toString();    
    50.          System.out.println("USER_ID=" + userId + "\t name=" + name + "\t password=" + password);    
    51.       }    
    52.           
    53.    }    
    54. }  

     

    5. 測試的輸出結(jié)果:

    代碼
    1. USER_ID=test1    name=aa    password=aa    
    2. USER_ID=test2    name=bb    password=bb    
    3. USER_ID=test3    name=cc    password=cc  
    posted @ 2007-11-16 17:31 hk2000c 閱讀(3560) | 評論 (2)編輯 收藏

    內(nèi)容或簡介:
    /**
    調(diào)用數(shù)據(jù)庫里的一個函數(shù)
    一個函數(shù)本質(zhì)上一個返回一個結(jié)果的存儲過程,這個例子示范了怎么調(diào)用有in、out和in/out參數(shù)的函數(shù)
    ***********************************/
    CallableStatement cs;
    try {
    // 調(diào)用一個沒有參數(shù)的函數(shù); 函數(shù)返回 a VARCHAR
    // 預(yù)處理callable語句

      cs = connection.prepareCall("{? = call myfunc}");

    // 注冊返回值類型
    cs.registerOutParameter(1, i);

    // Execute and retrieve the returned value
    cs.execute();
    String retValue = cs.getString(1);

    // 調(diào)用有一個in參數(shù)的函數(shù); the function returns a VARCHAR
    cs = connection.prepareCall("{? = call myfuncin(?)}");

    // Register the type of the return value
    cs.registerOutParameter(1, Types.VARCHAR);

    // Set the value for the IN parameter
    cs.setString(2, "a string");

    // Execute and retrieve the returned value
    cs.execute();
    retValue = cs.getString(1);

    // 調(diào)用有一個out參數(shù)的函數(shù); the function returns a VARCHAR
    cs = connection.prepareCall("{? = call myfuncout(?)}");

    // Register the types of the return value and OUT parameter
    cs.registerOutParameter(1, Types.VARCHAR);
    cs.registerOutParameter(2, Types.VARCHAR);

    // Execute and retrieve the returned values
    cs.execute();
    retValue = cs.getString(1);           // return value
    String outParam = cs.getString(2);    // OUT parameter

    // 調(diào)用有一個in/out參數(shù)的函數(shù); the function returns a VARCHAR
    cs = connection.prepareCall("{? = call myfuncinout(?)}");

    // Register the types of the return value and OUT parameter
    cs.registerOutParameter(1, Types.VARCHAR);
    cs.registerOutParameter(2, Types.VARCHAR);

    // Set the value for the IN/OUT parameter
    cs.setString(2, "a string");

    // Execute and retrieve the returned values
    cs.execute();
    retValue = cs.getString(1);           // return value
    outParam = cs.getString(2);           // IN/OUT parameter
    } catch (SQLException e) {
    }

    posted @ 2007-11-16 17:18 hk2000c 閱讀(301) | 評論 (0)編輯 收藏

    這段時間開始學(xué)習(xí)寫存儲過程,主要原因還是因為工作需要吧,本來以為很簡單的,但幾經(jīng)挫折,豪氣消磨殆盡,但總算搞通了,為了避免后來者少走彎路,特記述與此,同時亦對自己進行鼓勵。

    一:無返回值的存儲過程

    存儲過程為:

    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;

    然后呢,在java里調(diào)用時就用下面的代碼:

    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) {

          }

        }

     }

    }

    當(dāng)然了,這就先要求要建張表TESTTB,里面兩個字段(I_IDI_NAME)。

    二:有返回值的存儲過程(非列表)

    存儲過程為:

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

    BEGIN

       SELECT INTO PARA2 FROM TESTTB WHERE I_ID= PARA1;

    END TESTB;

    java里調(diào)用時就用下面的代碼:

    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) {

          }

        }

     }

    }

    }

    注意,這里的proc.getString(2)中的數(shù)值2并非任意的,而是和存儲過程中的out列對應(yīng)的,如果out是在第一個位置,那就是proc.getString(1),如果是第三個位置,就是proc.getString(3),當(dāng)然也可以同時有多個返回值,那就是再多加幾個out參數(shù)了。

    三:返回列表

    由于oracle存儲過程沒有返回值,它的所有返回值都是通過out參數(shù)來替代的,列表同樣也不例外,但由于是集合,所以不能用一般的參數(shù),必須要用pagkage.所以要分兩部分,

    1, 建一個程序包。如下:

    CREATE OR REPLACE PACKAGE TESTPACKAGE  AS

     TYPE Test_CURSOR IS REF CURSOR;

    end TESTPACKAGE;

    2,建立存儲過程,存儲過程為:

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

    BEGIN

        OPEN p_CURSOR FOR SELECT * FROM HYQ.TESTTB;

    END TESTC;

    可以看到,它是把游標(biāo)(可以理解為一個指針),作為一個out 參數(shù)來返回值的。

    java里調(diào)用時就用下面的代碼:

    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) {

          }

        }

     }

    }

    在這里要注意,在執(zhí)行前一定要先把oracle的驅(qū)動包放到class路徑里,否則會報錯的。

     

    posted @ 2007-11-16 17:15 hk2000c 閱讀(244) | 評論 (0)編輯 收藏

    關(guān)鍵字:   ActiveMQ    

    ActiveMQ 實踐之路(四) ActiveMQ 4.x +JBoss 4.x MDP實戰(zhàn)篇

          在<<ActiveMQ 實踐之路(三) ActiveMQ 4.x +JBoss 4.x 整合篇 >>里面我們比較詳細的講解了ActiveMQ與JBoss的整合,
    既然選擇了JBoss,那么項目里面或多或少都會使用到EJB,下面我們就詳細地介紹如何在ActiveMQ 4.x+JBOSS 4.x環(huán)境下開發(fā)
    Message Driven Bean,并且與使用jbossMQ在配置上作了比較詳細地比較。這里的OrderMessage 僅僅是一個自動生成的Message Driven Bean,在onMessage方法里面,作日志輸入。

     一. 配置ejb-jar.xml
          
            1.  ejb-jar.xml 不能使用XML DTD,需要使用XML Schema(XSD)
                
    很多朋友可能使用XDoclet來生成ejb-jar.xml,我這里直接使用XDoclet生成的ejb-jar.xml是

    <!--CTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dt-->

               但是在ActiveMQ+JBoss配置中間需要使用新的XML Schema才能完成對ra的定義,如下.

    xml 代碼
    1. <ejb-jar xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/ejb-jar_2_1.xsd" version="2.1">  

     

    2. ejb-jar.xml 直接使用JBossMQ的Message DriverBean 和使用ActiveMQ RA配置的區(qū)別

            (1) .使用JBossMQ的MessageDrivenBean的 ejb-jar.xml配置

    xml 代碼
    1. <!-- Message Driven Beans -->  
    2. <message-driven>  
    3.     <description>  
    4.           
    5.     description>  
    6.     <display-name>Name for OrderMessagedisplay-name>  
    7.     <ejb-name>OrderMessageejb-name>  
    8.     <ejb-class>com.mostone.ejb.OrderMessageejb-class>  
    9.     <transaction-type>Containertransaction-type>  
    10.     <acknowledge-mode>Auto-acknowledgeacknowledge-mode>  
    11.     <message-driven-destination>  
    12.         <destination-type>javax.jms.Queuedestination-type>  
    13.     message-driven-destination>  
    14. message-driven>  

         (2). 使用ActiveMQ RA配置的MessageDrivenBean的ejb-jar.xml配置

    xml 代碼
    1. <!-- Message Driven Beans -->  
    2. <message-driven>  
    3.     <description>  
    4.           
    5.     description>  
    6.     <display-name>Name for OrderMessagedisplay-name>  
    7.     <ejb-name>OrderMessageejb-name>  
    8.     <ejb-class>com.mostone.ejb.OrderMessageejb-class>  
    9.     <transaction-type>Containertransaction-type>  
    10.     <acknowledge-mode>Auto-acknowledgeacknowledge-mode>  
    11.     <!--使用了activetion-config-->  
    12.     <activation-config>  
    13.         <activation-config-property>  
    14.             <activation-config-property-name>destinationactivation-config-property-name>  
    15.             <activation-config-property-value>queue.outboundactivation-config-property-value>  
    16.         activation-config-property>  
    17.         <activation-config-property>  
    18.             <activation-config-property-name>destinationTypeactivation-config-property-name>  
    19.             <activation-config-property-value>javax.jms.Queueactivation-config-property-value>  
    20.         activation-config-property>  
    21.     activation-config>  
    22. message-driven>  

            其中destination,destinationType是ra.xml里面提供的配置屬性,(這里官方的文檔是Destination,DestinationType, 而實際上activemq-ra.rar里面的ra.xml是destination,destinationType,注意大小寫區(qū)別)

    . 配置jboss.xml
               大部分配置都是在jboss.xml里面.
             1.使用JBossMQ 和使用ActiveMQ RA配置Message Driven Bean的區(qū)別
               1.) 使用JBossMQ 的配置


    xml 代碼
    1. <message-driven>  
    2.     <ejb-name>OrderMessageejb-name>  
    3.     <destination-jndi-name>queue/testQueuedestination-jndi-name>  
    4. message-driven>  

             2.) 使用ActiveMQ RA的配置

    xml 代碼
    1. <message-driven>  
    2.     <ejb-name>ActiveMQMDPejb-name>  
    3.     <!-- 使用了resource-adapter-name -->  
    4.     <resource-adapter-name>activemq-ra.rarresource-adapter-name>  
    5.     <!-- 這里的configuration-name 需要和后面container-name 的名字相同 -->  
    6.     <configuration-name>ActiveMQ Message Driven Beanconfiguration-name>  
    7. message-driven>  

            2. jboss.xml 配置invoker proxy和container 支持ActiveMQ RA

    xml 代碼
    1. <invoker-proxy-bindings>  
    2.     <invoker-proxy-binding>  
    3.         <name>activemq-message-driven-beanname>  
    4.         <invoker-mbean>defaultinvoker-mbean>  
    5.         <proxy-factory>org.jboss.ejb.plugins.inflow.JBossMessageEndpointFactoryproxy-factory>  
    6.         <proxy-factory-config>  
    7.             <endpoint-interceptors>  
    8.                 <interceptor>org.jboss.proxy.ClientMethodInterceptorinterceptor>  
    9.                 <interceptor>org.jboss.ejb.plugins.inflow.MessageEndpointInterceptorinterceptor>  
    10.                 <interceptor>org.jboss.proxy.TransactionInterceptorinterceptor>  
    11.                 <interceptor>org.jboss.invocation.InvokerInterceptorinterceptor>  
    12.             endpoint-interceptors>  
    13.         proxy-factory-config>  
    14.     invoker-proxy-binding>  
    15. invoker-proxy-bindings>  

    MessageDrivenBean的container配置,這里的必須和上面的相同 才能起作用.


     

    xml 代碼
    1. <container-configurations>  
    2.     <container-configuration>  
    3.         <container-name>ActiveMQ Message Driven Beancontainer-name>  
    4.         <call-logging>falsecall-logging>  
    5.         <invoker-proxy-binding-name>activemq-message-driven-beaninvoker-proxy-binding-name>  
    6.         <container-interceptors>  
    7.             <interceptor>org.jboss.ejb.plugins.ProxyFactoryFinderInterceptorinterceptor>  
    8.                 <interceptor>org.jboss.ejb.plugins.LogInterceptorinterceptor>  
    9.                 <interceptor>org.jboss.ejb.plugins.RunAsSecurityInterceptorinterceptor>  
    10.                 <!-- CMT -->  
    11.                 <interceptor transaction="Container">org.jboss.ejb.plugins.TxInterceptorCMTinterceptor>  
    12.                 <interceptor transaction="Container">org.jboss.ejb.plugins.CallValidationInterceptorinterceptor>  
    13.                 <interceptor transaction="Container" metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptorinterceptor>  
    14.                 <interceptor transaction="Container">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptorinterceptor>  
    15.                 <!-- BMT -->  
    16.                 <interceptor transaction="Bean">org.jboss.ejb.plugins.MessageDrivenInstanceInterceptorinterceptor>  
    17.                 <interceptor transaction="Bean">org.jboss.ejb.plugins.MessageDrivenTxInterceptorBMTinterceptor>  
    18.                 <interceptor transaction="Bean">org.jboss.ejb.plugins.CallValidationInterceptorinterceptor>  
    19.                 <interceptor transaction="Bean" metricsEnabled="true">org.jboss.ejb.plugins.MetricsInterceptorinterceptor>  
    20.                 <interceptor>org.jboss.resource.connectionmanager.CachedConnectionInterceptorinterceptor>  
    21.         container-interceptors>  
    22.         <instance-pool>org.jboss.ejb.plugins.MessageDrivenInstancePoolinstance-pool>  
    23.         <instance-cache>instance-cache>  
    24.         <persistence-manager>persistence-manager>  
    25.         <container-pool-conf>  
    26.                 <MaximumSize>100MaximumSize>  
    27.         container-pool-conf>  
    28.         container-configuration>  
    29. container-configurations>  

    以上就是ActiveMQ+JBoss InBound 的配置

    三.在Servlet中通過發(fā)送消息,驗證上面的Message Driven Bean

         為了驗證這個MessageDrivenBean能夠正常工作,我使用一個很簡單的servlet向這個queue發(fā)送消息,前一篇的activemq-ds.xml 已經(jīng)提供在啟動的時候綁定了JNDI activemq/QueueConnectionFactory,activemq/queue/outbound,我們直接使用就行了,

    java 代碼
    1. try {   
    2.         initialContext = new InitialContext();   
    3.         QueueConnectionFactory connectionFactory = (QueueConnectionFactory) initialContext   
    4.                 .lookup("java:activemq/QueueConnectionFactory");   
    5.            Connection con=connectionFactory.createConnection();   
    6.         Session session =  con.createSession(false, Session.AUTO_ACKNOWLEDGE);   
    7.   
    8.         Queue queue = (Queue) initialContext.lookup("activemq/queue/outbound");   
    9.         MessageProducer producer = session.createProducer(queue);   
    10.         TextMessage txtMessage = session.createTextMessage();   
    11.         txtMessage.setText("A");   
    12.         producer.send(txtMessage);   
    13.         producer.close();   
    14.         session.close();   
    15.         con.close();   
    16.            
    17.     } catch (NamingException e) {   
    18.         // TODO Auto-generated catch block   
    19.         e.printStackTrace();   
    20.     } catch (JMSException e) {   
    21.         // TODO Auto-generated catch block   
    22.         e.printStackTrace();   
    23.     }   

    四.關(guān)于durable方式訂閱topic的補充說明
         使用durable方式,你需要在ejb-jar.xml中額外的配置,subscriptionDurability,clientId,subscriptionName

    xml 代碼
    1. <activation-config>  
    2.     <activation-config-property>  
    3.         ......   
    4.         <activation-config-property>  
    5.             <activation-config-property-name>subscriptionDurabilityactivation-config-property-name>  
    6.             <activation-config-property-value>Durableactivation-config-property-value>  
    7.         activation-config-property>  
    8.         <activation-config-property>  
    9.             <activation-config-property-name>clientIdactivation-config-property-name>  
    10.             <activation-config-property-value>fooactivation-config-property-value>  
    11.         activation-config-property>  
    12.         <activation-config-property>  
    13.             <activation-config-property-name>subscriptionNameactivation-config-property-name>  
    14.             <activation-config-property-value>baractivation-config-property-value>  
    15.         activation-config-property>  
    16.         ......   
    17.     activation-config-property>  
    18. activation-config>  

     

    ok 這樣就可以使用durable方式訂閱topic了。

    參考文檔:
            JBoss Integration
           ActiveMQ Inbound Communication
        ActiveMQ Outbound Communication


    posted @ 2007-11-16 17:10 hk2000c 閱讀(561) | 評論 (0)編輯 收藏

    關(guān)鍵字:   ActiveMQ    

          ActiveMQ本身是開源項目,所以采用ActiveMQ的項目往往也是以其他開源軟件共同構(gòu)建,目前主流開源應(yīng)用服務(wù)器有Boss,geronimo,JOnAs,而其中g(shù)eronimo 默認的JMS Provider就是ActiveMQ,那我們就著重介紹ActiveMQ與JBoss,JOnAs的整合方案

    本文參考了 Integrating Apache ActiveMQ with JBossJBoss Integration,再根據(jù)筆者實際整合經(jīng)驗總結(jié)而成。

     一.整合需要的環(huán)境.
                  jdk1.5
                  jboss-4.0.5.GA
                  activemq-ra-4.1.0-incubator.rar  (在ActiveMQ 4.*  lib\optional 目錄里面有對應(yīng)的ra的壓縮包)
       開始整合前請確保jboss能夠正確的啟動起來。

                 二.整合步驟

                  1. 步驟一: 解壓activemq-rar-4.1.0-incubator.rar 到 jboss-4.0.5.GA\server\default\deploy\activemq-ra.rar (這個是目錄名字) 下面是activemq-rar.rar目錄下面的文件和子目錄,請注意紅色標(biāo)記的地方(后面會逐一說明,整合的過程)

                  activeio-core-3.0.0-incubator.jar
                  activemq-core-4.1.0-incubator.jar
                  activemq-ra-4.1.0-incubator.jar
                  backport-util-concurrent-2.1.jar
                  commons-logging-1.0.3.jar
                  derby-10.1.1.0.jar
                  geronimo-j2ee-management_1.0_spec-1.0.jar
                  spring-2.0.jar
                  spring-1.2.6.jar
                  xbean-spring-2.7.jar
                  broker-config.xml
                  META-INF 
     2.步驟二. 刪除多余的spring-1.2.6.jar,由于4.1.0的ra里面包含了2個不同版本的spring會觸發(fā)一個exception的產(chǎn)生,https://issues.apache.org/activemq/browse/AMQ-1124, 而且為了以后能夠使用新的spring schema配置方式,我們這里會刪除spring-1.2.6.jar,保留spring-2.0.jar。(最新的snapshot version的ra已經(jīng)去掉了這個多余的spring-1.2.6.jar).

                   3.步驟三: 修改META-INF\ra.xml,讓JBoss使用broker-config.xml 作為默認的配置文件配置borker. 修改下面的地方

    1. <config-property-value>config-property-value>              
    2. <!--  <config-property-value>xbean:broker-config.xml</config-property-value>-->  

          改為:

    1. <!-- <config-property-value></config-property-value> -->  
    2. <config-property-value>xbean:broker-config.xmlconfig-property-value>  

        表示使用broker-config.xml來配置啟動ActiveMQ.
     
                     4.步驟四: 修改borker-config.xml,默認的borker-config.xml會產(chǎn)生一個錯誤,無論是我使用的版本還是最后的snapshot版本,默認的borker-config.xml都會讓xbean-spring 2.7(snapshot 使用的是2.8)拋出exception.解決的辦法如下
           將        
    1. <beans xmlns="http://activemq.org/config/1.0">  
    2.           <broker useJmx="true" >    
         
         改為
     
    1. <beans>  
    2. <broker useJmx="true" xmlns="http://activemq.org/config/1.0">  
     
       即可
           
                  5.步驟五: 將xbean-spring-2.7.jar (或者是2.8) 復(fù)制到j(luò)boss-4.0.5.GA\server\default\lib下面
     
              三 使用整合完畢的ActiveMQ作為ds綁定到JBoss的JNDI服務(wù)。
                    編寫jboss-4.0.5.GA\server\default\depoly\activemq-ds.xml
    xml 代碼
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <!DOCTYPE connection-factories   
    3.     PUBLIC "-//JBoss//DTD JBOSS JCA Config 1.5//EN"   
    4.     "http://www.jboss.org/j2ee/dtd/jboss-ds_1_5.dtd">  
    5.   
    6. <connection-factories>  
    7.    <tx-connection-factory>  
    8.       <jndi-name>activemq/QueueConnectionFactory</jndi-name>  
    9.       <xa-transaction/>  
    10.       <track-connection-by-tx/>  
    11.       <rar-name>activemq-ra.rar</rar-name>  
    12.       <connection-definition>javax.jms.QueueConnectionFactory</connection-definition>  
    13.       <ServerUrl>tcp://localhost:61616</ServerUrl>  
    14.       <min-pool-size>1</min-pool-size>  
    15.       <max-pool-size>200</max-pool-size>  
    16.       <blocking-timeout-millis>30000</blocking-timeout-millis>  
    17.       <idle-timeout-minutes>3</idle-timeout-minutes>  
    18.    </tx-connection-factory>  
    19.   
    20.    <tx-connection-factory>  
    21.       <jndi-name>activemq/TopicConnectionFactory</jndi-name>  
    22.       <xa-transaction/>  
    23.       <track-connection-by-tx/>  
    24.       <rar-name>activemq-ra.rar</rar-name>  
    25.       <connection-definition>javax.jms.TopicConnectionFactory</connection-definition>  
    26.       <ServerUrl>tcp://localhost:61616</ServerUrl>  
    27.       <min-pool-size>1</min-pool-size>  
    28.       <max-pool-size>200</max-pool-size>  
    29.       <blocking-timeout-millis>30000</blocking-timeout-millis>  
    30.       <idle-timeout-minutes>3</idle-timeout-minutes>  
    31.    </tx-connection-factory>  
    32.       
    33.    <mbean code="org.jboss.resource.deployment.AdminObject" name="activemq.queue:name=outboundQueue">  
    34.       <attribute name="JNDIName">activemq/queue/outbound</attribute>  
    35.       <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name=&apos;activemq-ra.rar&apos;</depends>  
    36.       <attribute name="Type">javax.jms.Queue</attribute>  
    37.       <attribute name="Properties">PhysicalName=queue.outbound</attribute>  
    38.    </mbean>  
    39.   
    40.    <mbean code="org.jboss.resource.deployment.AdminObject" name="activemq.topic:name=inboundTopic">  
    41.       <attribute name="JNDIName">activemq/topic/inbound</attribute>  
    42.       <depends optional-attribute-name="RARName">jboss.jca:service=RARDeployment,name=&apos;activemq-ra.rar&apos;</depends>  
    43.       <attribute name="Type">javax.jms.Topic</attribute>  
    44.       <attribute name="Properties">PhysicalName=topic.inbound</attribute>  
    45.    </mbean>  
    46.   
    47. </connection-factories>  
                   
                   啟動JBoss.如果看見以下信息就表示ActiveMQ已經(jīng)成功啟動,并且使用上面的ds配置文件成功地將topic/queue綁定到了JNDI服務(wù)上。
                  ......
                  [TransportConnector] Connector tcp://localhost:61616 Started
                  [NetworkConnector] Network Connector bridge Started
                  [BrokerService] ActiveMQ JMS Message Broker (localhost, ID:MyNoteBook-2165-1173250880171-1:0) started
                  ......
                  [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=ConnectionFactoryBinding,name=activemq/QueueConnectionFactory' to JNDI name 'java:activemq/QueueConnectionFactory'
                  [ConnectionFactoryBindingService] Bound ConnectionManager 'jboss.jca:service=ConnectionFactoryBinding,name=activemq/TopicConnectionFactory' to JNDI name 'java:activemq/TopicConnectionFactory'
                    [AdminObject] Bound admin object 'org.apache.activemq.command.ActiveMQQueue' at 'activemq/queue/outbound'
                    [AdminObject] Bound admin object 'org.apache.activemq.command.ActiveMQTopic' at 'activemq/topic/inbound
                    ......
                  
                 四.驗證ActiveMQ+JBoss
                 這里你可以使用簡單的jms  client連接到broker-config.xml里面的協(xié)議連接器上面,默認的是tcp://localhost:61616
                 在后面我們會在此整合基礎(chǔ)上開發(fā)Message Driver Bean和使用spring MDP 2種構(gòu)架 來驗證本次ActiveMQ+JBoss的整合。
    posted @ 2007-11-16 17:06 hk2000c 閱讀(598) | 評論 (0)編輯 收藏

      作者 cctvx1
        程度: 入門


        一.安裝ActiveMQ

           首先去http://activemq.apache.org/download.html 下載最新版本4.1.0release (http://activemq.apache.org/activemq-410-release.html),
        解壓apache-activemq-4.1-incubator.zip(或者apache-activemq-4.1-incubator.tar.gz)目錄如下:
          
           +bin       (windows下面的bat和unix/linux下面的sh)
           +conf      (activeMQ配置目錄,包含最基本的activeMQ配置文件)
           +data      (默認是空的)
           +docs      (index,replease版本里面沒有文檔,-.-b不知道為啥不帶)
           +example   (幾個例子
           +lib       (activemMQ使用到的lib)
           -apache-activemq-4.1-incubator.jar  (ActiveMQ的binary)
           -LICENSE.txt      
           -NOTICE.txt       
           -README.txt
           -user-guide.html


           你可以使用bin\activemq.bat(activemq) 啟動,如果一切順利,你就會看見類似下面的信息
          (細節(jié)可能不一樣,比如路徑,或者jmx,jdbc信息)

      ACTIVEMQ_HOME: D:\java\framework_and_lib\activemq\apache-activemq-4.1-incubator\
    bin\..
    Loading message broker from: xbean:activemq.xml
    INFO  BrokerService                  - ActiveMQ null JMS Message Broker (localho
    st) is starting
    INFO  BrokerService                  - For help or more information please see:
    http://incubator.apache.org/activemq/
    INFO  ManagementContext              - JMX consoles can connect to service:jmx:r
    mi:///jndi/rmi://localhost:1099/jmxrmi
    INFO  JDBCPersistenceAdapter         - Database driver recognized: [apache_derby
    _embedded_jdbc_driver]
    INFO  DefaultDatabaseLocker          - Attempting to acquire the exclusive lock
    to become the Master broker
    INFO  DefaultDatabaseLocker          - Becoming the master on dataSource: org.ap
    ache.derby.jdbc.EmbeddedDataSource@1d840cd
    INFO  JournalPersistenceAdapter      - Journal Recovery Started from: Active Jou
    rnal: using 5 x 20.0 Megs at: D:\java\framework_and_lib\activemq\apache-activemq
    -4.1-incubator\activemq-data\journal
    INFO  JournalPersistenceAdapter      - Journal Recovered: 0 message(s) in transa
    ctions recovered.
    INFO  TransportServerThreadSupport   - Listening for connections at: tcp://P-SUW
    EI:61616
    WARN  MulticastDiscoveryAgent        - brokerName not set
    INFO  TransportConnector             - Connector default Started
    INFO  TransportServerThreadSupport   - Listening for connections at: stomp://P-S
    UWEI:61613
    INFO  TransportConnector             - Connector stomp Started
    INFO  NetworkConnector               - Network Connector default Started
    INFO  BrokerService                  - ActiveMQ JMS Message Broker (localhost, I
    D:P-SUWEI-1207-1170916242296-1:0) started     

             *。幾個小提示
      1. 這個僅僅是最基礎(chǔ)的ActiveMQ的配置,很多地方都沒有配置因此不要直接使用這個配置用于生產(chǎn)系統(tǒng)
      2. 有的時候由于端口被占用,導(dǎo)致ActiveMQ錯誤,ActiveMQ可能需要以下端口1099(JMX),61616(默認的TransportConnector)
      3. 如果沒有物理網(wǎng)卡,或者MS的LoopBackAdpater Multicast會報一個錯誤

         二. 測試你的ActiveMQ
           
              由于ActiveMQ是一個獨立的jms provider,所以我們不需要其他任何第三方服務(wù)器就可以馬上做我們的測試了.編譯
         example目錄下面的程序
             
       ProducerTool/ConsumerTool 是JMS參考里面提到的典型應(yīng)用,Producer產(chǎn)生消息,Consumer消費消息
       而且這個例子還可以加入?yún)?shù)幫助你測試剛才啟動的本地ActiveMQ或者是遠程的ActiveMQ

       ProducerTool [url] broker的地址,默認的是tcp://localhost:61616
                    [true|flase] 是否使用topic,默認是false
             [subject] subject的名字,默認是TOOL.DEFAULT
             [durabl] 是否持久化消息,默認是false
             [messagecount] 發(fā)送消息數(shù)量,默認是10
             [messagesize] 消息長度,默認是255
             [clientID] durable為true的時候,需要配置clientID
             [timeToLive] 消息存活時間
             [sleepTime] 發(fā)送消息中間的休眠時間
             [transacte]  是否采用事務(wù)

             
              ConsumerTool [url] broker的地址,默認的是tcp://localhost:61616
                    [true|flase] 是否使用topic,默認是false
             [subject] subject的名字,默認是TOOL.DEFAULT
             [durabl] 是否持久化消息,默認是false
             [maxiumMessages] 接受最大消息數(shù)量,0表示不限制
           
             [clientID] durable為true的時候,需要配置clientID
            
             [transacte]  是否采用事務(wù)
             [sleepTime]  接受消息中間的休眠時間,默認是0,onMeesage方法不休眠
             [receiveTimeOut] 接受超時

              我們這樣可以使用:
       java -classpath .\apache-activemq-4.1-incubator.jar;example\bin ProducerTool  tcp://192.168.3.142:61616 test.mysubject
       java -classpath .\apache-activemq-4.1-incubator.jar;example\bin ConsumerTool  tcp://192.168.3.142:61616 test.mysubject

       當(dāng)然你可以使用上面的參數(shù)進行更復(fù)雜的測試,持久,事務(wù)

       如果出現(xiàn)下面的信息,恭喜你,你的ActiveMQ已經(jīng)能夠工作了
            
      Connecting to URL: tcp://192.168.3.142:61616
      Publishing a Message with size 255 to queue: TOOL.DEFAULT
      Using non-durable publishing
      Sleeping between publish 0 ms
      Sending message: Message: 0 sent at: Thu Feb 08 15:05:34 CST 2007  ...
      Sending message: Message: 1 sent at: Thu Feb 08 15:05:34 CST 2007  ...
             。。。。。。。。


      Connecting to URL: tcp://192.168.3.142:61616
      Consuming queue: test.mysubject
             Using non-durable subscription
             Received: Message: 0 sent at: Thu Feb 08 14:51:34 CST 2007  ...
             Received: Message: 1 sent at: Thu Feb 08 14:51:34 CST 2007  ...
      。。。。


             三.小結(jié)
         
          我們已經(jīng)下載,啟動,并且用程序測試了我們的ActiveMQ,而后面將在這個能跑得ActiveMQ進一步的走下去,一步一步展示ActiveMQ的高級特性。

    posted @ 2007-11-16 17:05 hk2000c 閱讀(4557) | 評論 (0)編輯 收藏

    本篇主要講解在未使用其他框架(Spring)整合情況下,獨立基于ActiveMQ,使用JMS規(guī)范進行消息通信。
        
         一.JMS回顧
           因為ActiveMQ是一個JMS Provider的實現(xiàn),因此在開始實作前,有必要復(fù)習(xí)下JMS的基礎(chǔ)知識
        Java Message Service (JMS)是sun提出來的為J2EE提供企業(yè)消息處理的一套規(guī)范,JMS目前有2套規(guī)范還在使用JMS 1.0.2b和1.1. 1.1已經(jīng)成為主流的JMS Provider事實上的標(biāo)準(zhǔn)了.
          *1.1主要在session上面有一些重要改變,比如支持建立同一session上的transaction,讓他支持同時發(fā)送P2P(Queue)消息和接受
    Topic消息。
          
           在JMS中間主要定義了2種消息模式Point-to-Point (點對點),Publich/Subscribe Model (發(fā)布/訂閱者),
        其中在Publich/Subscribe 模式下又有Nondurable subscription和durable subscription (持久化訂閱)2種消息處理方式。
        
         下面是JMS規(guī)范基本的接口和實現(xiàn)
         JMS Common Interfacse PTP-Specific Interface   Pub/Sub-specific interfaces
         ConnectionFactory     QueueConnectionFactory   TopicConnectionFactory
         Connection            QueueConnection          TopicConnection
         Destination           Queue                    Topic
         Session               QueueSession             TopiSession
         MessageProducer       QueueSender              TopicPublisher
         MessageConsumer       QueueReceiver/QueueBrwer TopicSubscriber


         二.使用Queue

             下面以ActiveMQ example的代碼為主進行說明
            
            1. 使用ActiveMQ的Connection,ConnectionFactory 建立連接,注意這里沒有用到pool
           

    java 代碼
    1. import org.apache.activemq.ActiveMQConnection   
    2. import org.apache.activemq.ActiveMQConnectionFactory   

            //建立Connection

    java 代碼
    1. protected Connection createConnection() throws JMSException, Exception {   
    2.      ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, pwd, url);   
    3.      Connection connection = connectionFactory.createConnection();   
    4.      if (durable && clientID!=null) {   
    5.          connection.setClientID(clientID);   
    6.      }   
    7.      connection.start();   
    8.      return connection;   
    9.     }  

            //建立Session
      

    java 代碼
    1. protected Session createSession(Connection connection) throws Exception {   
    2.          Session session = connection.createSession(transacted, ackMode);   
    3.          return session;   
    4.         }   

            2。發(fā)送消息的代碼
     //建立QueueSession
     

    java 代碼
    1. protected MessageProducer createProducer(Session session) throws JMSException {   
    2.         Destincation destination = session.createQueue("queue.hello");   
    3.         MessageProducer producer = session.createProducer(destination);   
    4.         producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);   
    5.            
    6.         if( timeToLive!=0 )   
    7.             producer.setTimeToLive(timeToLive);   
    8.         return producer;   
    9.         }   

             //使用Producer發(fā)送消息到Queue
        

    java 代碼
    1. producer.send(message);   

           
            3。接受消息,在JMS規(guī)范里面,你可以使用
      

    java 代碼
    1. QueueReceiver/QueueBrowser直接接受消息,但是更多的情況下我們采用消息通知方式,即實現(xiàn)MessageListener接口   
    2.  public void onMessage(Message message) {   
    3.  //process message   
    4.  }   
    5.           
    6.  //set MessageListner ,receive message   
    7.  Destincation destination = session.createQueue("queue.hello");   
    8.  consumer = session.createConsumer(destination);   
    9.  consumer.setMessageListener(this);   

           
            以上就是使用jms queue發(fā)送接受消息的基本方式

     
         三 Topic

            1. 建立連接
       

    java 代碼
    1. protected Connection createConnection() throws JMSException, Exception {      
    2.         ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(user, pwd, url);      
    3.         Connection connection = connectionFactory.createConnection();      
    4.         //如果你要使用DurableSubScription 方式,你必須為connection設(shè)置一個ClientID      
    5.         if (durable && clientID!=null) {      
    6.             connection.setClientID(clientID);      
    7.         }      
    8.         connection.start();      
    9.         return connection;      
    10.        }      

           2. 建立Session

    java 代碼
    1. protected Session createSession(Connection connection) throws Exception {      
    2.         Session session = connection.createSession(transacted, ackMode);      
    3.         return session;      
    4.         }    

     3.創(chuàng)建Producer 發(fā)送消息到Topic   
           

    java 代碼
    1. //create topic on  session   
    2.        topic = session.createTopic("topic.hello");   
    3.  producer = session.createProducer(topic);   
    4.        //send message    
    5.        producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);   
    6.  producer.send(message);   


     4.創(chuàng)建Consumer接受消息(基本上和Queue相同)

    java 代碼
    1. Destincation destination  = session.createTopic("topic.hello");      
    2. MessageConsumer consumer = session.createConsumer(destination);      
    3. consumer.setMessageListener(this);      
    4.            
    5.      //如果你使用的是Durable Subscription方式,你必須在建立connection的時候      
    6.      //設(shè)置ClientID,而且建立comsumer的時候使用createDurableSubscriber方法,為他指定一個consumerName。      
    7.  //connection.setClientID(clientId);      
    8.  //consumer = session.createDurableSubscriber((Topic) destination, consumerName);   

           
     四:連接ActiveMQ的方式
            ActiveMQConnectionFactory 提供了多種連接到Broker的方式activemq.apache.org/uri-protocols.html

     常見的有
     vm://host:port     //vm
     tcp://host:port    //tcp
     ssl://host:port    //SSL
     stomp://host:port  //stomp協(xié)議可以跨語言,目前有很多種stomp client 庫(java,c#,c/c++,ruby,python...);

    posted @ 2007-11-16 17:05 hk2000c 閱讀(8329) | 評論 (2)編輯 收藏

    郁悶了三天,今天終于把JMS弄出來了,就是發(fā)送消息,然后消息監(jiān)聽器接收到了消息后發(fā)送郵件給管理員

    先看web.xml里面關(guān)于activemq的invoke

    <!--調(diào)用activemq -->
        <context-param >
         <param-name>brokerURI </param-name >
         <param-value>/WEB-INF/activemq.xml </param-value >
        </context-param>
       
        <listener>
           <listener-class>org.activemq.web.SpringBrokerContextListener</listener-class>
        </listener>


    郁悶了三天,今天終于把JMS弄出來了,就是發(fā)送消息,然后消息監(jiān)聽器接收到了消息后發(fā)送郵件給管理員

    先看web.xml里面關(guān)于activemq的invoke

    <!--調(diào)用activemq -->
        <context-param >
         <param-name>brokerURI </param-name >
         <param-value>/WEB-INF/activemq.xml </param-value >
        </context-param>
       
        <listener>
           <listener-class>org.activemq.web.SpringBrokerContextListener</listener-class>
        </listener>

    然后是在上下文中定義的JmsTemplate和activemq監(jiān)聽

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "
    http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>

    <!--JMS Template-->
        <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
            <property name="connectionFactory">
          <bean class="org.activemq.ActiveMQConnectionFactory">
           <property name="brokerURL">
            <value>tcp://localhost:61616</value>
           </property>
          </bean>
         </property>
         
          <property name="defaultDestinationName" value="Hello.Queue"/>
        </bean>

       <bean id="activeMQContainer" class="org.activemq.jca.JCAContainer">
         <property name="workManager">
           <bean id="workManager" class="org.activemq.work.SpringWorkManager"/>
         </property>

         <property name="resourceAdapter">
           <bean id="activeMQResourceAdapter"
               class="org.activemq.ra.ActiveMQResourceAdapter">
             <property name="serverUrl" value="tcp://localhost:61616"/>
           </bean>
         </property>
       </bean>
     

      <!--監(jiān)聽 Message 的Message Driven POJO-->
        <bean id="HelloPlaceBean" class="com.officetao.jms.HelloMDP" autowire="byName"/>

      <bean id="HelloMDP" factory-method="addConnector" factory-bean="activeMQContainer">
         <property name="activationSpec">
           <bean class="org.activemq.ra.ActiveMQActivationSpec">
             <property name="destination" value="Hello.Queue"/>
             <property name="destinationType" value="javax.jms.Queue"/>
           </bean>
         </property>
         <property name="ref" value="HelloBean" />
       </bean>

    </beans>

    建立一個模擬的發(fā)送消息的bean,內(nèi)容如下

    final String mailContent = "新增單號為0000的訂單, 金額";
      try {
                if (jmsTemplate != null)
                    jmsTemplate.send(new MessageCreator() {
                        public Message createMessage(Session session)
                                throws JMSException {
                            Message message = session.createMessage();
                            message.setStringProperty("content", mailContent);
                            return message;
                        }
                    });
            }
            catch (Exception e) {
                logger.error("JMS error when place order:", e);
            }

    最后就是監(jiān)聽消息然后采取行動的bean


    public class HelloMDP implements MessageListener {


     
     public void onMessage(javax.jms.Message arg0) {
      
      try   {  
                subAuthenticator   subauth   =   new   subAuthenticator("郵箱登陸名","密碼");//smtp驗證   authenticator  
                props.put("mail.smtp.host","smtp.163.com");  
                props.put("mail.smtp.auth","true");  
                session   =   Session.getInstance(props,subauth);  
                MimeMessage   message   =   new   MimeMessage(session);  
                message.setRecipient(Message.RecipientType.TO,new   InternetAddress("
    接收郵件的郵箱"));  
                message.setFrom(new   InternetAddress("
    自己的郵箱"));  
                message.setSubject("ok");  
                message.setText("if you see it,it works!");  
                Transport.send(message);
            }  
            catch(AuthenticationFailedException   e1){  
                System.out.println("SMTP認證出錯!");  
            }  
            catch   (MessagingException   e)   {  
                e.printStackTrace();
            }  
     
    }

    public   static   Properties   props   =   System.getProperties();
    public   static   Session   session   =   null;  

    /**  
    *此內(nèi)部類定義了smtp認證方法  
    */  
    public   class   subAuthenticator   extends   Authenticator{  
    private   String   userName;  
    private   String   password;  
    public   subAuthenticator(String   user,String   pass){  
        userName=user;  
        password=pass;  
    }  
    public   PasswordAuthentication   getPasswordAuthentication(){  
        return   new   PasswordAuthentication(userName,password);  
    }  

    posted @ 2007-11-16 16:49 hk2000c 閱讀(1121) | 評論 (0)編輯 收藏

     JMS做為J2EE的高級部分一直蒙著一層神秘的面紗,作為JMS的定制者SUN只規(guī)定了JMS規(guī)范,象很多其他SUN產(chǎn)品一樣被多家廠商提供了具體的實現(xiàn)。但是作為tomcat和RESIN(今年初宣布全部支持J2EE規(guī)范)。這些面向低端但卻被廣泛應(yīng)用的服務(wù)器本身并不對JMS提供支持。慶幸的是openjms和activeMQ兩家開源軟件提供了插件式的支持。

        在應(yīng)用了一些開發(fā)框架如spring的項目里如果要使用到JMS,雖然SPRING提供了部分對JMS的支持但經(jīng)過我一段時間的應(yīng)用發(fā)現(xiàn),OO的封裝在某些地方反而成為開發(fā)過程中的障礙。在實現(xiàn)諸如監(jiān)聽之類的代碼段里使人非常的懊惱,即使用callback(回調(diào))有些東西仍然不能夠很好的被取到。

    下面就一些TOMCAT上面JMS的支持既實現(xiàn)做一下整理。

    1.很自然的你需要下載JMS實現(xiàn),如:opnerJMS或者activeMQ .下載地址www.jmsopen.com 或www.activeMQ.com

    2.服務(wù)器下載以后的具體配置在以上兩個網(wǎng)站上都有很詳細的說明,就不再列舉了。

    3.和WEB服務(wù)器的整合,首先要配置應(yīng)用的web.xml這個文件配置如下:

    1  <context-param>
                2  <param-name>brokerURI</param-name>
                3  <param-value>/WEB-INF/activemq.xml</param-value>
                4  </context-param>
                5
                6  <listener>
                7  <listener-class>org.activemq.web.SpringBrokerContextListener</listener-class>
                8  </listener>


    將這一段代碼放到web.xml里。注意到activemq.xml文件,是jms服務(wù)器的具體配置:

    <?xml version="1.0" encoding="UTF-8"?>
                <!DOCTYPE beans PUBLIC
                "-//ACTIVEMQ//DTD//EN"
                "http://activemq.org/dtd/activemq.dtd">
                <beans>
                <!-- ===================== -->
                <!-- ActiveMQ Broker Configuration -->
                <!-- ===================== -->
                <broker>
                <connector>
                <tcpServerTransport
                uri="tcp://localhost:61616"
                useAsyncSend="true"
                maxOutstandingMessages="50"/>
                </connector>
                <!-- to enable Stomp support uncomment this
                <connector>
                <serverTransport
                uri="stomp://localhost:61626"/>
                </connector>
                -->
                <persistence>
                <jdbcPersistence
                dataSourceRef="oracle-ds"/>
                </persistence>
                </broker>
                <!-- ======================= -->
                <!-- JDBC DataSource Configurations -->
                <!-- ======================= -->
                <!-- The Derby Datasource
                that will be used by the Broker -->
                <bean id="derby-ds" class=
                "org.apache.commons.dbcp.BasicDataSource"
                destroy-method="close">
                <property name="driverClassName">
                <value>
                org.apache.derby.jdbc.EmbeddedDriver
                </value>
                </property>
                <property name="url">
                <!-- Use a URL like
                'jdbc:hsqldb:hsql://localhost:9001'
                if you want to connect to a remote hsqldb -->
                <value>
                jdbc:derby:derbydb;create=true
                </value>
                </property>
                <property name="username">
                <value></value>
                </property>
                <property name="password">
                <value></value>
                </property>
                <property name="poolPreparedStatements">
                <value>true</value>
                </property>
                </bean>
                </beans>


    此時,在啟動你的TOMCAT的時候會看到JMS服務(wù)器已經(jīng)綁到了上面。
    posted @ 2007-11-16 16:48 hk2000c 閱讀(3904) | 評論 (0)編輯 收藏

         摘要: [原創(chuàng)] SSO(Single Sign-on) in Action(上篇) 1. SSO 原理淺談        SSO 是一個非常大的主題,我對這個主題有著深深的感受,自從廣州 UserGroup 的論壇成立以來,無數(shù)網(wǎng)友都在嘗試使用開源的 CAS , Kerberos 也提供另外一種方式的 SSO ,即基于 Windows ...  閱讀全文
    posted @ 2007-11-16 16:27 hk2000c 閱讀(382) | 評論 (0)編輯 收藏

    僅列出標(biāo)題
    共11頁: 上一頁 1 2 3 4 5 6 7 8 9 下一頁 Last 
    主站蜘蛛池模板: 免费A级毛片无码久久版| 日产亚洲一区二区三区| 亚洲AV无码一区二区三区人| 一级毛片完整版免费播放一区| 麻豆一区二区免费播放网站| 亚洲精品无码午夜福利中文字幕| 亚洲精品第一国产综合亚AV| 无码人妻丰满熟妇区免费| 男人的天堂亚洲一区二区三区| 99人中文字幕亚洲区| 国产精品免费久久久久久久久 | 国产男女猛烈无遮挡免费视频网站 | 无码国产精品久久一区免费 | 亚洲第一se情网站| 亚洲视频免费在线看| 亚洲人成网77777色在线播放| 久久亚洲色WWW成人欧美| 中文毛片无遮挡高潮免费| 亚洲a一级免费视频| 久久久久久噜噜精品免费直播| 成人午夜18免费看| 亚洲小视频在线播放| 久操视频免费观看| 丁香五月亚洲综合深深爱| 国产亚洲综合久久| 成人免费视频一区二区三区| 亚洲精品成人图区| 日本xxxx色视频在线观看免费| 亚洲无人区午夜福利码高清完整版| 国产精品亚洲专一区二区三区| 好爽又高潮了毛片免费下载| 亚洲国产中文在线视频| 免费人妻无码不卡中文字幕系| 亚洲精品无码国产| aa毛片免费全部播放完整| 亚洲国产香蕉人人爽成AV片久久 | 久久精品国产亚洲精品2020| 免费日本一区二区| 久久精品国产亚洲香蕉| 中文在线观看免费网站| 中文国产成人精品久久亚洲精品AⅤ无码精品 |