【问题标题】:Java SOAP based WebService endpoint over HTTP2基于 Java SOAP 的基于 HTTP2 的 WebService 端点
【发布时间】:2016-03-15 10:08:49
【问题描述】:

是否可以在 java 9 发布之前编写基于 SOAP 的 WebService 和客户端通过 HTTP2 进行通信?

如果是,我应该如何完成这项任务?

背景。最近我阅读并观看了一些关于 HTTP2 的很酷的东西。

文章: HTTP/2: A jump-start for Java developers

书籍章节: High Performance Browser Networking

还有视频:

unRESTful Web Services with HTTP2 by Fabian Stäber

Simone Bordet - HTTP 2.0 & Java: Current Status

简而言之,HTTP/2 更高效,解决了 HTTP/1.1 的问题,并且对 Web 应用程序是透明的(简化了它只是通过网络传输消息的不同表示)。

看起来您可以在使用 RESTful Web 服务时轻松切换到 HTTP2。 您需要在服务器端做的就是通过 Jetty(或其他支持 HTTP2 的容器)部署应用程序。

在客户端使用特殊的 Jetty HttpClient:

// Standard HTTP/1.1 client
new HttpClient();

// HTTP/2 transport client
new HttpClient(new HttpClientTransportOverHTTP2());

您可以通过 HTTP2 进行通信。

另一方面,基于 SOAP 的 WebServices 则完全不同(它们基于 JAX-WS API)。 您可以像这样定义服务器端端点:

@WebService
public class HelloWorld {
    public String hello(String name) {
        return "Hello " + name;
    }
}

使用 java wsgen 生成一些代码,然后像这样运行它:

public class RunService {
   public static void main(String[] args) {
       Endpoint.publish("http://localhost:8080/wsServerExample", new HelloWorld());
   }
}

对于客户端,当您从 WSDL(使用 java wsimport)生成代码时,您可以像这样调用此服务:

public class WsClient {
    public static void main(String args[]) {
        HelloWorldService shs = new HelloWorldService();
        HelloWorld sh = shs.getHelloWorldPort();
        ((BindingProvider) sh).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/wsServerExample");
        System.out.println(sh.hello("bary"));
    }
}

对于服务器,您可以通过更改属性 com.sun.net.httpserver.HttpServerProvider 来提供 HttpServer 的不同实现,例如:

System.setProperty("com.sun.net.httpserver.HttpServerProvider", "org.eclipse.jetty.http.spi.JettyHttpServerProvider");

但这不会为您提供 HTTP2 传输(对吗?)。

所以在我看来,这种基于 SOAP 的 WebServices 的 HTTP 传输被深埋在 java API 内部,在 java 9 之前无法切换到 HTTP2(或者至少我不知道如何做到这一点)?

我错过了什么吗?如果您有任何想法,请分享。

谢谢

【问题讨论】:

    标签: java web-services soap http2


    【解决方案1】:

    要使服务器端能够提供 http/2 端点,您需要一个支持 http/2 的服务器(jetty 或 undertow 从 2017 年 4 月起支持它)。

    此外,服务器必须配置为提供 https,即您必须添加 ssl/tls-certificate。因此,您创建了一个包含服务器证书的 java 密钥库。

    虽然 http/2 的工作不需要 https,但大多数客户端都需要对连接进行加密。此外,在使用 jetty 或 undertow 等服务器时,您必须通过添加 alpn-jar 来添加对 alpn(应用层协议协商)的支持。

    如果你使用 Spring Boot 和 Undertow 作为你的服务器,你可以这样配置它:

    @Bean
    UndertowEmbeddedServletContainerFactory embeddedServletContainerFactory() {
        UndertowEmbeddedServletContainerFactory factory = new UndertowEmbeddedServletContainerFactory();
        factory.addBuilderCustomizers(
                builder -> builder.setServerOption(UndertowOptions.ENABLE_HTTP2, true));
        return factory;
    }
    

    这应该添加到您的 application.properties:

    server.port=8443
    server.ssl.key-store=classpath:sample.jks
    server.ssl.key-store-password=secret
    server.ssl.key-password=password
    

    启动服务器时,必须将 ALPN-jar 添加到引导类路径:

    -Xbootclasspath/p:/home/user_x/.m2/repository/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar
    

    您的 http/2-client 必须信任服务器的证书。如果您为服务器创建了自签名证书,则必须将其公钥添加到客户端的 jvm 信任库中:

    $ keytool -import -trustcacerts -keystore /opt/java/jre/lib/security/cacerts \
    -storepass changeit -noprompt -alias mycert -file /tmp/examplecert.crt
    

    这个答案的灵感来自这篇博文:https://vanwilgenburg.wordpress.com/2016/04/01/spring-boot-http2/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-17
      • 2012-10-02
      • 1970-01-01
      • 2010-11-16
      • 2016-12-30
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多