亚洲成人一区二区三区,国产精品久久久久久超碰,欧美绝品在线观看成人午夜影视http://www.aygfsteel.com/waynemao/category/34604.htmlzh-cnSat, 13 Sep 2008 07:27:54 GMTSat, 13 Sep 2008 07:27:54 GMT60EJB3 (7)http://www.aygfsteel.com/waynemao/archive/2008/09/13/228705.htmlwaynemaowaynemaoSat, 13 Sep 2008 03:14:00 GMThttp://www.aygfsteel.com/waynemao/archive/2008/09/13/228705.htmlhttp://www.aygfsteel.com/waynemao/comments/228705.htmlhttp://www.aygfsteel.com/waynemao/archive/2008/09/13/228705.html#Feedback0http://www.aygfsteel.com/waynemao/comments/commentRss/228705.htmlhttp://www.aygfsteel.com/waynemao/services/trackbacks/228705.html有狀態會話bean的開發,首先創建遠程接口:

@Remote
public interface HelloRemote {

    String sayHi();

    
void init(String name);
    
    
void remove();
    
}

接著開發有狀態會話bean:
@Stateful
public class HelloBean implements HelloRemote {
    
private String name;
    
private Logger log = Logger.getLogger(this.getClass().getName());
    
    
public String sayHi() {
        
return "Hi " + name;
    }


    
public void init(String name) {
        
this.name = name;
    }

    
    @PostConstruct
    
public void postConstrut(){
        log.info(
"create " + this);
    }

    
    @PreDestroy
    
public void preDestory(){
        log.info(
"destory " + this);
    }

    
    @PostActivate
    
public void postActivate(){
        log.info(
"activate " + this);
    }

    
    @PrePassivate
    
public void prePassivate(){
        log.info(
"passivate " + this);
    }

    
    @Remove
    
public void remove(){
        log.info(
"remove " + this);
    }

}

@Stateful注釋表明這是一個有狀態會話bean,其他的注釋是管理會話bean的生命周期。@PostConstruct注釋表明方法將會在bean實例化并完成依賴注入后由容器調用此方法;@PreDestory注釋表示方法會在容器刪除bean實例前由容器調用;以上兩個注釋所有的EJB(包括MDB)都可以用。@PostActivate注釋表示容器在激活bean后調用此方法;@PrePassivate注釋表示容器在鈍化bean前調用此方法;以上兩個注釋是有狀態會話bean所特有。@Remove注釋也是有狀態會話bean所特有,也是用戶唯一可以能控制的生命周期方法,一旦用戶在客戶端調用此方法,容器將刪除bean實例。接著看客戶端的測試代碼:
<%
           InitialContext ctx 
= new InitialContext();
           HelloRemote helloBean 
= (HelloRemote)ctx.lookup(HelloRemote.class.getName());
           helloBean.init(
"Tom");
           out.println(helloBean.sayHi());
           helloBean.remove();
%>

很簡單,只是多調用了一個remove方法。

waynemao 2008-09-13 11:14 發表評論
]]>
EJB3 (6)http://www.aygfsteel.com/waynemao/archive/2008/09/13/228692.htmlwaynemaowaynemaoFri, 12 Sep 2008 20:36:00 GMThttp://www.aygfsteel.com/waynemao/archive/2008/09/13/228692.htmlhttp://www.aygfsteel.com/waynemao/comments/228692.htmlhttp://www.aygfsteel.com/waynemao/archive/2008/09/13/228692.html#Feedback0http://www.aygfsteel.com/waynemao/comments/commentRss/228692.htmlhttp://www.aygfsteel.com/waynemao/services/trackbacks/228692.htmlWeb服務客戶端可以通過bean的Web服務端點實現類來訪問無狀態會話Bean。在默認情況下,bean類中的所有公共方法對于Web服務客戶端都是可訪問的。@WebMethod注釋可以自定義Web服務方法,一旦在公共方法上使用該注釋,那么其他沒使用@WebMethod注釋的方法將不會對Web服務客戶端展現。
首先新建一個EJB模塊,然后在EJB模塊上新建一個WebService,代碼如下:

@WebService()
@Stateless()
public class Dog {
    
    @WebMethod(operationName 
= "ganr")
    
public String ganr() {
        
return "Wo-Wo-Wo";
    }


}

Dog類同時使用了@WebService和@Stateless注釋,web服務端點只能是無狀態會話bean,web服務本身就是無狀態的。我們還用@WebMethod注釋向Web服務客戶端公開了一個ganr方法,完成后打包部署。
接著我們創建一個Web模塊,然后在Web項目上右鍵,選新建--Web服務客戶端,指定項目或者WSDL url。接著新建一個Servlet,然后右鍵調用Web服務操作,我們找到Dog服務的garn方法點確定,代碼自動生成:
@WebServiceRef(wsdlLocation = "http://localhost:8080/DogService/Dog?wsdl")
    
private DogService service;

@WebServiceRef注釋聲明了一個到Web服務的引用
try // Call Web Service Operation

                ejb.Dog port 
= service.getDogPort();
                
// TODO process result here
                java.lang.String result = port.ganr();
                out.println(
"Result = " + result);
            }
 catch (Exception ex) {
                
// TODO handle custom exceptions here
            }

service.getDogPort()方法獲取到服務的一個代理,也稱為端口。接著看jsp:
  <%
    
try {
    ejb.DogService service 
= new ejb.DogService();
    ejb.Dog port 
= service.getDogPort();
    
// TODO process result here
    java.lang.String result = port.ganr();
    out.println(
"Result = "+result);
    }
 catch (Exception ex) {
    
// TODO handle custom exceptions here
    }

    
%>

發現只有一點點不同,完成后部署web應用并運行測試。

我們還可以通過一個現有的會話Bean創建Web服務,還是拿HelloWorld舉例,首先創建一個遠程接口:
@Remote
public interface HelloRemote {

    String sayHi(String name);
}

再創建一個無狀態會話bean,先已經說過了,只能是無狀態會話bean:
@Stateless
public class HelloBean implements HelloRemote {

    
public String sayHi(String name) {
        
return "Hi " + name; 
    }

}

然后新建一個Web服務Hello,只不過在彈出窗口中要選中“通過現有會話bean創建Web服務”單選框,并瀏覽指定HelloBean,代碼自動完成:
@WebService()
@Stateless()
public class Hello {
    @EJB
    
private HelloRemote ejbRef;
    
// Add business logic below. (Right-click in editor and choose
    
// "Web Service > Add Operation"

    @WebMethod(operationName 
= "sayHi")
    
public String sayHi(@WebParam(name = "name")String name) {
        
return ejbRef.sayHi(name);
    }

}

我們看到Hello服務里引用了一個HelloRemote接口,并發現遠程接口公開的方法也被Hello服務公開,完成后打包部署EJB模塊。接著在Web服務客戶端測試,這和之前的步驟一樣,不再贅述,直接看代碼吧:
@WebServiceRef(wsdlLocation = "http://localhost:8080/HelloService/Hello?wsdl")
    
private HelloService service;

    
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            
throws ServletException, IOException {
        response.setContentType(
"text/html;charset=UTF-8");
        PrintWriter out 
= response.getWriter();
        
try {
            
try // Call Web Service Operation

                ejb.Hello port 
= service.getHelloPort();
                
// TODO initialize WS operation arguments here
                java.lang.String name = "Tom";
                
// TODO process result here
                java.lang.String result = port.sayHi(name);
                out.println(
"Result = " + result);
            }
 catch (Exception ex) {
                
// TODO handle custom exceptions here
            }

 

<%
    
try {
    ejb.HelloService service 
= new ejb.HelloService();
    ejb.Hello port 
= service.getHelloPort();
     
// TODO initialize WS operation arguments here
    java.lang.String name = "Tom";
    
// TODO process result here
    java.lang.String result = port.sayHi(name);
    out.println(
"Result = "+result);
    }
 catch (Exception ex) {
    
// TODO handle custom exceptions here
    }

    
%>

發現一個問題,一個應用上不能新建兩個Web服務客戶端(Dog和Hello),只有一個能有效使用(只找到一份工件),這是為什么?

waynemao 2008-09-13 04:36 發表評論
]]>
WebService (1)http://www.aygfsteel.com/waynemao/archive/2008/09/13/228691.htmlwaynemaowaynemaoFri, 12 Sep 2008 18:31:00 GMThttp://www.aygfsteel.com/waynemao/archive/2008/09/13/228691.htmlhttp://www.aygfsteel.com/waynemao/comments/228691.htmlhttp://www.aygfsteel.com/waynemao/archive/2008/09/13/228691.html#Feedback0http://www.aygfsteel.com/waynemao/comments/commentRss/228691.htmlhttp://www.aygfsteel.com/waynemao/services/trackbacks/228691.html新建web項目,然后創建一個WEB服務:

@WebService()
public class Hello {
    @WebMethod(operationName 
= "sayHi")
    
public String sayHi(@WebParam(name = "name")String name) {
       
return "Hi " + name;
    }

}


可以在源圖上右鍵,選Web服務--添加操作,也可以在設計圖上直接添加操作。@WebService標注表明該類是一個web服務,展現給web服務客戶端的業務方法必須使用@WebMethod標注來表示。打包部署該web應用,web服務自動會發布。可以在glassfish應用服務器上找到該web服務,直接測試或者查看服務器生成的WSDL

<?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.3.1-hudson-417-SNAPSHOT. --><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.3.1-hudson-417-SNAPSHOT. -->
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://webservice/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://webservice/" name="HelloService">
    
<types>
        
<xsd:schema>
            
<xsd:import namespace="http://webservice/" schemaLocation="http://localhost:8080/WebServiceApp/HelloService?xsd=1">
            
</xsd:import>
        
</xsd:schema>
    
</types>
    
<message name="sayHi">
        
<part name="parameters" element="tns:sayHi">
        
</part>
    
</message>
    
<message name="sayHiResponse">
        
<part name="parameters" element="tns:sayHiResponse">
        
</part>
    
</message>
    
<portType name="Hello">
        
<operation name="sayHi">
            
<input message="tns:sayHi">
            
</input>
            
<output message="tns:sayHiResponse">
            
</output>
        
</operation>
    
</portType>
    
<binding name="HelloPortBinding" type="tns:Hello">
        
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document">
        
</soap:binding>
        
<operation name="sayHi">
            
<soap:operation soapAction="">
            
</soap:operation>
            
<input>
                
<soap:body use="literal">
                
</soap:body>
            
</input>
            
<output>
                
<soap:body use="literal">
                
</soap:body>
            
</output>
        
</operation>
    
</binding>
    
<service name="HelloService">
        
<port name="HelloPort" binding="tns:HelloPortBinding">
            
<soap:address location="http://localhost:8080/WebServiceApp/HelloService">
            
</soap:address>
        
</port>
    
</service>
</definitions>


也可以編寫客戶端測試,新建一個普通的java項目,在項目上右鍵,選擇新建--Web服務客戶端,在彈出窗口中指定WebService項目或者WSDL url,點擊完成。在源代碼上右鍵,選擇Web服務客戶端資源--調用Web服務操作,在彈出窗口中選擇sayHi操作,點確定,測試代碼自動生成:

public class Main {

    
public static void main(String[] args) {

        
try 

            webservice.HelloService service 
= new webservice.HelloService();
            webservice.Hello port 
= service.getHelloPort();
            
            java.lang.String name 
= "Tom";
            java.lang.String result 
= port.sayHi(name);
            System.out.println(
"Result = " + result);
        }
 catch (Exception ex) {
            
// TODO handle custom exceptions here
        }

    }

}

運行該客戶端,結果將會輸出

waynemao 2008-09-13 02:31 發表評論
]]>
EJB3 - Session beanhttp://www.aygfsteel.com/waynemao/archive/2008/09/12/228674.htmlwaynemaowaynemaoFri, 12 Sep 2008 15:19:00 GMThttp://www.aygfsteel.com/waynemao/archive/2008/09/12/228674.htmlEJB3 - Session bean

description

其實session bean是最一開始就看的, 回過頭來看再記重點有點心浮氣躁.

reference

EJB3 in Action - CH3 - Building business logic with session beans

Focal Points

  • session bean一定要有一個以上的interface與一個實現
  • 一個session bean可以有多個interface, 所以當客戶端調用一個@Local的interface, 就是使用local的session bean. 使用@Remote或@WebService就是用remote或web service的session bean.
  • session bean一定要是concrete class, 一定要有無參構造函數, 不能是abstract或final.
  • session bean可以是其他session bean或POJO的subclass.
  • session bean的business method與lifecycle callback可定在super class或session bean class裡.
  • session bean的annotation的繼承是有條件的, 就是class level比方說@Stateless, @Stateful會被忽略, 不過lifecycle callback會被繼承下來.
  • session bean的business method name不能以ejb開頭, 比方說不能是ejbDoit()
  • session bean的method必須是public且不能是static或final
  • 使用一個remote business interface要注意argument與return type必須實作Serizable
  • 所有session bean都有的生命週期是creation / destruction
  • stateful bean比stateless bean又多了passivation / activation
  • stateless bean的lifecycle callback為@PostConstruct, @PreDestroy
  • stateful bean的lifecycle callback為@PostConstruct, @PreDestroy, @PostActivate, @PrePassivate
  • @PostConstruct, @PreDestroy比較簡單.就是container實例化session bean後調用@PostContruct, container移除session bean前會調用@PreDestroy
  • @PostActivate, @PrePassivate比較特別.  一旦container判斷一個stateful bean停用了而決定要暫時讓這個session bean失去效用, 這個動作叫鈍化. 而container讓已經失效的stateful bean再度生效就叫激活. 所以@PostActivate就是activation後調用的method, @PrePassivate就是鈍化前呼叫的method.
  • lifecycle callback可以是public, private, protected, package-protected
  • lifecycle callback主要用來替session bean準備實例化後需要的資源以及從container移除前要釋放的資源.
  • lifecycle callback除了放在session bean以外也可放在分開的interceptor class
  • stateless session bean有pool, 也就是說有一定數量的stateless session bean在container的pool中
  • @Stateless的定義
    1. 屬性有name, mappedName, description
    2. name屬性用來指定bean的name, 有的container用來和JNDI綁定. 如果name沒有設定就會是bean的class name.
    3. mappedName是vender-specific(特定于廠商), 也就是依不同container有不同的情形. 以GlassFish來說是將mappedName的值綁定到JNDI name.
  • @Local: stateless session bean的local interface, local interface表示這個session bean和client放在同一個JVM上執行.
  • @Remote: 當client存在於container外的JVM時就必須使用@Remote
    1. 一個@Remote interface可以繼承java.rmi.Remote
       public interface TestRemote extends Remote { ... } 
      就算程序裡面沒寫繼承Remote, container還是會在byte code階段插入繼承Remote的動作
    2. 沒有程序上繼承java.rmi.Remote的好處就是不用處理java.rmi.RemoteException
    3. @Remote business interface有個需求就是所有的參數與回傳值都必須是Serializable, 因為這樣才能通過RMI
  • @WebService: 透過@WebService可讓session bean成為SOAP-based web service. 唯一要做的就是在interface上加上@WebService.
  • 不能讓一個business interface同時@Local又@Remote或是又@WebService, 不過可以透過interface的繼承改變要使用的是@Remote session bean還是@Local的 session bean.
  • 放session bean的lifecycle callback
  • 可以有多個@PostConstruct, @PreDestroy (不過我試起來一個session bean就只能一個lifecycle callback有效, 頂多除了callback以外還指定interceptor, 就加上interceptor的一個lifecycle callback有效.)
  • lifecycle callback要符合pattern: void < METHOD >()
  • interceptor內的lifecycle callback要符合pattern: Object < METHOD >(InvocationContext) throws Exception, 然後記得回傳InvocationContext.proceed, 除非打算不繼續執行. (可參考EJB3 Interceptor)
  • session bean的lifecycle callback不可有checked exception, interceptor的則可以.
  • session bean的lifecycle callback不可有傳入參數, interceptor則要傳入InvocationContext, 否則有java.lang.IllegalArgumentException: wrong number of arguments
  • stateless session bean與stateful session bean的差別主要在於container管理的方式, stateless session bean起始之後會被container放進pool, 等client要使用的時候再從pool取出, 用完再放回pool. stateful session bean則是讓一個client擁有一個stateful session bean直到client離開或stateful session bean destroy為止. stateful session bean與client是one to one的關係.
  • stateful session bean需要付出代價, stateless session bean由於所有client共用session bean比較能節省資源, stateful session bean則因為與client是one to one的關係所以比較耗資源. 一旦container判斷消耗資源太多或佔用資源太久就會開始執行passivate的動作.
  • 由於stateful session bean比較耗資源, 所以注意要在stateful session bean加上@Remove method, 當呼叫此method, container就會負責將此method destroy以節省資源.
  • 由於stateful session bean在passivate的時候會做serialize的動作, 所以注意stateful session bean的class 成員必須實做Serializable或必須是原始類型. 否則在passivate的時候會出現例如[NRU-stateful.SimpleStatefulBean]: passivateEJB(), Exception caught 的exception, 就是因為無法serialize該object的關係. 如果要使用不須serialize的class 成員只要用transient聲明該class member或在@PrePassivate把class member改成null再於@PostActivate設定回來即可.
  • 使用stateful session bean的方式幾乎和stateless session bean的方式幾乎一樣, 唯一不一樣的是stateful session bean的business interface只能使用@Local與@Remote而不能用@WebService. 因為SOAP-based web Service本來就不是stateful因此無法使用.
  • stateful session bean的生命週期中有重要的一點就是container在destroy一個passivate的時候會先將該stateful session bean先activate再passivate.
    @Stateful(name="SimpleStatefulBean", mappedName="ejb/SimpleStatefulBean")
    public class SimpleStatefulBean implements SimpleStatefulRemote {
    private Logger logger = Logger.getLogger("SimpleStatefulBean");
    private byte[] b = new byte[100000];
    {
    for ( int i = 0; i < b.length; i++ ) {
    b[i] = (byte) 100;
    }
    }
    public String simpleShow() {
    return this + ":This is simple show" + b;
    }
    @PostConstruct
    public void postConstruct() {
    logger.info("create " + this);
    }
    @PreDestroy
    public void preDestroy() {
    logger.info("destroy " + this);
    }
    @PostActivate
    public void postActivate() {
    logger.info("activate " + this);
    }
    @PrePassivate
    public void prePassivate() {
    logger.info("passivate " + this);
    }
    @Remove
    public void remove() {
    logger.info("remove " + this);
    }
    }
    
    放interceptor的lifecycle callback
    @Stateless
    @Interceptors(value={SimpleInterceptor.class})
    public class SimpleStatelessBean implements SimpleStatelessLocal {
    private Logger logger = Logger.getLogger("SimpleStatelessBean");
    @Resource(name="TestQueueConnectionFactory")
    private ConnectionFactory connectionFactory;
    @Resource(name="jms/TestQueueDestination")
    private Destination destination;
    public String simpleShow() {
    try {
    Connection conn = connectionFactory.createConnection();
    Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    MessageProducer messageProducer = session.createProducer(destination);
    TextMessage message = session.createTextMessage();
    message.setText("This is text message");
    messageProducer.send(message);
    messageProducer.close();
    session.close();
    conn.close();
    } catch (JMSException ex) {
    throw new RuntimeException( ex );
    }
    return this + ":This is simple show";
    }
    }
    public class SimpleInterceptor {
    Logger logger = Logger.getLogger("SimpleStatefulBeanInterceptor");
    @PostConstruct
    public void onCreate(InvocationContext ic) {
    try {
    logger.info("create " + this);
    ic.proceed();
    } catch (Exception ex) {
    Logger.getLogger(SimpleInterceptor.class.getName()).log(Level.SEVERE, null, ex);
    }
    }
    @AroundInvoke
    public Object aroundInvoke(InvocationContext ctx) throws Exception {
    logger.info(ctx + " is invoked.");
    return ctx.proceed();
    }
    @PreDestroy
    public void onDestroy(InvocationContext ic) {
    try {
    logger.info("destroy " + this);
    ic.proceed();
    } catch (Exception ex) {
    Logger.getLogger(SimpleInterceptor.class.getName()).log(Level.SEVERE, null, ex);
    }
    }
    }
    
    stateful bean的@PrePassivate, @PostActivate也可放interceptor
    @Interceptors(value={SimpleInterceptor.class})
    @Stateful(name="SimpleStatefulBean", mappedName="ejb/SimpleStatefulBean") public class SimpleStatefulBean implements SimpleStatefulRemote { private byte[] b = new byte[100000]; { for ( int i = 0; i < b.length; i++ ) { b[i] = (byte) 100; } } public String simpleShow() { return this + ":This is simple show" + b; } @Remove public void remove() { Logger.getLogger("SimpleStatefulBean").info("remove " + this); } } public class SimpleInterceptor { @PostConstruct public void onCreate(InvocationContext ic) { try { Logger.getLogger(SimpleInterceptor.class.getName()).info("create " + this); ic.proceed(); } catch (Exception ex) { Logger.getLogger(SimpleInterceptor.class.getName()).log(Level.SEVERE, null, ex); } } @PostActivate public void onActivate(InvocationContext ic) { try { Logger.getLogger(SimpleInterceptor.class.getName()).info("activate " + this); ic.proceed(); } catch (Exception ex) { Logger.getLogger(SimpleInterceptor.class.getName()).log(Level.SEVERE, null, ex); } } @PrePassivate public void onPassivate(InvocationContext ic) { try { Logger.getLogger(SimpleInterceptor.class.getName()).info("passivate " + this); ic.proceed(); } catch (Exception ex) { Logger.getLogger(SimpleInterceptor.class.getName()).log(Level.SEVERE, null, ex); } } @AroundInvoke public Object aroundInvoke(InvocationContext ctx) throws Exception { Logger.getLogger(SimpleInterceptor.class.getName()).info(ctx + " is invoked."); return ctx.proceed(); } @PreDestroy public void onDestroy(InvocationContext ic) { try { Logger.getLogger(SimpleInterceptor.class.getName()).info("destroy " + this); ic.proceed(); } catch (Exception ex) { Logger.getLogger(SimpleInterceptor.class.getName()).log(Level.SEVERE, null, ex); } } }
  • @EJB用來注入session bean到client code. @EJB有幾個屬性: name, beanInterface, beanName. name用來指定JNDI name, beanName則是當一個interface有兩個實作時用來決定要注入哪個實作.
  • 使用@EJB注入的時候如果沒有指定JNDI name, container就會用interface name當成JNDI name注入.
  • 如果要注入同個interface不同的實作可透過指定JNDI name或beanName
    @Stateless(name="SimpleStatelessBean1")
    public class SimpleStatelessBean1 implements SimpleStatelessLocal { ... }
    @Stateless(name="SimpleStatelessBean2")
    public class SimpleStatelessBean2 implements SimpleStatelessLocal { ... }
    public class SimpleStatelessServlet extends HttpServlet {
    @EJB(beanName="SimpleStatelessBean1")
    private SimpleStatelessLocal simpleStatelessLocal1;
    @EJB(beanName="SimpleStatelessBean2")
    private SimpleStatelessLocal simpleStatelessLocal2;
    ...
    }
    
  • 可注入stateless bean或stateful bean到其他的stateful bean. 但不能注入stateful bean到stateless bean, 因為這樣stateful session bean就會被所有client分享.
  • 注入stateful bean到另一個stateful bean時, 一旦持有注入的stateful bean destroy了, 被持有的stateful bean也會一起destroy.
  • 如果不用stateful bean可將狀態放在DB中或放在server side的檔案或放HttpSession, 不過要注意清除不必要的資源.
  • 儲存conversation state的時候要注意儲存的值愈小愈好, 例如primitive.
  • stateful bean要記得定義@Remove method.
  • 調整server到stateful bean效能最佳的狀態, 小心頻繁的passivate / activate造成效能變差太多.


  • waynemao 2008-09-12 23:19 發表評論
    ]]>
    EJB3 (3)http://www.aygfsteel.com/waynemao/archive/2008/09/12/228669.htmlwaynemaowaynemaoFri, 12 Sep 2008 14:24:00 GMThttp://www.aygfsteel.com/waynemao/archive/2008/09/12/228669.htmlhttp://www.aygfsteel.com/waynemao/comments/228669.htmlhttp://www.aygfsteel.com/waynemao/archive/2008/09/12/228669.html#Feedback0http://www.aygfsteel.com/waynemao/comments/commentRss/228669.htmlhttp://www.aygfsteel.com/waynemao/services/trackbacks/228669.html
    @Local
    public interface MessageLocal {

        String getMessage();
        
    }

    接著編寫一個會話bean實現該接口:
    @Stateless
    public class MessageBean implements MessageLocal {

        
    public String getMessage() {
            
    return "Hello world";
        }

        
    }

    然后創建一個遠程接口:

    @Remote
    public interface HelloRemote {

        String welcome();
        
    }

    編寫一個會話bean實現該接口:
    @Stateless
    public class HelloBean implements HelloRemote {
        @EJB
        
    private MessageLocal messageBean;

        
    public String welcome() {
            
    return messageBean.getMessage();
        }

        
    }

    在遠程對象里聲明了一個本地接口的引用,并嘗試在遠程方法當中調用本地接口的本地方法。這些都沒問題,打包部署成功。
    <%
                InitialContext ctx 
    = new InitialContext();
                HelloRemote helloBean 
    = (HelloRemote)ctx.lookup(HelloRemote.class.getName());
                out.println(helloBean.welcome());
    %>

    在遠程客戶端的代碼如此,看起來一切正常,不過在部署WEB模塊的時候報異常:正在域中部署應用程序 失敗;為模塊 [EjbWebClient] 裝入部署描述符時出錯 -- Cannot resolve reference Unresolved Ejb-Ref ejb.HelloBean/messageBean@jndi: @null@ejb.MessageLocal@Session@null


    waynemao 2008-09-12 22:24 發表評論
    ]]>
    EJB3 (2)http://www.aygfsteel.com/waynemao/archive/2008/09/12/228658.htmlwaynemaowaynemaoFri, 12 Sep 2008 13:29:00 GMThttp://www.aygfsteel.com/waynemao/archive/2008/09/12/228658.htmlhttp://www.aygfsteel.com/waynemao/comments/228658.htmlhttp://www.aygfsteel.com/waynemao/archive/2008/09/12/228658.html#Feedback0http://www.aygfsteel.com/waynemao/comments/commentRss/228658.htmlhttp://www.aygfsteel.com/waynemao/services/trackbacks/228658.html一個會話bean即可以遠程訪問,也可以本地訪問,盡管這種現象不常見。
    我們先定義遠程接口:

    @Remote
    public interface HelloRemote {

        String sayHi(String name);

        String sayByeBye(String name);
        
    }

    接著定義本地接口:
    @Local
    public interface HelloLocal {

        String sayBye(String name);
        
    }

    然后編寫一個會話bean同時實現兩個接口:
    @Stateless
    public class HelloBean implements HelloRemote, HelloLocal {

        
    public String sayHi(String name) {
            
    return "Hi " + name;
        }

        
        
    public String sayBye(String name) {
            
    return "Bye " + name;
        }

        
        
    public String sayByeBye(String name) {
            
    return sayBye(name);
        }

        
    }

    那么,這還是一個無狀態會話bean,不過即可以遠程訪問,也可以本地訪問。
    <%
                InitialContext ctx 
    = new InitialContext();
                HelloRemote helloBean 
    = (HelloRemote)ctx.lookup(HelloRemote.class.getName());
                out.println(helloBean.sayHi(
    "Tom"));
                out.println(
    "<br>" + helloBean.sayByeBye("Tom"));
    %>

    遠程訪問只能獲得遠程接口的代理,然后調用遠程業務方法。在遠程客戶端是無法獲得本地接口的引用,更別說訪問本地方法了。

    waynemao 2008-09-12 21:29 發表評論
    ]]>
    EJB3 (1)http://www.aygfsteel.com/waynemao/archive/2008/09/12/228653.htmlwaynemaowaynemaoFri, 12 Sep 2008 12:49:00 GMThttp://www.aygfsteel.com/waynemao/archive/2008/09/12/228653.htmlhttp://www.aygfsteel.com/waynemao/comments/228653.htmlhttp://www.aygfsteel.com/waynemao/archive/2008/09/12/228653.html#Feedback0http://www.aygfsteel.com/waynemao/comments/commentRss/228653.htmlhttp://www.aygfsteel.com/waynemao/services/trackbacks/228653.html新建一個EJB模塊
    先寫一個最簡單的無狀態Session Bean,首先定義一個遠程接口:

    @Remote
    public interface HelloRemote {

        String sayHi(String name);
        
    }
    用@Remote標注表明這是一個遠程接口,在接口里聲明一些業務方法。接著定義一個會話Bean實現該接口:
    @Stateless
    public class HelloBean implements HelloRemote {

        
    public String sayHi(String name) {
            
    return "Hi " + name;
        }

        
    }

    @Stateless標注表明這是一個無狀態會話Bean,完成了這個簡單的Demo后,打包部署到服務器上。接著我們來測試這個會話Bean,新建一個WEB模塊,我們利用這個web應用來遠程調用會話Bean。我們可以在web模塊里新建一個Servlet:
    public class HelloServlet extends HttpServlet {
        @EJB
        
    private HelloRemote helloBean;
    在Servlet里定義了一個成員變量,@EJB標注表明遠程接口的代理將依賴注入到成員變量,在doGet或doPost方法里可以直接使用該代理調用會話Bean的業務方法:
    PrintWriter out = response.getWriter();
            
    try {
               out.println(helloBean.sayHi(
    "Tom"));
            }
     finally 
                out.close();
            }
    JSP卻有所不同,這里不能使用@EJB標注,要使用傳統的JNDI lookup方式:
    <%
                InitialContext ctx 
    = new InitialContext();
                HelloRemote helloBean 
    = (HelloRemote)ctx.lookup(HelloRemote.class.getName());
                out.println(helloBean.sayHi(
    "Tom"));
    %>

    這個測試用web模塊已經完成,將WEB模塊打包部署后即可以運行
    不過,如果我們自己指定了會話Bean的JNDI名,那么以上的測試代碼將發生異常,例如:
    @Stateless(mappedName="hello")
    public class HelloBean implements HelloRemote {

        
    public String sayHi(String name) {
            
    return "Hi " + name;
        }

        
    }

    這里我們指定了會話bean的JNDI名為"hello",更改后的EJB模塊需要重新部署,還要更改相應的Servlet和Jsp中的代碼:
    @EJB(mappedName="hello")
        
    private HelloRemote helloBean;

    Servlet已經更改了,只有一點點不同。
    <%
                InitialContext ctx 
    = new InitialContext();
                HelloRemote helloBean 
    = (HelloRemote)ctx.lookup("hello");
                out.println(helloBean.sayHi(
    "Tom"));
            
    %>

    Jsp也做了小小的改動,如此更新后重新部署WEB模塊,測試代碼即可順利運行

    waynemao 2008-09-12 20:49 發表評論
    ]]>
    主站蜘蛛池模板: 邓州市| 嘉荫县| 平泉县| 咸丰县| 靖远县| 大厂| 江华| 舞阳县| 安西县| 梅河口市| 永善县| 永安市| 望江县| 黄平县| 台东县| 历史| 仪征市| 临沂市| 五莲县| 礼泉县| 开远市| 合山市| 盐边县| 息烽县| 黔江区| 泰兴市| 棋牌| 长白| 汕尾市| 桦甸市| 麦盖提县| 泰兴市| 浪卡子县| 广水市| 陵川县| 定结县| 沈阳市| 临湘市| 惠水县| 鄂伦春自治旗| 安福县|