2009-09-17 31 views
5

Ho un servizio Web stateful distribuito su Tomcat. Consiste del servizio di fabbrica e del principale servizio API e funziona perfettamente. Il servizio Factory restituisce un W3CEndpointReference all'istanza API principale e il client utilizza la sessione.JAX-WS: WS stato WS non riuscito in un processo standalone

Ora, sto cercando di eseguire lo stesso servizio di un'applicazione standalone. In questo caso, il W3CEndpointReference restituito dalla fabbrica inizia improvvisamente a puntare all'URI di fabbrica, non a quello di servizio principale.

Quando vengono confrontati i riferimenti da corse a Tomcat e standalone, diventa chiaro che il riferimento autonomo ha un URI errato. In particolare, punta all'URI di fabbrica, non all'API principale.

Ecco riferimento corretto:

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

Ecco i riferimenti quando fabbrica è chiamato processo autonomo:

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

mia comprensione che qualche codice sotto contesto servlet ha una conoscenza di corrispondenza tra classe di servizio (Td2Ws) ed è URI, e regola i riferimenti di conseguenza. Tuttavia, quel pezzo di codice non è in vigore sotto processo autonomo. Posso anche sospettare che il codice usi sun-jaxws.xml, ma non so come "accenderlo".

Come è possibile eseguire il servizio Web di stato in applicazioni standalone?

Qui sono parti rilevanti del codice:

servizio di fabbrica (stateless):

@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:

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

Codice cliente (mirata a standalone):

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..."); 

Quel codice non è riuscito login() come l'oggetto di destinazione non ha alcuna operazione di login (è a torto mirato alla fabbrica URI, dopo tutto):

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

risposta

0

non ho fatto questo in un po ', ma ho preso uno sguardo in un servizio web statico funzionale che ho costruito qualche tempo fa. Le mie annotazioni sono molto simili ai tuoi, tranne ho questo in cima alla mia classe:

public class MyService { 

    @Resource 
    WebServiceContext wsCtx; 

    ... 

} 

Avviso non v'è alcun modificatore, se niente altro penso che deve essere pubblica, ma non sono positivi. Il modo in cui il contenitore sa impostare questo mi batte, ma funziona. Deve solo cercare qualsiasi @Resource di tipo WebServiceContext e impostarlo. È possibile accedere alle informazioni sulla sessione in questo modo:

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

Session s = hRequest.getSession(); 
+0

Il servizio in questione è autonomo, ovvero non è in esecuzione all'interno di un contenitore Servlet. –