JAX-WS和Embedded Jetty - 在提供的HttpContext

时间:2016-05-03 15:59:51

标签: java web-services soap jetty jax-ws

我们有一个发布/订阅WS应用程序,我们希望将现有Oracle的Java HTTP Server实现替换为嵌入式Jetty实现。不幸的是,当我们尝试使用Endpoint.publish(HttpContext)调用发布Web服务时,我们遇到了一些麻烦。作为附加信息,我们被迫使用此调用,我们不能使用Endpoint.publish(地址)。

我刚刚创建了一个测试应用程序,以便隔离问题并征求您的意见。

请在下面找到TestService类:

public class TestService {

public static void main(String[] args) throws IOException {

    int port = 8081;
    String path = "/myservice";
    AsyncProvider<Source> internalProvider = new InternalProvider();
    Endpoint endpoint = Endpoint.create(internalProvider);

   // Preparing the Service
    URL wsdlLocation = TestService.class.getResource("NotificationService.wsdl");
    Source source = null;
    try {
        source = new StreamSource(wsdlLocation.openStream());
    } catch (IOException ex) {
        Logger.getLogger(TestService.class.getName()).log(Level.SEVERE, "Couldn't open WSDL", ex);
    }
    source.setSystemId(wsdlLocation.toExternalForm());
    List<Source> metadata = new ArrayList<Source>();
    metadata.add(source);
    endpoint.setMetadata(metadata);
    QName serviceName = new QName("http://notification/", "ConsumerService");
    QName portName = new QName("http://notification/", "ConsumerPort");
    Map<String, Object> map = new HashMap<String, Object>();
    map.put(Endpoint.WSDL_SERVICE, serviceName);
    map.put(Endpoint.WSDL_PORT, portName);
    endpoint.setProperties(map);

    // This is the fragment of code that is replacing Oracle’s HTTP Server with Jetty
    Server s = new Server(new InetSocketAddress("localhost", port));
    ServerConnector connector = new ServerConnector(s);
    connector.setReuseAddress(true);
    connector.setPort(port);
    s.setConnectors(new Connector[] {connector});
    s.setHandler(new ContextHandlerCollection());
    JettyHttpServer httpServer = new JettyHttpServer(s, false);
    JettyHttpContext context = (JettyHttpContext) httpServer.createContext(path); // It’s seems that is not taking into account the path
    endpoint.publish(context);        
    httpServer.start();

    W3CEndpointReference providerEPR = (W3CEndpointReference)endpoint.getEndpointReference(); // Throws a NullPointerException when calling HttpEndpoint.getEPRAddress()
    System.out.println("providerEPR: " + providerEPR);  

}

@WebServiceProvider
@ServiceMode(value = javax.xml.ws.Service.Mode.PAYLOAD)
private final static class InternalProvider implements AsyncProvider<Source>{

    @Override
    public void invoke(Source t, AsyncProviderCallback<Source> apc, WebServiceContext wsc) {
        processCall(t, apc, wsc);
    }

    private void processCall(Source t, AsyncProviderCallback<Source> apc, WebServiceContext wsc) {
        // Process the Request and generate a reply
         …

    }

}

此处附上消费者客户:

public class ConsumerClient {

public static void main(String[] args) throws Exception {

    Dispatch<Source> consumer;

    //Get the Service
    URL wsdURL = new URL("http://localhost:8081/myservice?wsdl");
    QName serviceName = new QName("http://notification/", "ConsumerService");
    Service service = Service.create(wsdURL, serviceName);

    //Get the Dispatch
    QName portName = new QName("http://notification/", "ConsumerPort");
    consumer = service.createDispatch(portName, Source.class, Service.Mode.PAYLOAD);

    //ProducerService - Subscribe
    String message = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
            + "<not:subscribe xmlns:not=\"http://notification/\" xmlns:S=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:wsa=\"http://www.w3.org/2005/08/addressing\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">"
            + "<name>Peter</name>"
            + "<epr> <Address xmlns=\"http://www.w3.org/2005/08/addressing\">http://localhost:8081/myservice</Address>"
            + "<Metadata xmlns=\"http://www.w3.org/2005/08/addressing\" xmlns:wsdli=\"http://www.w3.org/ns/wsdl-instance\" wsdli:wsdlLocation=\"http://notification/ http://localhost:8081/myservice?wsdl\">"
            + "<wsam:InterfaceName xmlns:wsam=\"http://www.w3.org/2007/05/addressing/metadata\" xmlns:wsaw=\"http://www.w3.org/2006/05/addressing/wsdl\" xmlns:wsns=\"http://notification/\">wsns:Consumer</wsam:InterfaceName>"
            + "<wsam:ServiceName xmlns:wsam=\"http://www.w3.org/2007/05/addressing/metadata\" xmlns:wsaw=\"http://www.w3.org/2006/05/addressing/wsdl\" xmlns:wsns=\"http://notification/\" EndpointName=\"ConsumerPort\">wsns:ConsumerService</wsam:ServiceName>"
            + "</Metadata> </epr> </not:subscribe> ";

    System.out.println("[ConsumerClient] Sending Subscribe Message");

    Source res = consumer.invoke(new StreamSource(new StringReader(message)));   // Here is where it crashes cause it cannot find the service (com.sun.xml.ws.client.ClientTransportException: The server sent HTTP status code 404: Not Found)

    System.out.println("[ConsumerClient] Received Response:");

    Transformer transformer = TransformerFactory.newInstance().newTransformer();
    Result output = new StreamResult(System.out);
    transformer.transform(res, output);

}

我附上了下面的日志

在服务器端

2016-05-03 17:14:24.374:INFO::main: Logging initialized @759ms
May 03, 2016 5:14:29 PM com.sun.xml.ws.server.MonitorBase createRoot
INFO: Metro monitoring rootname successfully set to: com.sun.metro:pp=/,type=WSEndpoint,name=ConsumerService-ConsumerPort
2016-05-03 17:14:30.317:INFO:oejs.Server:main: jetty-9.2.15.v20160210
2016-05-03 17:14:30.437:INFO:oejsh.ContextHandler:main: Started o.e.j.h.s.HttpSpiContextHandler@557db906{/myservice,null,AVAILABLE}
2016-05-03 17:14:30.494:INFO:oejs.ServerConnector:main: Started ServerConnector@44e8195b{HTTP/1.1}{0.0.0.0:8081}
2016-05-03 17:14:30.495:INFO:oejs.Server:main: Started @6883ms
Exception in thread "main" java.lang.NullPointerException
at com.sun.xml.ws.transport.http.server.HttpEndpoint.getEPRAddress(HttpEndpoint.java:104)
at com.sun.xml.ws.transport.http.server.HttpEndpoint.getEndpointReference(HttpEndpoint.java:135)
at com.sun.xml.ws.transport.http.server.EndpointImpl.getEndpointReference(EndpointImpl.java:348)
at com.sun.xml.ws.transport.http.server.EndpointImpl.getEndpointReference(EndpointImpl.java:341)
at fr.endpoint.TestService.main(TestService.java:111)

在客户端

2016-05-03 17:14:39.518:INFO::main: Logging initialized @2297ms
[ConsumerClient] Sending Subscribe Message
Exception in thread "main" com.sun.xml.ws.client.ClientTransportException: The server sent HTTP status code 404: Not Found
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.checkStatusCode(HttpTransportPipe.java:222)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.process(HttpTransportPipe.java:179)
at com.sun.xml.ws.transport.http.client.HttpTransportPipe.processRequest(HttpTransportPipe.java:93)
at com.sun.xml.ws.transport.DeferredTransportPipe.processRequest(DeferredTransportPipe.java:105)
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:629)
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:588)
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:573)
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:470)
at com.sun.xml.ws.client.Stub.process(Stub.java:319)
at com.sun.xml.ws.client.dispatch.DispatchImpl.doInvoke(DispatchImpl.java:189)
at com.sun.xml.ws.client.dispatch.DispatchImpl.invoke(DispatchImpl.java:215)
at fr.endpoint.ConsumerClient.main(ConsumerClient.java:54)

为此端点设置上下文时我们缺少什么?或者也许是因为我们没有正确初始化Jetty HttpServer?

我无法找到很多关于JAX-WS和Jetty集成的文档。如果您能给我们任何暗示和建议,我们将非常感激。

我们使用Metro 2.3作为JAX-WS RI,Jetty 9.2.15,Java 1.7(jdk1.7.0_21)和Netbeans 8.0.2。

感谢您的时间

大卫

0 个答案:

没有答案