Weblogic - Web Service Complex (with User-Defined Data Types)

> (Weblogic|Fusion Middelware|FMW)

1 - About

The simple web service uses only a simple data type, String, as the parameter and return value of the Web service operation. This article shows how to create a Web service that uses a user-defined data type, in particular a JavaBean called BasicStruct, as both a parameter and a return value of its operation.

To create a Web service using user-defined data type, you just have to:

  • create the Java source of the data type
  • and use it correctly in the JWS file.

The jwsc Ant task, when it encounters a user-defined data type in the JWS file, automatically generates all the data binding artifacts needed to convert data between its XML representation (used in the SOAP messages) and its Java representation (used in WebLogic Server).

3 - JavaBean DataType

BasicStruct JavaBean

package examples.webservices.complex;
 
/**
 * Defines a simple JavaBean called BasicStruct that has integer, String, and
 * String[] properties
 */
public class BasicStruct {
	// Properties
	private int intValue;
	private String stringValue;
	private String[] stringArray;
 
	// Getter and setter methods
	public int getIntValue() {
		return intValue;
	}
 
	public void setIntValue(int intValue) {
		this.intValue = intValue;
	}
 
	public String getStringValue() {
		return stringValue;
	}
 
	public void setStringValue(String stringValue) {
		this.stringValue = stringValue;
	}
 
	public String[] getStringArray() {
		return stringArray;
	}
 
	public void setStringArray(String[] stringArray) {
		this.stringArray = stringArray;
	}
 
	public String toString() {
		return "IntValue=" + intValue + ", StringValue=" + stringValue;
	}
}
Advertising

4 - JWS file

The sample JWS file uses several JWS annotations:

  • @WebMethod to specify explicitly that a method should be exposed as a Web service operation and to change its operation name from the default method name. Below from echoStruct to echoComplexType,
  • @WebParam and @WebResult to configure the parameters and return values;
  • and @SOAPBinding to specify the type of Web service.

The ComplexImpl.java JWS file also imports the examples.webservice.complex.BasicStruct class and then uses the BasicStruct user-defined data type as both a parameter and return value of the echoStruct() method.

package examples.webservices.complex;
 
// Import the standard JWS annotation interfaces
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
// Import the BasicStruct JavaBean
import examples.webservices.complex.BasicStruct;
 
// Standard JWS annotation that specifies that the portType name of the Web
// Service is "ComplexPortType", its public service name is "ComplexService",
// and the targetNamespace used in the generated WSDL is "http://example.org"
@WebService(serviceName = "ComplexService", name = "ComplexPortType", targetNamespace = "http://example.org")
 
// Standard JWS annotation that specifies this is a document-literal-wrapped
// Web Service
@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
 
/**
 * This JWS file forms the basis of a WebLogic Web Service.  The Web Services
 * has two public operations:
 *
 *  - echoInt(int)
 *  - echoComplexType(BasicStruct)
 *
 * The Web Service is defined as a "document-literal" service, which means
 * that the SOAP messages have a single part referencing an XML Schema element
 * that defines the entire body.
 */
 
public class ComplexImpl {
	// Standard JWS annotation that specifies that the method should be exposed
	// as a public operation. Because the annotation does not include the
	// member-value "operationName", the public name of the operation is the
	// same as the method name: echoInt.
	//
	// The WebResult annotation specifies that the name of the result of the
	// operation in the generated WSDL is "IntegerOutput", rather than the
	// default name "return". The WebParam annotation specifies that the input
	// parameter name in the WSDL file is "IntegerInput" rather than the Java
	// name of the parameter, "input".
	@WebMethod()
	@WebResult(name = "IntegerOutput", targetNamespace = "http://example.org/complex")
	public int echoInt(
			@WebParam(name = "IntegerInput", targetNamespace = "http://example.org/complex") int input) {
		System.out.println("echoInt '" + input + "' to you too!");
		return input;
	}
 
	// Standard JWS annotation to expose method "echoStruct" as a public
	// operation
	// called "echoComplexType"
	// The WebResult annotation specifies that the name of the result of the
	// operation in the generated WSDL is "EchoStructReturnMessage",
	// rather than the default name "return".
	@WebMethod(operationName = "echoComplexType")
	@WebResult(name = "EchoStructReturnMessage", targetNamespace = "http://example.org/complex")
	public BasicStruct echoStruct(BasicStruct struct) {
		System.out.println("echoComplexType called");
		return struct;
	}
}

5 - Ant File

<project name="webservices-complex" default="all">
	<!-- set global properties for this build -->
	<property name="wls.username" value="weblogic" />
	<property name="wls.password" value="weblogic" />
	<property name="wls.hostname" value="localhost" />
	<property name="wls.port" value="7001" />
	<property name="wls.server.name" value="myserver" />
	<property name="ear.deployed.name" value="complexServiceEAR" />
	<property name="example-output" value="output" />
	<property name="ear-dir" value="${example-output}/complexServiceEar" />
	<property name="clientclass-dir" value="${example-output}/clientclass" />
	<path id="client.class.path">
		<pathelement path="${clientclass-dir}" />
		<pathelement path="${java.class.path}" />
	</path>
	<taskdef name="jwsc" classname="weblogic.wsee.tools.anttasks.JwscTask" />
	<taskdef name="clientgen" classname="weblogic.wsee.tools.anttasks.ClientGenTask" />
	<taskdef name="wldeploy" classname="weblogic.ant.taskdefs.management.WLDeploy" />
	<target name="all" depends="clean,build-service,deploy,client" />
	<target name="clean" depends="undeploy">
		<delete dir="${example-output}" />
	</target>
	<target name="build-service">
		<jwsc srcdir="src" destdir="${ear-dir}" keepGenerated="true">
			<jws file="examples/webservices/complex/ComplexImpl.java" type="JAXWS">
				<WLHttpTransport contextPath="complex" serviceUri="ComplexService"
					portName="ComplexServicePort" />
			</jws>
		</jwsc>
	</target>
	<target name="deploy">
		<wldeploy action="deploy" name="${ear.deployed.name}" source="${ear-dir}"
			user="${wls.username}" password="${wls.password}" verbose="true"
			adminurl="t3://${wls.hostname}:${wls.port}" targets="${wls.server.name}" />
	</target>
	<target name="undeploy">
		<wldeploy action="undeploy" failonerror="false"
			name="${ear.deployed.name}" user="${wls.username}" password="${wls.password}"
			verbose="true" adminurl="t3://${wls.hostname}:${wls.port}" targets="${wls.server.name}" />
	</target>
	<target name="client">
		<clientgen
			wsdl="http://${wls.hostname}:${wls.port}/complex/ComplexService?WSDL"
			destDir="${clientclass-dir}" packageName="examples.webservices.complex.client"
			type="JAXWS" />
		<javac srcdir="${clientclass-dir}" destdir="${clientclass-dir}"
			includes="**/*.java" />
		<javac srcdir="src" destdir="${clientclass-dir}"
			includes="examples/webservices/complex/client/**/*.java" />
	</target>
	<target name="run">
		<java fork="true" classname="examples.webservices.complex.client.Main"
			failonerror="true">
			<classpath refid="client.class.path" />
			<arg line="http://${wls.hostname}:${wls.port}/complex/ComplexService" />
		</java>
	</target>
</project>

where:

  • The type attribute of the <jws> element specifies the type of Web service (JAX-WS or JAX-RPC).
  • The <WLHttpTransport> child element of the <jws> element of the jwsc Ant task specifies the context path and service URI sections of the URL used to invoke the Web service over the HTTP/S transport, as well as the name of the port in the generated WSDL. For more information about defining the context path, see "Defining the Context Path of a WebLogic Web Service" in WebLogic Web Services Reference for Oracle WebLogic Server.

6 - Test

6.1 - Wsdl

http://localhost:7003/complex/ComplexService?WSDL

<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is 
	Oracle JAX-WS 2.1.5. -->
 
<definitions targetNamespace="http://example.org" name="ComplexService">
	<types>
		<xsd:schema>
			<xsd:import namespace="http://example.org/complex"
				schemaLocation="http://localhost:7003/complex/ComplexService?xsd=1" />
		</xsd:schema>
		<xsd:schema>
			<xsd:import namespace="http://example.org"
				schemaLocation="http://localhost:7003/complex/ComplexService?xsd=2" />
		</xsd:schema>
	</types>
	<message name="echoInt">
		<part name="parameters" element="tns:echoInt" />
	</message>
	<message name="echoIntResponse">
		<part name="parameters" element="tns:echoIntResponse" />
	</message>
	<message name="echoComplexType">
		<part name="parameters" element="tns:echoComplexType" />
	</message>
	<message name="echoComplexTypeResponse">
		<part name="parameters" element="tns:echoComplexTypeResponse" />
	</message>
	<portType name="ComplexPortType">
 
		<operation name="echoInt">
			<input message="tns:echoInt" />
			<output message="tns:echoIntResponse" />
		</operation>
		<operation name="echoComplexType">
			<input message="tns:echoComplexType" />
			<output message="tns:echoComplexTypeResponse" />
		</operation>
	</portType>
	<binding name="ComplexPortTypePortBinding" type="tns:ComplexPortType">
		<soap:binding transport="http://schemas.xmlsoap.org/soap/http"
			style="document" />
		<operation name="echoInt">
			<soap:operation soapAction="" />
			<input>
				<soap:body use="literal" />
			</input>
			<output>
				<soap:body use="literal" />
			</output>
		</operation>
		<operation name="echoComplexType">
			<soap:operation soapAction="" />
			<input>
				<soap:body use="literal" />
			</input>
			<output>
				<soap:body use="literal" />
			</output>
		</operation>
	</binding>
	<service name="ComplexService">
		<port name="ComplexPortTypePort" binding="tns:ComplexPortTypePortBinding">
			<soap:address location="http://localhost:7003/complex/ComplexService" />
		</port>
	</service>
</definitions>
Advertising

6.2 - Client

6.2.1 - echoComplexType

6.2.1.1 - Service Request

echoComplexType Request Detail

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Header />
    <env:Body>
    <echoComplexType xmlns="http://example.org">
      <!--Optional:-->
      <arg0 xmlns="">
        <intValue>3</intValue>
        <!--Zero or more repetitions:-->
        <stringArray>string</stringArray>
        <!--Optional:-->
        <stringValue>string</stringValue>
      </arg0>
    </echoComplexType>
  </env:Body>
  </env:Envelope>
6.2.1.2 - Service Response
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
    <ns3:echoComplexTypeResponse xmlns:ns3="http://example.org" xmlns:ns2="http://example.org/complex">
      <ns2:EchoStructReturnMessage>
        <intValue>3</intValue>
        <stringArray>string</stringArray>
        <stringValue>string</stringValue>
      </ns2:EchoStructReturnMessage>
    </ns3:echoComplexTypeResponse>
  </S:Body>
</S:Envelope>												

6.2.2 - echoInt

6.2.2.1 - Service Request
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Header />
    <env:Body>
    <echoInt xmlns="http://example.org" xmlns:com="http://example.org/complex">
      <com:IntegerInput>2</com:IntegerInput>
    </echoInt>
  </env:Body>
  </env:Envelope>
6.2.2.2 - Service Response
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
    <ns3:echoIntResponse xmlns:ns3="http://example.org" xmlns:ns2="http://example.org/complex">
      <ns2:IntegerOutput>2</ns2:IntegerOutput>
    </ns3:echoIntResponse>
  </S:Body>
  </S:Envelope>	

7 - Documentation / Reference

Advertising
weblogic/web_service_complex.txt · Last modified: 2017/02/12 21:06 by gerardnico