2010年10月15日 星期五

[JAX-WS]解決 WebService 只會產生一個實體的問題

一般來說,一個 WebService 只會產生一個實體來服務所有 Client 的請求

例如
package com.blogspot.karrysu;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService
public class MyWS {
 private int i = 0;
 @WebMethod
 public void testInstanceMember(){
  this.i = this.i + 1;
  System.out.println("this.i="+i);
 }
}
這個例子是每次呼叫 testInstanceMember(),就會將 i 這個 instance member 加一
所以,若是多個 instance,則每個 instance 的 i 都會是從 0 開始

接著我們試著用下面的 Client code 呼叫
MyWSService service = new MyWSService(
  new URL("http://localhost:8080/WebServices/services/myws?wsdl")
  ,new QName("http://karrysu.blogspot.com/", "MyWSService")
 );
MyWS port1 = service.getMyWSPort();

port1.testInstanceMember();
port1.testInstanceMember();

MyWS port2 = service.getMyWSPort();

port2.testInstanceMember();
port2.testInstanceMember();
如果每次在 Client 端產生 MyWS 實體,也都能在 Server 端產生一個對應的 MyWS 實體
那麼當我們執行上面的 Client code 時,理應在 Server console 會看到
this.i=1
this.i=2
this.i=1
this.i=2
但我們看到的結果是
this.i=1
this.i=2
this.i=3
this.i=4
這就表示 Server 端實際上只有產生一個 MyWS 實體

如果我們希望每次在 Client 端產生 MyWS 實體時,Server 端也都能產生一個對應的 MyWS 實體
那麼,我們在 MyWS 就要加上 @HttpSessionScope,如下
package com.blogspot.karrysu;

import javax.jws.WebMethod;
import javax.jws.WebService;

import com.sun.xml.ws.developer.servlet.HttpSessionScope;

@HttpSessionScope
@WebService
public class MyWS {
 private int i = 0;
 @WebMethod
 public void testInstanceMember(){
  this.i = this.i + 1;
  System.out.println("this.i="+i);
 }
 @WebMethod
 public TestVO test(TestVO vo){
  if( vo==null ) return null;
  vo.setStrValue("Modified by Server side.");
  return vo;
 }
}
且 Client code 在呼叫時,必須多執行一句
((BindingProvider)port).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY,true);
如下
MyWSService service = new MyWSService(
  new URL("http://localhost:8080/WebServices/services/myws?wsdl")
  ,new QName("http://karrysu.blogspot.com/", "MyWSService")
 );
MyWS port1 = service.getMyWSPort();
((BindingProvider)port1).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY,true);

port1.testInstanceMember();
port1.testInstanceMember();

MyWS port2 = service.getMyWSPort();
((BindingProvider)port2).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY,true);

port2.testInstanceMember();
port2.testInstanceMember();
如此就能得到我們想要的結果
this.i=1
this.i=2
this.i=1
this.i=2
這裡要注意的是,如果 Client code 沒有寫這一行
((BindingProvider)port).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY,true);
那麼就會變成每呼叫一次 method 就會產生一個 MyWS 實體,執行結果是
this.i=1
this.i=1
this.i=1
this.i=1

參考資料
https://jax-ws-commons.dev.java.net/http-session-scope/

相關文章:
[JAX-WS]簡單實作 WebService

沒有留言:

張貼留言

廣告訊息會被我刪除