2009-09-17 33 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

相关问题