hk2000c技術(shù)專欄

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

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

          #

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

          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)建存儲(chǔ)過(guò)程:

          代碼
          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;  

           

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

          3. 完整實(shí)現(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. 測(cè)試代碼,在這里使用了Junit4測(cè)試:

          代碼
          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. 測(cè)試的輸出結(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 閱讀(3559) | 評(píng)論 (2)編輯 收藏

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

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

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

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

          // 調(diào)用有一個(gè)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)用有一個(gè)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)用有一個(gè)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 閱讀(300) | 評(píng)論 (0)編輯 收藏

          這段時(shí)間開(kāi)始學(xué)習(xí)寫存儲(chǔ)過(guò)程,主要原因還是因?yàn)楣ぷ餍枰桑緛?lái)以為很簡(jiǎn)單的,但幾經(jīng)挫折,豪氣消磨殆盡,但總算搞通了,為了避免后來(lái)者少走彎路,特記述與此,同時(shí)亦對(duì)自己進(jìn)行鼓勵(lì)。

          一:無(wú)返回值的存儲(chǔ)過(guò)程

          存儲(chǔ)過(guò)程為:

          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)用時(shí)就用下面的代碼:

          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,里面兩個(gè)字段(I_IDI_NAME)。

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

          存儲(chǔ)過(guò)程為:

          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)用時(shí)就用下面的代碼:

          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并非任意的,而是和存儲(chǔ)過(guò)程中的out列對(duì)應(yīng)的,如果out是在第一個(gè)位置,那就是proc.getString(1),如果是第三個(gè)位置,就是proc.getString(3),當(dāng)然也可以同時(shí)有多個(gè)返回值,那就是再多加幾個(gè)out參數(shù)了。

          三:返回列表

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

          1, 建一個(gè)程序包。如下:

          CREATE OR REPLACE PACKAGE TESTPACKAGE  AS

           TYPE Test_CURSOR IS REF CURSOR;

          end TESTPACKAGE;

          2,建立存儲(chǔ)過(guò)程,存儲(chǔ)過(guò)程為:

          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)(可以理解為一個(gè)指針),作為一個(gè)out 參數(shù)來(lái)返回值的。

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

          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ū)動(dòng)包放到class路徑里,否則會(huì)報(bào)錯(cuò)的。

           

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

          關(guān)鍵字:   ActiveMQ    

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

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

           一. 配置ejb-jar.xml
                
                  1.  ejb-jar.xml 不能使用XML DTD,需要使用XML Schema(XSD)
                      
          很多朋友可能使用XDoclet來(lái)生成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才能完成對(duì)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, 而實(shí)際上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中通過(guò)發(fā)送消息,驗(yàn)證上面的Message Driven Bean

               為了驗(yàn)證這個(gè)MessageDrivenBean能夠正常工作,我使用一個(gè)很簡(jiǎn)單的servlet向這個(gè)queue發(fā)送消息,前一篇的activemq-ds.xml 已經(jīng)提供在啟動(dòng)的時(shí)候綁定了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的補(bǔ)充說(shuō)明
               使用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) | 評(píng)論 (0)編輯 收藏

          關(guān)鍵字:   ActiveMQ    

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

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

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

                       二.整合步驟

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

                        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個(gè)不同版本的spring會(huì)觸發(fā)一個(gè)exception的產(chǎn)生,https://issues.apache.org/activemq/browse/AMQ-1124, 而且為了以后能夠使用新的spring schema配置方式,我們這里會(huì)刪除spring-1.2.6.jar,保留spring-2.0.jar。(最新的snapshot version的ra已經(jīng)去掉了這個(gè)多余的spring-1.2.6.jar).

                         3.步驟三: 修改META-INF\ra.xml,讓JBoss使用broker-config.xml 作為默認(rèn)的配置文件配置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來(lái)配置啟動(dòng)ActiveMQ.
           
                           4.步驟四: 修改borker-config.xml,默認(rèn)的borker-config.xml會(huì)產(chǎn)生一個(gè)錯(cuò)誤,無(wú)論是我使用的版本還是最后的snapshot版本,默認(rèn)的borker-config.xml都會(huì)讓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>  
                         
                         啟動(dòng)JBoss.如果看見(jiàn)以下信息就表示ActiveMQ已經(jīng)成功啟動(dò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
                          ......
                        
                       四.驗(yàn)證ActiveMQ+JBoss
                       這里你可以使用簡(jiǎn)單的jms  client連接到broker-config.xml里面的協(xié)議連接器上面,默認(rèn)的是tcp://localhost:61616
                       在后面我們會(huì)在此整合基礎(chǔ)上開(kāi)發(fā)Message Driver Bean和使用spring MDP 2種構(gòu)架 來(lái)驗(yàn)證本次ActiveMQ+JBoss的整合。
          posted @ 2007-11-16 17:06 hk2000c 閱讀(598) | 評(píng)論 (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      (默認(rèn)是空的)
                 +docs      (index,replease版本里面沒(méi)有文檔,-.-b不知道為啥不帶)
                 +example   (幾個(gè)例子
                 +lib       (activemMQ使用到的lib)
                 -apache-activemq-4.1-incubator.jar  (ActiveMQ的binary)
                 -LICENSE.txt      
                 -NOTICE.txt       
                 -README.txt
                 -user-guide.html


                 你可以使用bin\activemq.bat(activemq) 啟動(dòng),如果一切順利,你就會(huì)看見(jiàn)類似下面的信息
                (細(xì)節(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     

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

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

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

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

                    我們這樣可以使用:
             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ù)進(jìn)行更復(fù)雜的測(cè)試,持久,事務(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)下載,啟動(dòng),并且用程序測(cè)試了我們的ActiveMQ,而后面將在這個(gè)能跑得ActiveMQ進(jìn)一步的走下去,一步一步展示ActiveMQ的高級(jí)特性。

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

          本篇主要講解在未使用其他框架(Spring)整合情況下,獨(dú)立基于ActiveMQ,使用JMS規(guī)范進(jìn)行消息通信。
              
               一.JMS回顧
                 因?yàn)锳ctiveMQ是一個(gè)JMS Provider的實(shí)現(xiàn),因此在開(kāi)始實(shí)作前,有必要復(fù)習(xí)下JMS的基礎(chǔ)知識(shí)
              Java Message Service (JMS)是sun提出來(lái)的為J2EE提供企業(yè)消息處理的一套規(guī)范,JMS目前有2套規(guī)范還在使用JMS 1.0.2b和1.1. 1.1已經(jīng)成為主流的JMS Provider事實(shí)上的標(biāo)準(zhǔn)了.
                *1.1主要在session上面有一些重要改變,比如支持建立同一session上的transaction,讓他支持同時(shí)發(fā)送P2P(Queue)消息和接受
          Topic消息。
                
                 在JMS中間主要定義了2種消息模式Point-to-Point (點(diǎn)對(duì)點(diǎn)),Publich/Subscribe Model (發(fā)布/訂閱者),
              其中在Publich/Subscribe 模式下又有Nondurable subscription和durable subscription (持久化訂閱)2種消息處理方式。
              
               下面是JMS規(guī)范基本的接口和實(shí)現(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的代碼為主進(jìn)行說(shuō)明
                  
                  1. 使用ActiveMQ的Connection,ConnectionFactory 建立連接,注意這里沒(méi)有用到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直接接受消息,但是更多的情況下我們采用消息通知方式,即實(shí)現(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è)置一個(gè)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的時(shí)候      
          6.      //設(shè)置ClientID,而且建立comsumer的時(shí)候使用createDurableSubscriber方法,為他指定一個(gè)consumerName。      
          7.  //connection.setClientID(clientId);      
          8.  //consumer = session.createDurableSubscriber((Topic) destination, consumerName);   

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

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

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

          郁悶了三天,今天終于把JMS弄出來(lái)了,就是發(fā)送消息,然后消息監(jiān)聽(tīng)器接收到了消息后發(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弄出來(lái)了,就是發(fā)送消息,然后消息監(jiān)聽(tīng)器接收到了消息后發(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)聽(tīng)

          <?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)聽(tīng) 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>

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

          final String mailContent = "新增單號(hào)為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)聽(tīng)消息然后采取行動(dòng)的bean


          public class HelloMDP implements MessageListener {


           
           public void onMessage(javax.jms.Message arg0) {
            
            try   {  
                      subAuthenticator   subauth   =   new   subAuthenticator("郵箱登陸名","密碼");//smtp驗(yàn)證   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認(rèn)證出錯(cuò)!");  
                  }  
                  catch   (MessagingException   e)   {  
                      e.printStackTrace();
                  }  
           
          }

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

          /**  
          *此內(nèi)部類定義了smtp認(rèn)證方法  
          */  
          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) | 評(píng)論 (0)編輯 收藏

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

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

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

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

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

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

          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>


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

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

          僅列出標(biāo)題
          共11頁(yè): 上一頁(yè) 1 2 3 4 5 6 7 8 9 下一頁(yè) Last 
          主站蜘蛛池模板: 鲁甸县| 弥勒县| 桐城市| 宜丰县| 临朐县| 清镇市| 滦平县| 富锦市| 黎川县| 麻城市| 登封市| 仙居县| 巴中市| 浠水县| 赤峰市| 闻喜县| 贵港市| 友谊县| 镇巴县| 东平县| 大城县| 当阳市| 汉沽区| 吉安县| 绥阳县| 辽阳县| 龙山县| 潞西市| 营口市| 仙居县| 临澧县| 安化县| 平江县| 璧山县| 泸西县| 盐源县| 新和县| 六枝特区| 江油市| 郧西县| 望江县|