2009-09-17 71 views
5

我有一個部署到Tomcat上的有狀態Web服務。它由工廠服務和主要API服務組成,工作得很好。工廠服務將W3CEndpointReference返回給主API實例,並且客戶端使用該會話。JAX-WS:有狀態WS在獨立進程中失敗

現在,我試圖運行與獨立應用程序非常相同的服務。在這種情況下,工廠返回的W3CEndpointReference突然開始指向工廠URI,而不是主要服務。

當比較針對Tomcat和獨立版的運行引用時,很明顯獨立引用具有錯誤的URI。具體來說,它指向工廠的URI,而不是主要的API。

這裏是正確的參考:

... 
<ns3:Address>http://localhost:8080/td2ws/api</ns3:Address> 
... 

這裏的引用時,工廠被稱爲在獨立的過程:

<Address>http://localhost:9009/td2ws/factory</Address> 

我的理解是,在servlet上下文的一些代碼有服務類之間的對應關係的知識(Td2Ws ),它是URI,並相應地調整引用。儘管如此,這段代碼在單獨的過程中不起作用。我甚至可以懷疑代碼使用sun-jaxws.xml,但我不知道如何「打開它」。

如何使獨立應用程序中的有狀態Web服務工作?

這裏是代碼的相關部分:

工廠服務(無狀態):

@WebService(targetNamespace="http://server.td2ws.sf.net/") 
public class Td2WsFactory { 
    @WebMethod(operationName="StartSession", action="urn:StartSession") 
    @WebResult(name="Reference") 
    public W3CEndpointReference startSession() { 
     StatefulWebServiceManager<Td2Ws> manager = Td2Ws.getManager(); 

     // for standalone execution only 
     if(manager == null) { 
      manager = new StatefulInstanceResolver<Td2Ws>(Td2Ws.class); 
      Td2Ws.setManager(manager); 
     } 

     Td2Ws session = new Td2Ws(); 
     return manager.export(W3CEndpointReference.class,session); 
    } 
} 

有狀態API:

@Stateful 
@WebService(targetNamespace="http://server.td2ws.sf.net/") 
@Addressing 
public class Td2Ws { 
    private static StatefulWebServiceManager<Td2Ws> manager; 

    public static void setManager(StatefulWebServiceManager<Td2Ws> manager) { 
     Td2Ws.manager = manager; 
    } 

    public static StatefulWebServiceManager<Td2Ws> getManager() { 
     return Td2Ws.manager; 
    } 

    @WebMethod(operationName="Login", action="urn:Login") 
    public void login(
      @WebParam(name="Username") String username, 
      @WebParam(name="Password") String password, 
      @WebParam(name="Domain") String domain, 
      @WebParam(name="Project") String project 
      ) throws Td2WsException { 

客戶端代碼(針對單機):

public static void main(String[] args) throws Exception { 
    Endpoint epf = Endpoint.publish("http://localhost:9009/td2ws/factory", new net.sf.td2ws.server.Td2WsFactory()); 
    Endpoint eps = Endpoint.publish("http://localhost:9009/td2ws/api", new net.sf.td2ws.server.Td2Ws()); 

    URL factoryUrl = new URL("http://localhost:9009/td2ws/factory?wsdl"); 
    QName factoryQname = new QName("http://server.td2ws.sf.net/", "Td2WsFactoryService"); 

    URL sessionUrl = new URL("http://localhost:9009/td2ws/api?wsdl"); 
    QName sessionQname = new QName("http://server.td2ws.sf.net/", "Td2WsService"); 

    Td2WsFactory factory = new Td2WsFactoryService(factoryUrl,factoryQname).getTd2WsFactoryPort(); 
    System.out.println("factory: "+factory); 

    W3CEndpointReference session = factory.startSession(); 
    System.out.println("session: "+session); 

    Td2WsService service = new Td2WsService(sessionUrl,sessionQname); 
    System.out.println("service: "+service); 

    Td2Ws port = service.getPort(session,Td2Ws.class); 
    System.out.println("port: "+port); 

    port.login(
      Config.get("td.user"), 
      Config.get("td.pass"), 
      Config.get("td.domain"), 
      Config.get("td.project")); 
    System.out.println("logged in..."); 

該代碼在登錄失敗()作爲目標對象沒有登錄操作(它錯誤地定位到工廠URI,畢竟):

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: 
Cannot find dispatch method for {http://server.td2ws.sf.net/}Login 

回答

0

我還沒有在一段時間這樣做,但我接過來一看在我之前建立的功能有狀態的Web服務中。我的註釋是你的差不多,但我有這個在我的類的頂部:

public class MyService { 

    @Resource 
    WebServiceContext wsCtx; 

    ... 

} 

公告不存在修改,如果什麼事我認爲它需要是公開的,但我還不能肯定。容器如何知道如何設置這個節拍,但它有效。它必須尋找任何類型的WebServiceContext的@Resource並設置它。你可以像這樣訪問會話信息:

HttpServletRequest hRequest = (HttpServletRequest)ctx.getMessageContext().get(MessageContext.SERVLET_REQUEST); 

Session s = hRequest.getSession(); 
+0

有問題的服務是獨立的,即不在Servlet容器內運行。 – 2013-01-31 01:57:29

相關問題