27 Developing Dynamic Proxy Clients

This chapter highlights the differences between static and dynamic proxy clients, and describes the steps to develop a dynamic proxy client for WebLogic web services using Java API for XML Web Services (JAX-WS)

This chapter includes the following sections:

Overview of Static Versus Dynamic Proxy Clients

Table 27-1 highlights the differences between static and dynamic proxy clients.

Table 27-1 Static Versus Dynamic Proxy Clients

Proxy Client Type Description

Static proxy client

Compile and bind the web service client at development time. This generates a static stub for the web service client proxy. The source code for the generated static stub client relies on a specific service implementation. As a result, this option offers the least flexibility.

For examples of static proxy clients, see:

Dynamic proxy client

Compile nothing at development time. At runtime, the application retrieves and interprets the WSDL and dynamically constructs calls. A dynamic proxy client enables a web service client to invoke a web service based on a service endpoint interface (SEI) dynamically at run-time (without using clientgen). This option does not rely upon a specific service implementation, providing greater flexibility, but also a greater performance hit.

The steps to develop a dynamic proxy client are described in Steps to Develop a Dynamic Proxy Client.

Steps to Develop a Dynamic Proxy Client

The steps to create a dynamic proxy client are outlined in the following table. For more information, see the javax.xml.ws.Service Javadoc at http://docs.oracle.com/javase/8/docs/api/javax/xml/ws/Service.html.

Table 27-2 Steps to Create a Dynamic Proxy Client

# Step Description

1

Create the javax.xml.ws.Service instance.

Create the Service instance using the Service.create method.

You must pass the service name and optionally the location of the WSDL document. The method details are as follows:

public static Service create (QName serviceName) throws javax.xml.ws.WebServiceException {}
public static Service create (URL wsdlDocumentLocation, QName serviceName) throws javax.xml.ws.WebServiceException {}

For example:

URL wsdlLocation = new URL("http://example.org/my.wsdl");
QName serviceName = new QName("http://example.org/sample", "MyService");
Service s = Service.create(wsdlLocation, serviceName);

See Additional Considerations When Specifying WSDL Location for additional usage information.

2

Create the proxy stub.

Use the Service.getPort method to create the proxy stub. You can use this stub to invoke operations on the target service endpoint.

You must pass the service endpoint interface (SEI) and optionally the name of the port in the WSDL service description. The method details are as follows:

public <T> T getPort(QName portName, Class<T> serviceEndpointInterface) throws javax.xml.ws.WebServiceException {}
public <T> T getPort(Class<T> serviceEndpointInterface) throws javax.xml.ws.WebServiceException {}

For example:

MyPort port = s.getPort(MyPort.class);

Additional Considerations When Specifying WSDL Location

If you use HTTPS to get the web service from the WSDL, and the hostname definition in the WebLogic Server SSL certificate does not equal the hostname of the peer HTTPS server or is not one of the following, the action fails with a hostname verification error:

  • localhost

  • 127.0.0.1

  • hostname of localhost

  • IP address of localhost

The hostname verification error is as follows:

EchoService service = new EchoService(https-wsdl, webservice-qName);
:
:
javax.xml.ws.WebServiceException: javax.net.ssl.SSLKeyException:  
Security:090504 Certificate chain received from host.example.com - 192.0.2.1
failed hostname verification check. Certificate contained {....} but
check expected host.example.com

The recommended workaround is to use HTTP instead of HTTPS to get the web service from a WSDL when creating the service, and your own hostname verifier code to verify the hostname after the service is created:

EchoService service = Service.create(http_wsdl, qname);
//get Port
EchoPort port = service.getPort(...);
//set self-defined hostname verifier
((BindingProvider) port).getRequestContext().put(
      com.sun.xml.ws.developer.JAXWSProperties.HOSTNAME_VERIFIER,
      new  MyHostNameVerifier());
/*
*/  

Optionally, you can ignore hostname verification by setting the binding provider property:

((BindingProvider) port).getRequestContext().put(
      BindingProviderProperties.HOSTNAME_VERIFICATION_PROPERTY,
      "true");

However, if you must use HTTPS to get the web service from the WSDL, there are several possible workarounds:

  • Turn off hostname verification if you are using the WebLogic Server HTTPS connection. To do this, set the global system property to ignore hostname verification:

    weblogic.security.SSL.ignoreHostnameVerification=true
    

    The system property does not work for service creation if the connection is a JDK connection or other non-WebLogic Server connection.

  • Set your own hostname verifier for the connection before you get the web service from the WSDL, then use HTTPS to get the web service from the WSDL:

    //set self-defined hostname verifier
    URL url = new URL(https_wsdl);
    HttpsURLConnection connection = (HttpsURLConnection)url.openConnection();
    connection.setHostnameVerifier(new MyHostNameVerifier());
     
    //then initiate the service
    EchoService service = Service.create(https_wsdl, qname);
     
    //get port and set self-defined hostname verifier to binding provider
    ... 

For the workarounds in which you set your own hostname verifier, an example hostname verifier might be as follows:

public class MyHostnameVerifier implements HostnameVerifier {
    public boolean verify(String hostname, SSLSession session) {
            if (hostname.equals("the host you want"))
          return true;
           else
               return false;
    }
}