2009-09-17 22 views
5

Mam stanową usługę internetową wdrożoną na serwerze Tomcat. Składa się z usługi fabrycznej i głównej usługi API i działa dobrze. Usługa Factory zwraca W3CEndpointReference do głównej instancji API, a klient korzysta z sesji.JAX-WS: stanowe WS kończy się niepowodzeniem w procesie autonomicznym

Teraz próbuję uruchomić tę samą usługę, co samodzielna aplikacja. W tym przypadku W3CEndpointReference zwrócony przez fabrykę nagle zaczyna wskazywać na fabryczny URI, a nie na główny serwis.

W przypadku porównywania odniesień z Tomcat i wersji samodzielnej staje się jasne, że samodzielny odnośnik ma nieprawidłowy identyfikator URI. W szczególności wskazuje na URI fabryczny, a nie główny interfejs API.

Oto prawidłowe odniesienie:

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

Oto, referencje, kiedy fabryka nazywa się na samodzielny procesu:

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

Moje zrozumienie, że niektóre kodu na podstawie kontekstu serwletu posiada wiedzę z zakresu korespondencji pomiędzy klasy usług (Td2Ws) i jego URI, i odpowiednio dostosowuje odnośniki. Ten fragment kodu nie działa jednak w ramach samodzielnego procesu. Mogę nawet podejrzewać, że kod używa sun-jaxws.xml, ale nie wiem jak go "włączyć".

Jak mogę utworzyć usługę sieciową w stanie autonomicznym w samodzielnej pracy aplikacji?

Oto stosowne fragmenty kodu:

usług Factory (bezpaństwowiec):

@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); 
    } 
} 

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

kod klienta (skierowane do samodzielnych):

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

Ten kod nie działa na login() jako obiekt docelowy ma operację logowania (to błędnie skierowane do fabrycznego URI, mimo wszystko):

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

Odpowiedz

0

nie robiłem to na jakiś czas, ale przyjrzał w funkcjonalną, stanową usługę sieciową, którą zbudowałem jakiś czas temu. Moi Adnotacje są bardzo podobne do Ciebie, chyba mam to na szczycie mojej klasy:

public class MyService { 

    @Resource 
    WebServiceContext wsCtx; 

    ... 

} 

Wskazówka nie ma modyfikator, czy cokolwiek innego, myślę, że musi być publiczne, ale nie jestem pozytywne. Jak pojemnik wie, że to ustawia, bije mnie, ale działa. Musi po prostu wyszukać dowolny @Resource typu WebServiceContext i ustawić go. Dostęp do informacji o sesji można uzyskać w następujący sposób:

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

Session s = hRequest.getSession(); 
+0

Usługa jest samodzielna, tzn. Nie działa w kontenerze z serwletem. –