Wednesday July 19, 2006
JAX-WS 2.0 example illustrating Soap Messages with Headers and generating Soap Faults and Soap Header Faults
This techtip will focus on how to send and receive headers in soap messages and how to generate and throw soap faults and soap header faults.
Step 1
Create your wsdl description for your webservices endpoint which will send and receive headers in soap messagesand generate and throw soap faults and soap header faults.
In this techtip example our wsdl will define the following 4 operations:
GoodOrderTestWithSoapHeaderAndMUFalse
GoodOrderTestWithSoapHeaderAndMUTrue
SoapHeaderFaultTest
SoapFaultTest
These 4 operations will demonstrate the sending and receiving of headers in soap messages and generating and throwing back a soap fault and a soap header fault.
a) HeaderTestDefs.xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema
targetNamespace="http://headertestservice.org/types4"
xmlns:tns="http://headertestservice.org/types4"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.w3.org/2001/XMLSchema">
<import namespace="http://schemas.xmlsoap.org/soap/envelope/"
schemaLocation="soap-env.xsd"/>
<complexType name="ProductOrderRequest">
<sequence>
<element name="item" type="tns:ProductOrderItem" maxOccurs="unbounded"/>
<element name="customerInfo" type="tns:CustomerInfo" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
<complexType name="ProductOrderItem">
<sequence>
<element name="productName" type="string" minOccurs="1" maxOccurs="1"/>
<element name="productCode" type="tns:ProductCode" minOccurs="1" maxOccurs="1"/>
<element name="quantity" type="int" minOccurs="1" maxOccurs="1"/>
<element name="price" type="decimal" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
<complexType name="ProductOrderResponse">
<sequence>
<element name="item" type="tns:ProductOrderItem" maxOccurs="unbounded"/>
</sequence>
</complexType>
<complexType name="CustomerInfo">
<sequence>
<element name="creditcard" type="string" minOccurs="1" maxOccurs="1"/>
<element name="name" type="string" minOccurs="1" maxOccurs="1"/>
<element name="street" type="string" minOccurs="1" maxOccurs="1"/>
<element name="city" type="string" minOccurs="1" maxOccurs="1"/>
<element name="state" type="string" minOccurs="1" maxOccurs="1"/>
<element name="zip" type="string" minOccurs="1" maxOccurs="1"/>
<element name="country" type="string" minOccurs="1" maxOccurs="1"/>
</sequence>
</complexType>
<simpleType name="ProductCode">
<restriction base="integer">
<minInclusive value="1"/>
<maxInclusive value="99999999999999999999999999999999999999999999999"/>
</restriction>
</simpleType>
<element name="BadOrderFaultReason" type="tns:BadOrderFaultType"/>
<complexType name="BadOrderFaultType">
<sequence>
<element name="message" type="string"/>
</sequence>
</complexType>
<element name="ConfigHeaderRequest" type="tns:ConfigHeader"/>
<complexType name="ConfigHeader">
<sequence>
<annotation>
<documentation>
This is the configuration header
</documentation>
</annotation>
<element name="message" type="string"/>
<element name="testName" type="string"/>
</sequence>
<attribute ref="env:mustUnderstand"/>
</complexType>
<element name="ConfigFaultReason" type="tns:ConfigFaultType"/>
<complexType name="ConfigFaultType">
<sequence>
<annotation>
<documentation>
This is the configuration fault
</documentation>
</annotation>
<element name="message" type="string"/>
</sequence>
<attribute ref="env:mustUnderstand"/>
</complexType>
</schema>
b) soap-env.xsd
<?xml version='1.0' encoding='UTF-8' ?>
<!-- Schema for the SOAP/1.1 envelope
This schema has been produced using W3C's SOAP Version 1.2 schema
found at:
http://www.w3.org/2001/06/soap-envelope
Copyright 2001 Martin Gudgin, Developmentor.
Changes made are the following:
- reverted namespace to http://schemas.xmlsoap.org/soap/envelope/
- reverted mustUnderstand to only allow 0 and 1 as lexical values
- made encodingStyle a global attribute 20020825
Original copyright:
Copyright 2001 W3C (Massachusetts Institute of Technology,
Institut National de Recherche en Informatique et en Automatique,
Keio University). All Rights Reserved.
http://www.w3.org/Consortium/Legal/
This document is governed by the W3C Software License [1] as
described in the FAQ [2].
[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720
[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://schemas.xmlsoap.org/soap/envelope/"
targetNamespace="http://schemas.xmlsoap.org/soap/envelope/" >
<!-- Envelope, header and body -->
<!-- COMMENT OUT FOR NOW (AEF) FUNCTIONALITY NOT AVAILABLE YET
<xs:element name="Envelope" type="tns:Envelope" />
<xs:complexType name="Envelope" >
<xs:sequence>
<xs:element ref="tns:Header" minOccurs="0" />
<xs:element ref="tns:Body" minOccurs="1" />
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Header" type="tns:Header" />
<xs:complexType name="Header" >
<xs:sequence>
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Body" type="tns:Body" />
<xs:complexType name="Body" >
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" >
<xs:annotation>
<xs:documentation>
Prose in the spec does not specify that attributes are allowed on the Body element
</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>
-->
<!-- Global Attributes. The following attributes are intended to be usable via qualified attribute names on any complex type referencing them. -->
<xs:attribute name="mustUnderstand" default="false" >
<xs:simpleType>
<xs:restriction base='xs:boolean'>
<xs:pattern value='false|true' />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="actor" type="xs:anyURI" />
<!-- COMMENT OUT FOR NOW (AEF) FUNCTIONALITY NOT AVAILABLE YET
<xs:simpleType name="encodingStyle" >
<xs:annotation>
<xs:documentation>
'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element. For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification
</xs:documentation>
</xs:annotation>
<xs:list itemType="xs:anyURI" />
</xs:simpleType>
<?xml version='1.0' encoding='UTF-8' ?>
<!-- Schema for the SOAP/1.1 envelope
This schema has been produced using W3C's SOAP Version 1.2 schema
found at:
http://www.w3.org/2001/06/soap-envelope
Copyright 2001 Martin Gudgin, Developmentor.
Changes made are the following:
- reverted namespace to http://schemas.xmlsoap.org/soap/envelope/
- reverted mustUnderstand to only allow 0 and 1 as lexical values
</xs:complexType>
<xs:element name="Header" type="tns:Header" />
<xs:complexType name="Header" >
<xs:sequence>
<xs:any namespace="##other" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="lax" />
</xs:complexType>
<xs:element name="Body" type="tns:Body" />
<xs:complexType name="Body" >
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" >
<xs:annotation>
<xs:documentation>
Prose in the spec does not specify that attributes are allowed on the Body element
</xs:documentation>
</xs:annotation>
</xs:anyAttribute>
</xs:complexType>
-->
<!-- Global Attributes. The following attributes are intended to be usable via qualified attribute names on an
y complex type referencing them. -->
<xs:attribute name="mustUnderstand" default="false" >
<xs:simpleType>
<xs:restriction base='xs:boolean'>
<xs:pattern value='false|true' />
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="actor" type="xs:anyURI" />
<!-- COMMENT OUT FOR NOW (AEF) FUNCTIONALITY NOT AVAILABLE YET
<xs:simpleType name="encodingStyle" >
<xs:annotation>
<xs:documentation>
'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing
element. For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in
SOAP specification
</xs:documentation>
</xs:annotation>
<xs:list itemType="xs:anyURI" />
</xs:simpleType>
<xs:attribute name="encodingStyle" type="tns:encodingStyle" />
<xs:attributeGroup name="encodingStyle" >
<xs:attribute ref="tns:encodingStyle" />
</xs:attributeGroup>
<xs:element name="Fault" type="tns:Fault" />
<xs:complexType name="Fault" final="extension" >
<xs:annotation>
<xs:documentation>
Fault reporting structure
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="faultcode" type="xs:QName" />
<xs:element name="faultstring" type="xs:string" />
<xs:element name="faultactor" type="xs:anyURI" minOccurs="0" />
<xs:element name="detail" type="tns:detail" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="detail">
<xs:sequence>
<xs:any namespace="##any" minOccurs="0" maxOccurs="unbounded" processContents="lax" />
</xs:sequence>
<xs:anyAttribute namespace="##any" processContents="lax" />
</xs:complexType>
-->
</xs:schema>
c) HeaderTestService.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions
name="HeaderTestService"
targetNamespace="http://headertestservice.org/HeaderTestService.wsdl"
xmlns:mts1="http://headertestservice.org/HeaderTestService.wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
<import
namespace="http://headertestservice.org/HeaderTestService.wsdl"
location="HeaderTestDefs.wsdl"/>
<types/>
<service name="HeaderTestService">
<port name="HeaderTestPort" binding="mts1:HeaderTestSoapBinding">
<soap:address location="http://localhost:8080/WSW2JRLHeaderTest/jaxws/HeaderTest"/>
</port>
</service>
</definitions>
d) HeaderTestDefs.wsdl
<?xml version="1.0" encoding="utf-8"?>
<definitions
name="HeaderTestDefs"
targetNamespace="http://headertestservice.org/HeaderTestService.wsdl"
xmlns:tns="http://headertestservice.org/HeaderTestService.wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns4="http://headertestservice.org/types4">
<types>
<xsd:schema elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://headertestservice.org/types4" schemaLocation="HeaderTestDefs.xsd"/>
</xsd:schema>
</types>
<message name="SubmitOrderRequest">
<part name="ProductOrderRequest" type="ns4:ProductOrderRequest"/>
<part name="ConfigHeader" element="ns4:ConfigHeaderRequest"/>
</message>
<message name="SubmitOrderResponse">
<part name="ProductOrderResponse" type="ns4:ProductOrderResponse"/>
</message>
<message name="BadOrderFault">
<part name="Reason" element="ns4:BadOrderFaultReason"/>
</message>
<message name="ConfigFault">
<part name="ConfigFault" element="ns4:ConfigFaultReason"/>
</message>
<portType name="HeaderTest">
<operation name="submitOrder">
<input message="tns:SubmitOrderRequest"/>
<output message="tns:SubmitOrderResponse"/>
<fault name="BadOrderFault" message="tns:BadOrderFault"/>
<fault name="ConfigFault" message="tns:ConfigFault"/>
</operation>
</portType>
<binding name="HeaderTestSoapBinding" type="tns:HeaderTest">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"/>
<operation name="submitOrder">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal" parts="ProductOrderRequest" namespace="http://headertestservice.org/HeaderTestService.wsdl"/>
<soap:header message="tns:SubmitOrderRequest" part="ConfigHeader" use="literal"/>
</input>
<output>
<soap:body use="literal" namespace="http://headertestservice.org/HeaderTestService.wsdl"/>
</output>
<fault name="BadOrderFault">
<soap:fault name="BadOrderFault" use="literal"/>
</fault>
<fault name="ConfigFault">
<soap:fault name="ConfigFault" use="literal"/>
</fault>
</operation>
</binding>
</definitions>
Step 2
Run wsimport to generate the server side artifacts for the webservices endpoint using the schema and wsdl created above.
First create a customization file for the server side generation.
a) customfile-server.xml and customfile2-server.xml
<?xml version="1.0" encoding="UTF-8"?>
<bindings wsdlLocation="wsdl/HeaderTestService.wsdl" xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<package name="headertest.server"/>
</bindings>
</bindings>
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="wsdl/HeaderTestDefs.xsd" node="/xs:schema">
<jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
<jxb:package name="headertest.server"/>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
Second run wsimport to generate the server side artifacts using the above customization file.
b) ant import-wsdl-server
import-wsdl-server:
init:
[mkdir] Created dir: /home/af70133/netbeans/nbprojects/HeaderTest/classes
[mkdir] Created dir: /home/af70133/netbeans/nbprojects/HeaderTest/dist
[mkdir] Created dir: /home/af70133/netbeans/nbprojects/HeaderTest/generated
do-wsdl2java:
[echo] Invoking WsImport task (WSDL-to-Java mapping)
[echo] wsdlLocation=/home/af70133/netbeans/nbprojects/HeaderTest/conf/wsdl/HeaderTestService.wsdl
[echo] wsdl=/home/af70133/netbeans/nbprojects/HeaderTest/conf/wsdl/HeaderTestService.wsdl
[wsimport] command line: wsimport /files/jdk/jdk1.5.0/jre/bin/java -classpath /sun/appserver9/lib/activation.jar:/sun/appserver9/lib/javaee.jar:/sun/appserver9/lib/appserv-ws.jar com.sun.tools.ws.WsImport -d /home/af70133/netbeans/nbprojects/HeaderTest/classes -keep -s /home/af70133/netbeans/nbprojects/HeaderTest/generated -verbose /home/af70133/netbeans/nbprojects/HeaderTest/conf/wsdl/HeaderTestService.wsdl -wsdllocation /home/af70133/netbeans/nbprojects/HeaderTest/conf/wsdl/HeaderTestService.wsdl -b /home/af70133/netbeans/nbprojects/HeaderTest/conf/customfile2-server.xml -b /home/af70133/netbeans/nbprojects/HeaderTest/conf/customfile-server.xml
[wsimport] headertest/server/BadOrderFaultType.java
[wsimport] headertest/server/ConfigFaultType.java
[wsimport] headertest/server/ConfigHeader.java
[wsimport] headertest/server/CustomerInfo.java
[wsimport] headertest/server/HeaderTest.java
[wsimport] headertest/server/HeaderTestService.java
[wsimport] headertest/server/ObjectFactory.java
[wsimport] headertest/server/ProductOrderItem.java
[wsimport] headertest/server/ProductOrderRequest.java
[wsimport] headertest/server/ProductOrderResponse.java
[wsimport] headertest/server/package-info.java
[wsimport] headertest/server/BadOrderFault.java
[wsimport] headertest/server/BadOrderFaultType.java
[wsimport] headertest/server/ConfigFault.java
[wsimport] headertest/server/ConfigFaultType.java
[wsimport] headertest/server/ConfigHeader.java
[wsimport] headertest/server/CustomerInfo.java
[wsimport] headertest/server/HeaderTest.java
[wsimport] headertest/server/HeaderTestService.java
[wsimport] headertest/server/ObjectFactory.java
[wsimport] headertest/server/ProductOrderItem.java
[wsimport] headertest/server/ProductOrderRequest.java
[wsimport] headertest/server/ProductOrderResponse.java
[wsimport] headertest/server/package-info.java
Step 3
Create and implement the code for the webservices server side endpoint.
a) HeaderTestImpl.java
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
/*
* %W% %E%
*/
package headertest.server;
import javax.xml.ws.WebServiceException;
import javax.jws.WebService;
@WebService(
portName="HeaderTestPort",
serviceName="HeaderTestService",
targetNamespace="http://headertestservice.org/HeaderTestService.wsdl",
wsdlLocation="WEB-INF/wsdl/HeaderTestService.wsdl",
endpointInterface="headertest.server.HeaderTest"
)
public class HeaderTestImpl implements HeaderTest {
public ProductOrderResponse submitOrder(ProductOrderRequest poRequest,
ConfigHeader configHeader) throws BadOrderFault, ConfigFault {
ProductOrderResponse poResponse = null;
poResponse = new ProductOrderResponse();
String testName = configHeader.getTestName();
ConfigFaultType cft = new ConfigFaultType();
cft.setMessage(testName);
cft.setMustUnderstand(true);
if(testName.equals("GoodOrderTestWithSoapHeaderAndMUFalse")) {
if(!ValidHeader(configHeader, false, "Config Header", testName))
throw new ConfigFault("Invalid ConfigHeader: mustUnderstand="+
configHeader.isMustUnderstand()+", message="+
configHeader.getMessage()+", testName="+testName, cft);
poResponse.getItem().addAll(poRequest.getItem());
} else if(testName.equals("GoodOrderTestWithSoapHeaderAndMUTrue")) {
if(!ValidHeader(configHeader, true, "Config Header", testName))
throw new ConfigFault("Invalid ConfigHeader: mustUnderstand="+
configHeader.isMustUnderstand()+", message="+
configHeader.getMessage()+", testName="+testName, cft);
poResponse.getItem().addAll(poRequest.getItem());
} else if(testName.equals("SoapHeaderFaultTest")) {
throw new ConfigFault("This is a soap header fault ConfigFault", cft);
} else if(testName.equals("SoapFaultTest")) {
BadOrderFaultType bft = new BadOrderFaultType();
bft.setMessage(testName);
throw new BadOrderFault("This is a soap fault BadOrderFault", bft);
} else {
throw new ConfigFault("Invalid ConfigHeader: mustUnderstand="+
configHeader.isMustUnderstand()+", message="+
configHeader.getMessage()+", testName="+testName, cft);
}
return poResponse;
}
private boolean ValidHeader(ConfigHeader ch, boolean mu, String msg, String test) {
if(ch.isMustUnderstand() == mu
&& ch.getMessage().equals(msg) && ch.getTestName().equals(test))
return true;
else
return false;
}
}
Step 4
Build and compile the webservices server side endpoint code and package it in a war file.
a) ant compile-server create-war
compile-server:
[echo] compile-server
[javac] Compiling 1 source file to /home/af70133/netbeans/nbprojects/HeaderTest/classes
compile-server-w2j:
[echo] compile-server-w2j
create-war:
[echo] create-war
[echo] Creating war file /home/af70133/netbeans/nbprojects/HeaderTest/dist/headertest/HeaderTestService.war
[war] Building war: /home/af70133/netbeans/nbprojects/HeaderTest/dist/headertest/HeaderTestService.war
[echo] Created war file /home/af70133/netbeans/nbprojects/HeaderTest/dist/headertest/HeaderTestService.war
build-server-w2j:
build-server:
Step 5
Deploy the webservices endpoint packaged in the war to a GlassFish appserver environment.
a) ant deploy
Buildfile: build.xml
checkPlatform:
configUnix:
configWindows:
filter.password.file:
[copy] Copying 1 file to /home/af70133/netbeans/nbprojects/HeaderTest/build
configPlatform:
deploy:
[echo] deploy
[echo] Deploying /home/af70133/netbeans/nbprojects/HeaderTest/dist/headertest/HeaderTestService.war.
[echo] asadmin deploy --user admin --passwordfile /home/af70133/netbeans/nbprojects/HeaderTest/build/password.txt --host localhost --port 4848 --contextroot HeaderTestService --target server --updload=true
[exec] Command deploy executed successfully.
Developing WebServices Client Side Code for soap with attachments
Step 1
Run wsimport to generate the client side artifacts to communicate with the webservices endpoint developed in previous section pointing to the wsdl of the deployed endpoint on a GlassFish appserver environment.
First create the customization file for the client side generation.
a) customfile-client.xml and customfile2-client.xml
<?xml version="1.0" encoding="UTF-8"?>
<bindings wsdlLocation="wsdl/HeaderTestService.wsdl" xmlns="http://java.sun.com/xml/ns/jaxws">
<bindings node="wsdl:definitions" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<package name="headertest.client"/>
</bindings>
</bindings>
<jxb:bindings version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings schemaLocation="wsdl/HeaderTestDefs.xsd" node="/xs:schema">
<jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
<jxb:package name="headertest.client"/>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
Second run wsimport to generate the client side artifacts to communicate with the endpoint developed in the previous section pointing to the wsdl of the deployed endpoint on a GlassFish appserver environment using the above customization file.
b) ant import-wsdl-client
import-wsdl-client:
init:
do-wsdl2java:
[echo] Invoking WsImport task (WSDL-to-Java mapping)
[echo] wsdlLocation=http://localhost:8001/HeaderTestService/jaxws/HeaderTest?WSDL
[echo] wsdl=/home/af70133/netbeans/nbprojects/HeaderTest/conf/wsdl/HeaderTestService.wsdl
[wsimport] command line: wsimport /files/jdk/jdk1.5.0/jre/bin/java -classpath /sun/appserver9/lib/activation.jar:/sun/appserver9/lib/javaee.jar:/sun/appserver9/lib/appserv-ws.jar:/home/af70133/netbeans/nbprojects/HeaderTest/classes com.sun.tools.ws.WsImport -d /home/af70133/netbeans/nbprojects/HeaderTest/classes -keep -s /home/af70133/netbeans/nbprojects/HeaderTest/generated -verbose /home/af70133/netbeans/nbprojects/HeaderTest/conf/wsdl/HeaderTestService.wsdl -wsdllocation http://localhost:8001/HeaderTestService/jaxws/HeaderTest?WSDL -b /home/af70133/netbeans/nbprojects/HeaderTest/conf/customfile-client.xml -b /home/af70133/netbeans/nbprojects/HeaderTest/conf/customfile2-client.xml
[wsimport] headertest/client/BadOrderFaultType.java
[wsimport] headertest/client/ConfigFaultType.java
[wsimport] headertest/client/ConfigHeader.java
[wsimport] headertest/client/CustomerInfo.java
[wsimport] headertest/client/HeaderTest.java
[wsimport] headertest/client/HeaderTestService.java
[wsimport] headertest/client/ObjectFactory.java
[wsimport] headertest/client/ProductOrderItem.java
[wsimport] headertest/client/ProductOrderRequest.java
[wsimport] headertest/client/ProductOrderResponse.java
[wsimport] headertest/client/package-info.java
[wsimport] headertest/client/BadOrderFault.java
[wsimport] headertest/client/BadOrderFaultType.java
[wsimport] headertest/client/ConfigFault.java
[wsimport] headertest/client/ConfigFaultType.java
[wsimport] headertest/client/ConfigHeader.java
[wsimport] headertest/client/CustomerInfo.java
[wsimport] headertest/client/HeaderTest.java
[wsimport] headertest/client/HeaderTestService.java
[wsimport] headertest/client/ObjectFactory.java
[wsimport] headertest/client/ProductOrderItem.java
[wsimport] headertest/client/ProductOrderRequest.java
[wsimport] headertest/client/ProductOrderResponse.java
[wsimport] headertest/client/package-info.java
Step 2
Create the client code to communicate with the deployed endpoint.
a) Client.java
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/
package headertest.client;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.rmi.*;
import java.util.*;
import javax.xml.ws.*;
import javax.xml.soap.*;
import javax.activation.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.*;
import javax.xml.namespace.QName;
import java.math.BigInteger;
import java.math.BigDecimal;
public class Client {
private static String protocol = "http";
private static String hostname = "localhost";
private static int portnum = 8080;
private static String ctxroot = "/HeaderTestService";
private String endpointUrl = "/HeaderTestService/jaxws/HeaderTest";
private String wsdlUrl = "/HeaderTestService/jaxws/HeaderTest?WSDL";
private static HeaderTest port = null;
private static URL url = null;
private static int idx=0, numoftests=4;
private static boolean tests[] = new boolean[numoftests];
@WebServiceRef
private static HeaderTestService service = null;
public static void main(String[] args ) {
try {
Client client = new Client();
port = service.getHeaderTestPort();
System.out.println("WebService Port = "+port);
BindingProvider bindingprovider = (BindingProvider)port;
java.util.Map context = bindingprovider.getRequestContext();
String targetEndpointAddr = (String)context.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY);
System.out.println("WebService TargetEndpointAddress = "+targetEndpointAddr);
url = new URL(targetEndpointAddr);
hostname = url.getHost();
portnum = url.getPort();
protocol = url.getProtocol();
String path = url.getPath();
ctxroot = path.substring(0, path.indexOf("/", 2));
System.out.println("WebService Ctxroot = "+ctxroot);
System.out.println("------------------------------------------");
client.GoodOrderTestWithSoapHeaderAndMUFalse();
System.out.println("------------------------------------------");
client.GoodOrderTestWithSoapHeaderAndMUTrue();
System.out.println("------------------------------------------");
client.SoapHeaderFaultTest();
System.out.println("------------------------------------------");
client.SoapFaultTest();
System.out.println("*********************************************");
System.out.println("* Test Summary Results *");
System.out.println("*********************************************");
if(tests[0])
System.out.println("GoodOrderTestWithSoapHeaderAndMUFalse ....... PASSED");
else
System.out.println("GoodOrderTestWithSoapHeaderAndMUFalse ....... FAILED");
if(tests[1])
System.out.println("GoodOrderTestWithSoapHeaderAndMUTrue ....... PASSED");
else
System.out.println("GoodOrderTestWithSoapHeaderAndMUTrue ....... FAILED");
if(tests[2])
System.out.println("SoapHeaderFaultTest ....... PASSED");
else
System.out.println("SoapHeaderFaultTest ....... FAILED");
if(tests[3])
System.out.println("SoapFaultTest ....... PASSED");
else
System.out.println("SoapFaultTest ....... FAILED");
} catch(Exception e) {
System.err.println("Exception occured: "+e.getMessage());
e.printStackTrace(System.err);
System.exit(1);
}
}
public void GoodOrderTestWithSoapHeaderAndMUFalse() {
System.out.println("GoodOrderTestWithSoapHeaderAndMUFalse");
boolean pass = true;
ProductOrderRequest poRequest;
ConfigHeader ch;
try {
poRequest = new ProductOrderRequest();
ProductOrderItem poi = new ProductOrderItem();
poi.setProductName("Product-1");
poi.setProductCode(new BigInteger("100"));
poi.setQuantity(10);
poi.setPrice(new BigDecimal(119.00));
CustomerInfo ci = new CustomerInfo();
ci.setCreditcard("1201-4465-1567-9823");
ci.setName("John Doe");
ci.setStreet("1 Network Drive");
ci.setCity("Burlington");
ci.setState("Ma");
ci.setZip("01837");
ci.setCountry("USA");
poRequest.getItem().add(poi);
poRequest.setCustomerInfo(ci);
ch = new ConfigHeader();
ch.setMustUnderstand(false);
ch.setMessage("Config Header");
ch.setTestName("GoodOrderTestWithSoapHeaderAndMUFalse");
System.out.println(
"Submit good order with soap header (ConfigHeader:MU=false)");
System.out.println("ConfigHeader must be ignored because MU=false");
System.out.println("The service endpoint simply ignores the soap header");
System.out.println("The RPC request must succeed");
ProductOrderResponse poResponse = port.submitOrder(poRequest, ch);
if(!ProductOrdersEqual(poRequest, poResponse))
pass = false;
}
catch (Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++] = pass;
if (!pass)
System.out.println("GoodOrderTestWithSoapHeaderAndMUFalse passed");
else
System.err.println("GoodOrderTestWithSoapHeaderAndMUFalse failed");
}
public void GoodOrderTestWithSoapHeaderAndMUTrue() {
System.out.println("GoodOrderTestWithSoapHeaderAndMUTrue");
boolean pass = true;
ProductOrderRequest poRequest;
ConfigHeader ch;
try {
poRequest = new ProductOrderRequest();
ProductOrderItem poi = new ProductOrderItem();
poi.setProductName("Product-1");
poi.setProductCode(new BigInteger("100"));
poi.setQuantity(10);
poi.setPrice(new BigDecimal(119.00));
CustomerInfo ci = new CustomerInfo();
ci.setCreditcard("1201-4465-1567-9823");
ci.setName("John Doe");
ci.setStreet("1 Network Drive");
ci.setCity("Burlington");
ci.setState("Ma");
ci.setZip("01837");
ci.setCountry("USA");
poRequest.getItem().add(poi);
poRequest.setCustomerInfo(ci);
ch = new ConfigHeader();
ch.setMustUnderstand(true);
ch.setMessage("Config Header");
ch.setTestName("GoodOrderTestWithSoapHeaderAndMUTrue");
System.out.println(
"Submit good order with soap header (ConfigHeader:MU=true)");
System.out.println(
"ConfigHeader must be understood and valid bacause MU=true");
System.out.println(
"The service endpoint understands and validates the soap header as ok");
System.out.println("The RPC request must succeed");
ProductOrderResponse poResponse = port.submitOrder(poRequest, ch);
System.out.println("GoodOrderTestWithMUTrueHeader succeeded (expected)");
if(!ProductOrdersEqual(poRequest, poResponse))
pass = false;
}
catch (Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++] = pass;
if (!pass)
System.out.println("GoodOrderTestWithSoapHeaderAndMUTrue passed");
else
System.err.println("GoodOrderTestWithSoapHeaderAndMUTrue failed");
}
public void SoapHeaderFaultTest() {
System.out.println("SoapHeaderFaultTest");
boolean pass = true;
ProductOrderRequest poRequest;
ConfigHeader ch;
try {
poRequest = new ProductOrderRequest();
ProductOrderItem poi = new ProductOrderItem();
poi.setProductName("Product-1");
poi.setProductCode(new BigInteger("100"));
poi.setQuantity(10);
poi.setPrice(new BigDecimal(119.00));
CustomerInfo ci = new CustomerInfo();
ci.setCreditcard("1201-4465-1567-9823");
ci.setName("John Doe");
ci.setStreet("1 Network Drive");
ci.setCity("Burlington");
ci.setState("Ma");
ci.setZip("01837");
ci.setCountry("USA");
poRequest.getItem().add(poi);
poRequest.setCustomerInfo(ci);
ch = new ConfigHeader();
ch.setMustUnderstand(true);
ch.setMessage("Config Header");
ch.setTestName("SoapHeaderFaultTest");
System.out.println(
"Submit good order with soap header (ConfigHeader:MU=true)");
System.out.println(
"ConfigHeader must be understood and valid bacause MU=true");
System.out.println(
"The service endpoint does not understand the soap header");
System.out.println("The RPC request must fail with a ConfigFault");
ProductOrderResponse poResponse = port.submitOrder(poRequest, ch);
System.err.println("Did not throw expected ConfigFault");
pass = false;
} catch(ConfigFault e) {
System.out.println("Caught expected ConfigFault");
} catch (Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++] = pass;
if (!pass)
System.out.println("SoapHeaderFaultTest passed");
else
System.err.println("SoapHeaderFaultTest failed");
}
public void SoapFaultTest() {
System.out.println("SoapFaultTest");
boolean pass = true;
ProductOrderRequest poRequest;
ConfigHeader ch;
try {
poRequest = new ProductOrderRequest();
ProductOrderItem poi = new ProductOrderItem();
poi.setProductName("Product-1");
poi.setProductCode(new BigInteger("1234123412341234"));
poi.setQuantity(10);
poi.setPrice(new BigDecimal(119.00));
CustomerInfo ci = new CustomerInfo();
ci.setCreditcard("1201-4465-1567-9823");
ci.setName("John Doe");
ci.setStreet("1 Network Drive");
ci.setCity("Burlington");
ci.setState("Ma");
ci.setZip("01837");
ci.setCountry("USA");
poRequest.getItem().add(poi);
poRequest.setCustomerInfo(ci);
ch = new ConfigHeader();
ch.setMustUnderstand(false);
ch.setMessage("Config Header");
ch.setTestName("SoapFaultTest");
System.out.println(
"Submit bad order with soap header (ConfigHeader:MU=false)");
System.out.println("ConfigHeader must be ignored because MU=false");
System.out.println("The service endpoint simply ignores the soap header");
System.out.println(
"Order contains bad product code (must throw BadOrderFault)");
System.out.println("The RPC request must fail with a BadOrderFault");
ProductOrderResponse poResponse = port.submitOrder(poRequest, ch);
System.err.println("Did not throw expected BadOrderFault");
pass = false;
} catch(BadOrderFault e) {
System.out.println("Caught expected BadOrderFault");
} catch (Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++] = pass;
if (!pass)
System.out.println("SoapFaultTest passed");
else
System.err.println("SoapFaultTest failed");
}
private boolean ProductOrdersEqual(ProductOrderRequest req, ProductOrderResponse resp) {
boolean equal = true;
System.out.println("Performing data comparison of request/response (should be equal)");
Object[] reqArray = req.getItem().toArray();
Object[] respArray = resp.getItem().toArray();
ProductOrderItem reqItem = null;
ProductOrderItem respItem = null;
if(reqArray == null || respArray == null) {
System.err.println("Data comparison error (unexpected)");
System.err.println("Got: Item Array = " + respItem);
System.err.println("Expected: Item Array = " + reqItem);
equal = false;
} else if(reqArray.length != respArray.length) {
System.err.println("Data comparison error (unexpected)");
System.err.println("Got: Item Array length = " + respArray.length);
System.err.println("Expected: Item Array length = " + reqArray.length);
equal = false;
} else {
reqItem = (ProductOrderItem) reqArray[0];
respItem = (ProductOrderItem) respArray[0];
}
if(equal) {
if(!reqItem.getProductName().equals(respItem.getProductName()) ||
!reqItem.getProductCode().equals(respItem.getProductCode()) ||
reqItem.getQuantity() != respItem.getQuantity() ||
!reqItem.getPrice().equals(respItem.getPrice())) {
System.err.println("Data comparison error (unexpected)");
System.err.println("Got: <"+respItem.getProductName()+","+
respItem.getProductCode()+","+respItem.getQuantity()+
","+respItem.getPrice()+">");
System.err.println("Expected: <"+reqItem.getProductName()+","+
reqItem.getProductCode()+","+reqItem.getQuantity()+
","+reqItem.getPrice()+">");
equal = false;
} else {
System.out.println("Data comparison ok (expected)");
System.out.println("Got: <"+respItem.getProductName()+","+
respItem.getProductCode()+","+respItem.getQuantity()+
","+respItem.getPrice()+">");
System.out.println("Expected: <"+reqItem.getProductName()+","+
reqItem.getProductCode()+","+reqItem.getQuantity()+
","+reqItem.getPrice()+">");
}
}
return equal;
}
}
Step 3
Build and compile the client code.
a) ant compile-client
Buildfile: build.xml
compile-client:
[echo] compile-client
[javac] Compiling 1 source files to /home/af70133/netbeans/nbprojects/HeaderTest/classes
Step 4
Run the client code which will communicate with the deployed webservices endpoint and demonstrate the sending and receiving of soap messages with attachments.
a) ant runclient
checkPlatform:
configUnix:
configWindows:
filter.password.file:
[copy] Copying 1 file to /home/af70133/netbeans/nbprojects/HeaderTest/build
configPlatform:
runclient:
[echo] runclient headertest.client.Client
[exec] WebService Port = com.sun.xml.ws.client.EndpointIFInvocationHandler@9c176c
[exec] WebService TargetEndpointAddress = http://lobo:8001/HeaderTestService/jaxws/HeaderTest
[exec] WebService Ctxroot = /HeaderTestService
[exec] ------------------------------------------
[exec] GoodOrderTestWithSoapHeaderAndMUFalse
[exec] Submit good order with soap header (ConfigHeader:MU=false)
[exec] ConfigHeader must be ignored because MU=false
[exec] The service endpoint simply ignores the soap header
[exec] The RPC request must succeed
[exec] Performing data comparison of request/response (should be equal)
[exec] Data comparison ok (expected)
[exec] Got:
[exec] Expected:
[exec] GoodOrderTestWithSoapHeaderAndMUFalse failed
[exec] ------------------------------------------
[exec] GoodOrderTestWithSoapHeaderAndMUTrue
[exec] Submit good order with soap header (ConfigHeader:MU=true)
[exec] ConfigHeader must be understood and valid bacause MU=true
[exec] The service endpoint understands and validates the soap header as ok
[exec] The RPC request must succeed
[exec] GoodOrderTestWithMUTrueHeader succeeded (expected)
[exec] Performing data comparison of request/response (should be equal)
[exec] Data comparison ok (expected)
[exec] Got:
[exec] Expected:
[exec] GoodOrderTestWithSoapHeaderAndMUTrue failed
[exec] ------------------------------------------
[exec] SoapHeaderFaultTest
[exec] Submit good order with soap header (ConfigHeader:MU=true)
[exec] ConfigHeader must be understood and valid bacause MU=true
[exec] The service endpoint does not understand the soap header
[exec] The RPC request must fail with a ConfigFault
[exec] SoapHeaderFaultTest failed
[exec] Caught expected ConfigFault
[exec] ------------------------------------------
[exec] SoapFaultTest
[exec] Submit bad order with soap header (ConfigHeader:MU=false)
[exec] ConfigHeader must be ignored because MU=false
[exec] The service endpoint simply ignores the soap header
[exec] Order contains bad product code (must throw BadOrderFault)
[exec] The RPC request must fail with a BadOrderFault
[exec] Caught expected BadOrderFault
[exec] SoapFaultTest failed
[exec] ------------------------------------------
[exec] *********************************************
[exec] * Test Summary Results *
[exec] *********************************************
[exec] GoodOrderTestWithSoapHeaderAndMUFalse ....... PASSED
[exec] GoodOrderTestWithSoapHeaderAndMUTrue ....... PASSED
[exec] SoapHeaderFaultTest ....... PASSED
[exec] SoapFaultTest ....... PASSED
For a working example of this client and server code download here.Posted at 11:29AM Jul 19, 2006 by alanf760 in Sun | Comments[3]
Implementing Soap With Attachments using the WS-I Attachment Profile 1.0 features in JAX-WS 2.0
This techtip will focus on how to send and receive soap messages with attachments using the WS-I Attachment Profile 1.0 features in JAX-WS 2.0. The WS-I Attachment Profile 1.0 defines webservices interoperability standards for how to send and receive soap messages with attachments using the WSDL/MIME bindings and the swaRef schema type. The example code below was developed and tested using a GlassFish implementation.
To understand soap messages with attachments based on the WS-I Attachment Profile 1.0 in JAX-WS 2.0 you will need to be familiar with the following 3 specifications:
WS-I Attachments Profile 1.0
Web Services Description Language (WSDL) 1.1
Simple Object Access Protocol (SOAP) 1.1
WSDL/MIME content can be specified on the <input> and <output> part of the soap binding of a wsdl operation. For example:
<operation name="echoMultipleAttachments">
<soap:operation/>
<input>
<mime:multipartRelated>
<mime:part>
<soap:body parts="request" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</input>
<output>
<mime:multipartRelated>
<mime:part>
<soap:body parts="response" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</output>
</operation>
The wsdl fragment above shows a soap operation called echoMultipleAttachments which contains the wsdl/mime binding on both the input and output parts of the operation. This means that soap messages with attachments will be sent across the wire from client to endpoint via the input section (soap request) and also received across the wire from the endpoint to ednpoint via the output section (soap response). There will be 2 attachments sent in the soap request and 2 attachments received in the soap response both of type "text/plain" and "text/html".
Developing WebServices Server Side Endpoint for soap with attachments
Step 1
Create your wsdl description for your webservices endpoint which will send and receive soap messages with attachments. Below is the schema and wsdl for this techtip.
In this techtip example our wsdl will define the following 6 operations:
getMultipleAttachments
putMultipleAttachments
echoMultipleAttachments
echoAttachmentsAndThrowAFault
echoAttachmentsWithHeader
echoMultipleAttachmentsSwaRef
These 6 operations will demonstrate the different scenarios for sending and receiving soap messages with attachments in the SOAP request, the SOAP response, adding a SOAP header, and throwing back a SOAP fault. Both wsdl:mime binding and swaRef attachments are demonstrated.
a) WS-ISwA.xsd
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://ws-i.org/profiles/basic/1.1/xsd"
xmlns:tns="http://ws-i.org/profiles/basic/1.1/xsd">
<xsd:simpleType name="swaRef">
<xsd:restriction base="xsd:anyURI" />
</xsd:simpleType>
</xsd:schema>
b) SwaTestService.wsdl
<?xml version="1.0" encoding="UTF-8"?>
<definitions name="SwaTestService" targetNamespace="http://SwaTestService.org/wsdl"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://SwaTestService.org/wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:s="http://SwaTestService.org/xsd"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<types>
<schema targetNamespace="http://SwaTestService.org/xsd"
xmlns:tns="http://SwaTestService.org/xsd"
xmlns="http://www.w3.org/2001/XMLSchema"
xmlns:ref="http://ws-i.org/profiles/basic/1.1/xsd"
elementFormDefault="qualified">
<import namespace="http://ws-i.org/profiles/basic/1.1/xsd"
schemaLocation="WS-ISwA.xsd"/>
<element name="InputRequestGet" type="tns:InputRequestGet"/>
<complexType name="InputRequestGet">
<sequence>
<element name="mimeType1" type="string"/>
<element name="mimeType2" type="string"/>
<element name="url1" type="string"/>
<element name="url2" type="string"/>
</sequence>
</complexType>
<element name="InputRequestPut" type="tns:InputRequestPut"/>
<complexType name="InputRequestPut">
<sequence>
<element name="mimeType1" type="string"/>
<element name="mimeType2" type="string"/>
<element name="header" type="string"/>
</sequence>
</complexType>
<element name="InputRequest" type="tns:InputRequest"/>
<complexType name="InputRequest">
<sequence>
<element name="mimeType1" type="string"/>
<element name="mimeType2" type="string"/>
</sequence>
</complexType>
<element name="InputRequestThrowAFault" type="tns:InputRequestThrowAFault"/>
<complexType name="InputRequestThrowAFault">
<sequence>
<element name="mimeType1" type="string"/>
<element name="mimeType2" type="string"/>
</sequence>
</complexType>
<element name="InputRequestWithHeader" type="tns:InputRequestWithHeader"/>
<complexType name="InputRequestWithHeader">
<sequence>
<element name="mimeType1" type="string"/>
<element name="mimeType2" type="string"/>
</sequence>
</complexType>
<element name="InputRequestString" type="tns:InputRequestString"/>
<complexType name="InputRequestString">
<sequence>
<element name="myString" type="string"/>
</sequence>
</complexType>
<element name="InputRequestSwaRef" type="tns:InputRequestSwaRef"/>
<complexType name="InputRequestSwaRef">
<sequence>
<element name="attachRef1" type="ref:swaRef"/>
<element name="attachRef2" type="ref:swaRef">
<annotation>
<appinfo>
<mime:expectedMediaType>text/html</mime:expectedMediaType>
</appinfo>
</annotation>
</element>
</sequence>
</complexType>
<element name="OutputResponse" type="tns:OutputResponse"/>
<complexType name="OutputResponse">
<sequence>
<element name="mimeType1" type="string"/>
<element name="mimeType2" type="string"/>
<element name="result" type="string"/>
<element name="reason" type="string"/>
</sequence>
</complexType>
<element name="OutputResponseString" type="tns:OutputResponseString"/>
<complexType name="OutputResponseString">
<sequence>
<element name="myString" type="string"/>
</sequence>
</complexType>
<element name="OutputResponseSwaRef" type="tns:OutputResponseSwaRef"/>
<complexType name="OutputResponseSwaRef">
<sequence>
<element name="attachRef1" type="ref:swaRef"/>
<element name="attachRef2" type="ref:swaRef">
<annotation>
<appinfo>
<mime:expectedMediaType>text/html</mime:expectedMediaType>
</appinfo>
</annotation>
</element>
<element name="result" type="string"/>
<element name="reason" type="string"/>
</sequence>
</complexType>
<element name="MyHeader" type="tns:MyHeader"/>
<complexType name="MyHeader">
<sequence>
<annotation>
<documentation>
This is my header
</documentation>
</annotation>
<element name="message" type="string"/>
</sequence>
</complexType>
<element name="MyFaultReason" type="tns:MyFaultType"/>
<complexType name="MyFaultType">
<sequence>
<annotation>
<documentation>
This is my fault
</documentation>
</annotation>
<element name="message" type="string"/>
</sequence>
</complexType>
</schema>
</types>
<message name="messageInputSwaRef">
<part name="request" element="s:InputRequestSwaRef"/>
</message>
<message name="messageInputGet">
<part name="request" element="s:InputRequestGet"/>
</message>
<message name="messageInputPut">
<part name="request" element="s:InputRequestPut"/>
<part name="attach1" type="xsd:string"/>
<part name="attach2" type="xsd:string"/>
</message>
<message name="messageInput">
<part name="request" element="s:InputRequest"/>
<part name="attach1" type="xsd:string"/>
<part name="attach2" type="xsd:string"/>
</message>
<message name="messageInputThrowAFault">
<part name="request" element="s:InputRequestThrowAFault"/>
<part name="attach1" type="xsd:string"/>
<part name="attach2" type="xsd:string"/>
</message>
<message name="messageInputWithHeader">
<part name="request" element="s:InputRequestWithHeader"/>
<part name="header" element="s:MyHeader"/>
<part name="attach1" type="xsd:string"/>
<part name="attach2" type="xsd:string"/>
</message>
<message name="messageOutput">
<part name="response" element="s:OutputResponse"/>
<part name="attach1" type="xsd:string"/>
<part name="attach2" type="xsd:string"/>
</message>
<message name="messageOutputStringResponse">
<part name="response" element="s:OutputResponseString"/>
</message>
<message name="messageOutputSwaRef">
<part name="response" element="s:OutputResponseSwaRef"/>
</message>
<message name="MyFault">
<part name="MyFault" element="s:MyFaultReason"/>
</message>
<message name="MyHeaderFault">
<part name="MyHeaderFault" element="s:MyHeaderFaultReason"/>
</message>
<portType name="SwaTest">
<operation name="getMultipleAttachments">
<input message="tns:messageInputGet"/>
<output message="tns:messageOutput"/>
</operation>
<operation name="putMultipleAttachments">
<input message="tns:messageInputPut"/>
<output message="tns:messageOutputStringResponse"/>
</operation>
<operation name="echoMultipleAttachments">
<input message="tns:messageInput"/>
<output message="tns:messageOutput"/>
</operation>
<operation name="echoAttachmentsAndThrowAFault">
<input message="tns:messageInputThrowAFault"/>
<output message="tns:messageOutput"/>
<fault name="MyFault" message="tns:MyFault"/>
</operation>
<operation name="echoAttachmentsWithHeader">
<input message="tns:messageInputWithHeader"/>
<output message="tns:messageOutput"/>
<fault name="MyFault" message="tns:MyFault"/>
</operation>
<operation name="echoMultipleAttachmentsSwaRef">
<input message="tns:messageInputSwaRef"/>
<output message="tns:messageOutputSwaRef"/>
</operation>
</portType>
<binding name="SwaTestSoapBinding" type="tns:SwaTest">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="getMultipleAttachments">
<soap:operation/>
<input>
<soap:body parts="request" use="literal"/>
</input>
<output>
<mime:multipartRelated>
<mime:part>
<soap:body parts="response" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</output>
</operation>
<operation name="putMultipleAttachments">
<soap:operation/>
<input>
<mime:multipartRelated>
<mime:part>
<soap:body parts="request" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
<mime:content part="attach1" type="text/html"/>
<mime:content part="attach1" type="text/xml"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/plain"/>
<mime:content part="attach2" type="text/html"/>
<mime:content part="attach2" type="text/xml"/>
</mime:part>
</mime:multipartRelated>
</input>
<output>
<soap:body use="literal" message="tns:messageOutputStringResponse" parts="response"/>
</output>
</operation>
<operation name="echoMultipleAttachments">
<soap:operation/>
<input>
<mime:multipartRelated>
<mime:part>
<soap:body parts="request" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
<mime:content part="attach1" type="text/html"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/plain"/>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</input>
<output>
<mime:multipartRelated>
<mime:part>
<soap:body parts="response" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
<mime:content part="attach1" type="text/html"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/plain"/>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</output>
</operation>
<operation name="echoAttachmentsAndThrowAFault">
<soap:operation/>
<input>
<mime:multipartRelated>
<mime:part>
<soap:body parts="request" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</input>
<output>
<mime:multipartRelated>
<mime:part>
<soap:body parts="response" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</output>
<fault name="MyFault">
<soap:fault name="MyFault" use="literal"/>
</fault>
</operation>
<operation name="echoAttachmentsWithHeader">
<soap:operation/>
<input>
<mime:multipartRelated>
<mime:part>
<soap:body parts="request" use="literal"/>
<soap:header part="header" use="literal" message="tns:messageInputWithHeader"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</input>
<output>
<mime:multipartRelated>
<mime:part>
<soap:body parts="response" use="literal"/>
</mime:part>
<mime:part>
<mime:content part="attach1" type="text/plain"/>
</mime:part>
<mime:part>
<mime:content part="attach2" type="text/html"/>
</mime:part>
</mime:multipartRelated>
</output>
<fault name="MyFault">
<soap:fault name="MyFault" use="literal"/>
</fault>
</operation>
<operation name="echoMultipleAttachmentsSwaRef">
<soap:operation/>
<input>
<soap:body parts="request" use="literal"/>
</input>
<output>
<soap:body use="literal" message="tns:messageOutputSwaRef" parts="response"/>
</output>
</operation>
</binding>
<service name="SwaTestService">
<port name="SwaTestPort" binding="tns:SwaTestSoapBinding">
<soap:address location="http://localhost:8888/SwaTestService/jaxws/SwaTest"/>
</port>
</service>
</definitions>
Step 2
WSDL/MIME content information is enabled or disabled via use of the enableMIMEContent binding declaration used within a binding customization file.
Run wsimport to generate the server side artifacts for the webservices endpoint using the schema and wsdl created above.
First create a customization file for the server side generation.
a) customfile-server.xml
<jaxws:bindings wsdlLocation="wsdl/SwaTestService.wsdl" version="2.0"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
<jaxws:bindings node="wsdl:definitions">
<jaxws:package name="swatest.server"/>
<jaxws:enableMIMEContent>true</jaxws:enableMIMEContent>
</jaxws:bindings>
<jaxws:bindings
node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://SwaTestService.org/xsd']"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
<jxb:package name="swatest.server"/>
</jxb:schemaBindings>
</jaxws:bindings>
</jaxws:bindings>
Second run wsimport to generate the server side artifacts using the above customization file.
b) ant import-wsdl-server
Buildfile: build.xml
import-wsdl-server:
do-wsdl2java:
[echo] Invoking WsImport task (WSDL-to-Java mapping)
[wsimport] command line: wsimport /files/jdk/jdk1.5.0/jre/bin/java -classpath /sun/appserver9/lib/javaee.jar:/sun/appserver9/lib/appserv-ws.jar:/home/af70133/swatest/classes com.sun.tools.ws.WsImport -d /home/af70133/swatest/classes -keep -s /home/af70133/swatest/generated -verbose wsdl/SwaTestService.wsdl -wsdllocation WEB-INF/wsdl/SwaTestService.wsdl -b /home/af70133/swatest/src/swatest/customfile-server.xml
[wsimport] swatest/server/InputRequest.java
[wsimport] swatest/server/InputRequestGet.java
[wsimport] swatest/server/InputRequestPut.java
[wsimport] swatest/server/InputRequestString.java
[wsimport] swatest/server/InputRequestSwaRef.java
[wsimport] swatest/server/InputRequestThrowAFault.java
[wsimport] swatest/server/InputRequestWithHeader.java
[wsimport] swatest/server/MyFaultType.java
[wsimport] swatest/server/MyHeader.java
[wsimport] swatest/server/ObjectFactory.java
[wsimport] swatest/server/OutputResponse.java
[wsimport] swatest/server/OutputResponseString.java
[wsimport] swatest/server/OutputResponseSwaRef.java
[wsimport] swatest/server/SwaTest.java
[wsimport] swatest/server/SwaTestService.java
[wsimport] swatest/server/package-info.java
Step 3
Create and implement the code for the webservices server side endpoint.
a) SwaTestImpl.java
package swatest.server;
import javax.xml.ws.WebServiceException;
import javax.xml.soap.*;
import javax.activation.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.*;
import java.net.*;
import java.awt.*;
import javax.jws.WebService;
@WebService(
portName="SwaTestPort", serviceName="SwaTestService",
targetNamespace="http://SwaTestService.org/wsdl",
wsdlLocation="WEB-INF/wsdl/SwaTestService.wsdl",
endpointInterface="swatest.server.SwaTest")
public class SwaTestImpl implements SwaTest {
public void getMultipleAttachments(swatest.server.InputRequestGet request,
javax.xml.ws.Holder<swatest.server.OutputResponse> response,
javax.xml.ws.Holder<javax.activation.DataHandler> attach1,
javax.xml.ws.Holder<javax.activation.DataHandler> attach2) {
try {
System.out.println("Enter getMultipleAttachments() ......");
OutputResponse theResponse = new OutputResponse();
theResponse.setMimeType1(request.getMimeType1());
theResponse.setMimeType2(request.getMimeType2());
theResponse.setResult("ok");
theResponse.setReason("ok");
response.value = theResponse;
DataHandler dh1 = new DataHandler(new URL(request.getUrl1()));
DataHandler dh2 = new DataHandler(new URL(request.getUrl2()));
attach1.value = dh1;
attach2.value = dh2;
System.out.println("Leave getMultipleAttachments() ......");
} catch (Exception e) {
throw new WebServiceException(e.getMessage());
}
}
public swatest.server.OutputResponseString
putMultipleAttachments(swatest.server.InputRequestPut request,
javax.activation.DataHandler attach1, javax.activation.DataHandler attach2) {
try {
OutputResponseString theResponse = new OutputResponseString();
theResponse.setMyString("ok");
System.out.println("Enter putMultipleAttachments() ......");
if(attach1 == null) {
System.err.println("attach1 is null (unexpected)");
theResponse.setMyString("not ok");
}
if(attach2 == null) {
System.err.println("attach2 is null (unexpected)");
theResponse.setMyString("not ok");
}
System.out.println("Leave putMultipleAttachments() ......");
return theResponse;
} catch (Exception e) {
throw new WebServiceException(e.getMessage());
}
}
public swatest.server.OutputResponse
echoMultipleAttachments(swatest.server.InputRequest request,
javax.xml.ws.Holder<javax.activation.DataHandler> attach1,
javax.xml.ws.Holder<javax.activation.DataHandler> attach2) {
try {
System.out.println("Enter echoMultipleAttachments() ......");
OutputResponse theResponse = new OutputResponse();
theResponse.setMimeType1(request.getMimeType1());
theResponse.setMimeType2(request.getMimeType2());
theResponse.setResult("ok");
theResponse.setReason("ok");
if(attach1 == null || attach1.value == null) {
System.err.println("attach1.value is null (unexpected)");
theResponse.setReason("attach1.value is null (unexpected)");
theResponse.setResult("not ok");
}
if(attach2 == null || attach2.value == null) {
System.err.println("attach2.value is null (unexpected)");
if(theResponse.getReason().equals("ok"))
theResponse.setReason("attach2.value is null (unexpected)");
else
theResponse.setReason(theResponse.getReason() +
"\nattach2.value is null (unexpected)");
theResponse.setResult("not ok");
}
System.out.println("Leave echoMultipleAttachments() ......");
return theResponse;
} catch (Exception e) {
throw new WebServiceException(e.getMessage());
}
}
public swatest.server.OutputResponse
echoAttachmentsAndThrowAFault(swatest.server.InputRequestThrowAFault request,
javax.xml.ws.Holder<javax.activation.DataHandler> attach1,
javax.xml.ws.Holder<javax.activation.DataHandler> attach2) throws
swatest.server.MyFault {
System.out.println("Enter echoAttachmentsAndThrowAFault() ......");
System.out.println("Throwing back a fault [MyFault] ......");
throw new MyFault("This is my fault", new MyFaultType());
}
public swatest.server.OutputResponse
echoAttachmentsWithHeader(swatest.server.InputRequestWithHeader request,
swatest.server.MyHeader header,
javax.xml.ws.Holder<javax.activation.DataHandler> attach1,
javax.xml.ws.Holder<javax.activation.DataHandler> attach2) throws
swatest.server.MyFault {
System.out.println("Enter echoAttachmentsWithHeader() ......");
if(header.getMessage().equals("do throw a fault")) {
System.out.println("Throwing back a fault [MyFault] ......");
throw new MyFault("This is my fault", new MyFaultType());
}
try {
OutputResponse theResponse = new OutputResponse();
theResponse.setMimeType1(request.getMimeType1());
theResponse.setMimeType2(request.getMimeType2());
theResponse.setResult("ok");
theResponse.setReason("ok");
System.out.println("Leave echoAttachmentsWithHeader() ......");
return theResponse;
} catch (Exception e) {
throw new WebServiceException(e.getMessage());
}
}
public swatest.server.OutputResponseSwaRef echoMultipleAttachmentsSwaRef(
swatest.server.InputRequestSwaRef request) {
System.out.println("Enter echoMultiplAttachmentsSwaRef() ......");
try {
String response = "ok";
if(request.getAttachRef1() == null) {
System.err.println("swaRef attach1 is null (unexpected)");
response = "not ok";
}
if(request.getAttachRef2() == null) {
System.err.println("swaRef attach2 is null (unexpected)");
response = "not ok";
}
OutputResponseSwaRef theResponse = new OutputResponseSwaRef();
theResponse.setAttachRef1(request.getAttachRef1());
theResponse.setAttachRef2(request.getAttachRef2());
theResponse.setResult(response);
theResponse.setReason(response);
System.out.println("Leave echoMultiplAttachmentsSwaRef() ......");
return theResponse;
} catch (Exception e) {
throw new WebServiceException(e.getMessage());
}
}
}
Step 4
Build and compile the webservices server side endpoint code and package it in a war file.
a) ant compile-server create-war
compile-server:
[echo] compile-server
[javac] Compiling 1 source file to /home/af70133/swatest/classes
compile-server-w2j:
[echo] compile-server-w2j
create-war:
[echo] create-war
[echo] Creating war file /home/af70133/swatest/dist/swatest/SwaTestService.war
[war] Building war: /home/af70133/swatest/dist/swatest/SwaTestService.war
[echo] Created war file /home/af70133/swatest/dist/swatest/SwaTestService.war
build-server-w2j:
build-server:
Step 5
Deploy the webservices endpoint packaged in the war to a GlassFish appserver environment.
a) ant deploy
Buildfile: build.xml
checkPlatform:
configUnix:
configWindows:
filter.password.file:
[copy] Copying 1 file to /home/af70133/swatest/build
configPlatform:
deploy:
[echo] deploy
[echo] Deploying /home/af70133/swatest/dist/swatest/SwaTestService.war.
[echo] asadmin deploy --user admin --passwordfile /home/af70133/swatest/build/password.txt --host localhost --port 4848 --contextroot SwaTestService --target server --updload=true
[exec] Command deploy executed successfully.
Developing WebServices Client Side Code for soap with attachments
Step 1
Run wsimport to generate the client side artifacts to communicate with the webservices endpoint developed in previous section pointing to the wsdl of the deployed endpoint on a GlassFish appserver environment.
First create the customization file for the client side generation.
a) customfile-client.xml
<jaxws:bindings wsdlLocation="wsdl/SwaTestService.wsdl" version="2.0"
xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
<jaxws:bindings node="wsdl:definitions">
<jaxws:package name="swatest.client"/>
<jaxws:enableMIMEContent>true</jaxws:enableMIMEContent>
</jaxws:bindings>
<jaxws:bindings
node="wsdl:definitions/wsdl:types/xs:schema[@targetNamespace='http://SwaTestService.org/xsd']"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<jxb:schemaBindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
<jxb:package name="swatest.client"/>
</jxb:schemaBindings>
</jaxws:bindings>
</jaxws:bindings>
Second run wsimport to generate the client side artifacts to communicate with the endpoint developed in the previous section pointing to the wsdl of the deployed endpoint on a GlassFish appserver environment using the above customization file.
b) ant import-wsdl-client
Buildfile: build.xml
import-wsdl-client:
do-wsdl2java:
[echo] Invoking WsImport task (WSDL-to-Java mapping)
[wsimport] command line: wsimport /files/jdk/jdk1.5.0/jre/bin/java -classpath /sun/appserver9/lib/javaee.jar:/sun/appserver9/lib/appserv-ws.jar:/home/af70133/swatest/classes com.sun.tools.ws.WsImport -d /home/af70133/swatest/classes -keep -s /home/af70133/swatest/generated -verbose wsdl/SwaTestService.wsdl -wsdllocation http://localhost:8001/SwaTestService/jaxws/SwaTest?WSDL -b /home/af70133/swatest/src/swatest/customfile-client.xml
[wsimport] swatest/client/InputRequest.java
[wsimport] swatest/client/InputRequestGet.java
[wsimport] swatest/client/InputRequestPut.java
[wsimport] swatest/client/InputRequestString.java
[wsimport] swatest/client/InputRequestSwaRef.java
[wsimport] swatest/client/InputRequestThrowAFault.java
[wsimport] swatest/client/InputRequestWithHeader.java
[wsimport] swatest/client/MyFaultType.java
[wsimport] swatest/client/MyHeader.java
[wsimport] swatest/client/ObjectFactory.java
[wsimport] swatest/client/OutputResponse.java
[wsimport] swatest/client/OutputResponseString.java
[wsimport] swatest/client/OutputResponseSwaRef.java
[wsimport] swatest/client/SwaTest.java
[wsimport] swatest/client/SwaTestService.java
[wsimport] swatest/client/package-info.java
Step 2
Create the client code to communicate with the deployed endpoint.
a) Client.java
package swatest.client;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.rmi.*;
import java.util.*;
import javax.xml.ws.*;
import javax.xml.soap.*;
import javax.activation.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.*;
import javax.xml.namespace.QName;
public class Client {
private String hostname = "localhost";
private int portnum = 8001;
private String ctxroot = "/SwaTestService";
private String endpointUrl = "/SwaTestService/jaxws/SwaTest";
private String wsdlUrl = "/SwaTestService/jaxws/SwaTest?WSDL";
private static int idx=0, numoftests=7;
private static boolean tests[] = new boolean[numoftests];
private static SwaTest port = null;
@WebServiceRef
private static SwaTestService service = null;
public static void main(String[] args ) {
Client client = new Client();
port = service.getSwaTestPort();
client.GetMultipleAttachmentsTest();
System.out.println("------------------------------------------");
client.PutMultipleAttachmentsTest();
System.out.println("------------------------------------------");
client.EchoMultipleAttachmentsTest();
System.out.println("------------------------------------------");
client.EchoAttachmentsAndThrowAFaultTest();
System.out.println("------------------------------------------");
client.EchoAttachmentsWithHeaderTest();
System.out.println("------------------------------------------");
client.EchoAttachmentsWithHeaderAndThrowAFaultTest();
System.out.println("------------------------------------------");
client.EchoMultipleAttachmentsSwaRefTest();
System.out.println("*********************************************");
System.out.println("* Test Summary Results *");
System.out.println("*********************************************");
if(tests[0])
System.out.println("GetMultipleAttachmentsTest ....... PASSED");
else
System.out.println("GetMultipleAttachmentsTest ....... FAILED");
if(tests[1])
System.out.println("PutMultipleAttachmentsTest ....... PASSED");
else
System.out.println("PutMultipleAttachmentsTest ....... FAILED");
if(tests[2])
System.out.println("EchoMultipleAttachmentsTest ....... PASSED");
else
System.out.println("EchoMultipleAttachmentsTest ....... FAILED");
if(tests[3])
System.out.println("EchoAttachmentsAndThrowAFault ....... PASSED");
else
System.out.println("EchoAttachmentsAndThrowAFault ....... FAILED");
if(tests[4])
System.out.println("EchoAttachmentsWithHeaderTest ....... PASSED");
else
System.out.println("EchoAttachmentsWithHeaderTest ....... FAILED");
if(tests[5])
System.out.println("EchoAttachmentsWithHeaderAndThrowAFaultTest ....... PASSED");
else
System.out.println("EchoAttachmentsWithHeaderAndThrowAFaultTest ....... FAILED");
if(tests[6])
System.out.println("EchoMultipleAttachmentsSwaRefTest ....... PASSED");
else
System.out.println("EchoMultipleAttachmentsSwaRefTest ....... FAILED");
}
public void GetMultipleAttachmentsTest() {
System.out.println("GetMultipleAttachmentsTest");
boolean pass = true;
try {
InputRequestGet request = new InputRequestGet();
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
request.setMimeType1("text/plain");
request.setMimeType2("text/html");
request.setUrl1(url1.toString());
request.setUrl2(url2.toString());
System.out.println("Get 2 attachments (text/plain) and (text/html)");
Holder<javax.activation.DataHandler> attach1 =
new Holder<javax.activation.DataHandler>();
Holder<javax.activation.DataHandler> attach2 =
new Holder<javax.activation.DataHandler>();
Holder<OutputResponse> response =
new Holder<OutputResponse>();
port.getMultipleAttachments(request, response, attach1, attach2);
if(!ValidateRequestResponseAttachmentsGetTestCase(
request, response.value, attach1, attach2))
pass = false;
} catch(Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++]=pass;
}
public void PutMultipleAttachmentsTest() {
System.out.println("PutMultipleAttachmentsTest");
boolean pass = true;
try {
InputRequestPut request = new InputRequestPut();
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
request.setMimeType1("text/plain");
request.setMimeType2("text/html");
request.setHeader("notused");
DataHandler attach1 = new DataHandler(url1);
DataHandler attach2 = new DataHandler(url2);
System.out.println("Put 2 attachments (text/plain) and (text/html)");
OutputResponseString response =
port.putMultipleAttachments(request, attach1, attach2);
if(!response.getMyString().equals("ok")) {
System.err.println("Return status is " +
response.getMyString() + ", expected ok");
pass = false;
}
} catch(Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++]=pass;
}
public void EchoMultipleAttachmentsTest() {
System.out.println("EchoMultipleAttachmentsTest");
boolean pass = true;
try {
InputRequest request = new InputRequest();
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
request.setMimeType1("text/plain");
request.setMimeType2("text/html");
DataHandler dh1 = new DataHandler(url1);
DataHandler dh2 = new DataHandler(url2);
Holder<javax.activation.DataHandler> attach1 =
new Holder<javax.activation.DataHandler>();
Holder<javax.activation.DataHandler> attach2 =
new Holder<javax.activation.DataHandler>();
attach1.value = dh1;
attach2.value = dh2;
System.out.println("Echo 2 attachments (text/plain) and (text/html)");
OutputResponse response = port.echoMultipleAttachments(
request, attach1, attach2);
if(!ValidateRequestResponseAttachmentsEchoTestCase(
request, response, attach1, attach2))
pass = false;
} catch(Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++]=pass;
}
public void EchoAttachmentsAndThrowAFaultTest() {
System.out.println("EchoAttachmentsAndThrowAFaultTest");
boolean pass = true;
try {
InputRequestThrowAFault request = new InputRequestThrowAFault();
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
request.setMimeType1("text/plain");
request.setMimeType2("text/html");
DataHandler dh1 = new DataHandler(url1);
DataHandler dh2 = new DataHandler(url2);
Holder<javax.activation.DataHandler> attach1 =
new Holder<javax.activation.DataHandler>();
Holder<javax.activation.DataHandler> attach2 =
new Holder<javax.activation.DataHandler>();
attach1.value = dh1;
attach2.value = dh2;
System.out.println("Echo attachments and throw a fault");
OutputResponse response = port.echoAttachmentsAndThrowAFault(request, attach1, attach2);
pass = false;
} catch(MyFault e) {
System.out.println("Caught expected MyFault exception: "
+ e.getMessage());
} catch(Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++]=pass;
}
public void EchoAttachmentsWithHeaderTest() {
System.out.println("EchoAttachmentsWithHeaderTest");
boolean pass = true;
try {
InputRequestWithHeader request = new InputRequestWithHeader();
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
request.setMimeType1("text/plain");
request.setMimeType2("text/html");
DataHandler dh1 = new DataHandler(url1);
DataHandler dh2 = new DataHandler(url2);
Holder<javax.activation.DataHandler> attach1 =
new Holder<javax.activation.DataHandler>();
Holder<javax.activation.DataHandler> attach2 =
new Holder<javax.activation.DataHandler>();
attach1.value = dh1;
attach2.value = dh2;
MyHeader header = new MyHeader();
header.setMessage("do not throw my fault");
System.out.println("Echo attachments with a header");
OutputResponse response = port.echoAttachmentsWithHeader(
request, header, attach1, attach2);
if(!ValidateRequestResponseAttachmentsEchoWithHeaderTestCase(
request, response, attach1, attach2))
pass = false;
} catch(Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++]=pass;
}
public void EchoAttachmentsWithHeaderAndThrowAFaultTest() {
System.out.println("EchoAttachmentsWithHeaderAndThrowAFaultTest");
boolean pass = true;
try {
InputRequestWithHeader request = new InputRequestWithHeader();
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
request.setMimeType1("text/plain");
request.setMimeType2("text/html");
DataHandler dh1 = new DataHandler(url1);
DataHandler dh2 = new DataHandler(url2);
Holder<javax.activation.DataHandler> attach1 =
new Holder<javax.activation.DataHandler>();
Holder<javax.activation.DataHandler> attach2 =
new Holder<javax.activation.DataHandler>();
attach1.value = dh1;
attach2.value = dh2;
MyHeader header = new MyHeader();
header.setMessage("do throw a fault");
System.out.println("Echo attachments with a header and throw a fault");
OutputResponse response = port.echoAttachmentsWithHeader(
request, header, attach1, attach2);
pass = false;
} catch(MyFault e) {
System.out.println("Caught expected MyFault exception: "
+ e.getMessage());
} catch(Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++]=pass;
}
public void EchoMultipleAttachmentsSwaRefTest() {
System.out.println("EchoMultipleAttachmentsSwaRefTest");
boolean pass = true;
try {
InputRequestSwaRef request = new InputRequestSwaRef();
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
request.setAttachRef1(new DataHandler(url1));
request.setAttachRef2(new DataHandler(url2));
System.out.println("Echo 2 attachments (text/plain) and (text/html) using SwaRef");
OutputResponseSwaRef response = port.echoMultipleAttachmentsSwaRef(request);
if(!ValidateRequestResponseAttachmentsEchoSwaRefTestCase(request, response))
pass = false;
} catch(Exception e) {
System.err.println("Caught exception: " + e.getMessage());
e.printStackTrace(System.err);
pass = false;
}
tests[idx++]=pass;
}
private boolean mimeTypesEqual(String req1, res1, req2, res2) {
boolean result = true;
System.out.println("Check if the mime types are correct");
if(!res1.equals(req1) {
System.err.println("MimeType1 is not equal in request and response");
System.err.println("Request MimeType1 = " + req1);
System.err.println("Response MimeType1 = " + res1);
result=false;
}
if(!res2.equals(req2) {
System.err.println("MimeType2 is not equal in request and response");
System.err.println("Request MimeType2 = " + req2);
System.err.println("Response MimeType2 = " + res2);
result=false;
} else {
System.out.println("The mime types are correct");
}
return result;
}
/* Validate request, response and attachments (getMultipleAttachments) */
private boolean ValidateRequestResponseAttachmentsGetTestCase(InputRequestGet request,
OutputResponse response, Holder<javax.activation.DataHandler>
attach1, Holder<javax.activation.DataHandler> attach2)
{
boolean result=true;
System.out.println("Validating the request, the response, and the attachments");
if(!mimeTypesEqual(request.getMimeType1(), response.getMimeType1(),
request.getMimeType2(), response.getMimeType2()))
result=false;
System.out.println("Check if the response result is correct");
if(!response.getResult().equals("ok")) {
System.err.println("Return status is " + response + ", expected ok");
System.err.println("Return Reason is: " + response.getReason());
result=false;
} else {
System.out.println("The response result is correct");
}
try {
System.out.println("Check if the attachment contents are correct");
DataHandler dh1 = new DataHandler(new URL(request.getUrl1()));
DataHandler dh2 = new DataHandler(new URL(request.getUrl2()));
byte data1[] = new byte[4096];
byte data2[] = new byte[4096];
int count1 = dh1.getInputStream().read(data1, 0, 4096);
int count2 = attach1.value.getInputStream().read(data2, 0, 4096);
if(!ValidateAttachmentData(count1, data1, count2, data2, "Attachment1"))
result=false;
count1 = dh2.getInputStream().read(data1, 0, 4096);
data2 = new byte[4096];
count2 = attach2.value.getInputStream().read(data2, 0, 4096);
if(!ValidateAttachmentData(count1, data1, count2, data2, "Attachment2"))
result=false;
System.out.println("The attachment contents are equal");
} catch(Exception e) {
result=false;
System.err.println("Caught unexpected exception: " + e.getMessage());
e.printStackTrace(System.err);
}
return result;
}
/* Validate request, response and attachments (echoMultipleAttachments) */
private boolean ValidateRequestResponseAttachmentsEchoTestCase(InputRequest request,
OutputResponse response, Holder<javax.activation.DataHandler> attach1, Holder<javax.activation.DataHandler> attach2)
{
boolean result=true;
System.out.println("Validating the request, the response, and the attachments");
if(!mimeTypesEqual(request.getMimeType1(), response.getMimeType1(),
request.getMimeType2(), response.getMimeType2()))
result=false;
System.out.println("Check if the response result is correct");
if(!response.getResult().equals("ok")) {
System.err.println("Return status is " + response + ", expected ok");
System.err.println("Return Reason is: " + response.getReason());
result=false;
} else {
System.out.println("The response result is correct");
}
try {
System.out.println("Check if the attachment contents are correct");
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
DataHandler dh1 = new DataHandler(url1);
byte data1[] = new byte[4096];
byte data2[] = new byte[4096];
int count1 = dh1.getInputStream().read(data1, 0, 4096);
int count2 = attach1.value.getInputStream().read(data2, 0, 4096);
if(!ValidateAttachmentData(count1, data1, count2, data2, "Attachment1"))
result=false;
dh1 = new DataHandler(url2);
count1 = dh1.getInputStream().read(data1, 0, 4096);
count2 = attach2.value.getInputStream().read(data2, 0, 4096);
if(!ValidateAttachmentData(count1, data1, count2, data2, "Attachment2"))
result=false;
} catch(Exception e) {
result=false;
System.err.println("Caught unexpected exception: " + e.getMessage());
e.printStackTrace(System.err);
}
return result;
}
/* Validate request, response and attachments (echoAttachmentsWithHeader) */
private boolean ValidateRequestResponseAttachmentsEchoWithHeaderTestCase(InputRequestWithHeader
request, OutputResponse response, Holder<javax.activation.DataHandler> attach1, Holder<javax.activation.DataHandler> attach2)
{
boolean result=true;
System.out.println("Validating the request, the response, and the attachments");
if(!mimeTypesEqual(request.getMimeType1(), response.getMimeType1(),
request.getMimeType2(), response.getMimeType2()))
result=false;
System.out.println("Check if the response result is correct");
if(!response.getResult().equals("ok")) {
System.err.println("Return status is " + response + ", expected ok");
System.err.println("Return Reason is: " + response.getReason());
result=false;
} else {
System.out.println("The response result is correct");
}
try {
System.out.println("Check if the attachment contents are correct");
URL url1 = new URL("http", hostname, portnum, ctxroot + "/attach.text");
URL url2 = new URL("http", hostname, portnum, ctxroot + "/attach.html");
DataHandler dh1 = new DataHandler(url1);
DataHandler dh2 = new DataHandler(url2);
byte data1[] = new byte[4096];
byte data2[] = new byte[4096];
int count1 = dh1.getInputStream().read(data1, 0, 4096);
int count2 = attach1.value.getInputStream().read(data2, 0, 4096);
if(!ValidateAttachmentData(count1, data1, count2, data2, "Attachment1"))
result=false;
count1 = dh2.getInputStream().read(data1, 0, 4096);
data2 = new byte[4096];
count2 = attach2.value.getInputStream().read(data2, 0, 4096);
if(!ValidateAttachmentData(count1, data1, count2, data2, "Attachment2"))
result=false;
System.out.println("The attachment contents are equal");
} catch(Exception e) {
result=false;
System.err.println("Caught unexpected exception: " + e.getMessage());
e.printStackTrace(System.err);
}
return result;
}
/* Validate request, response and attachments (echoMultipleAttachmentsSwaRef) */
private boolean ValidateRequestResponseAttachmentsEchoSwaRefTestCase(
InputRequestSwaRef request, OutputResponseSwaRef response)
{
boolean result=true;
System.out.println("Validating the request, the response, and the attachments");
if(!response.getResult().equals("ok")) {
System.err.println("Return status is " + response + ", expected ok");
System.err.println("Return Reason is: " + response.getReason());
result=false;
} else {
System.out.println("The response result is correct");
}
if(request.getAttachRef1() == null || request.getAttachRef2() != null) {
System.err.println("AttachRef1 or AttachRef2 is null (unexpected)");
return false;
}
if(response.getAttachRef1() == null || response.getAttachRef2() != null) {
System.err.println("AttachRef1 or AttachRef2 is null (unexpected)");
return false;
}
try {
System.out.println("Check if the attachment contents are correct");
DataHandler dh1 = request.getAttachRef1();
DataHandler dh2 = request.getAttachRef2();
byte data1[] = new byte[4096];
byte data2[] = new byte[4096];
int count1 = dh1.getInputStream().read(data1, 0, 4096);
int count2 = response.getAttachRef1().getInputStream().read(data2, 0, 4096);
if(!ValidateAttachmentData(count1, data1, count2, data2, "SwaRefAttachment1"))
result=false;
count1 = dh2.getInputStream().read(data1, 0, 4096);
data2 = new byte[4096];
count2 = response.getAttachRef2().getInputStream().read(data2, 0, 4096);
if(!ValidateAttachmentData(count1, data1, count2, data2, "SwaRefAttachment2"))
result=false;
if(result) System.out.println("The attachment contents are equal");
} catch(Exception e) {
result=false;
System.err.println("Caught unexpected exception: " + e.getMessage());
e.printStackTrace(System.err);
}
return result;
}
private boolean ValidateAttachmentData(
int count1, byte[] data1, int count2, byte[] data2, String attach)
{
int max=0;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos);
if(count2 > count1) {
System.out.println("Data counts are different so check for and remove any trailing CR's");
System.out.println("Data count1="+count1+", Data count2="+count2);
for(int i=count1; i<count2; i++) {
if((char)data2[i] != '\r') break;
}
System.out.println("Removed "+(count2-count1)+" trailing CR's from data2");
count2 = count1;
}
if(count1 != count2) {
System.err.println(attach+" data count is not equal in request and response");
System.err.println("Request data count = " + count1);
System.err.println("Response data count = " + count2);
if(count2 > count1) max = count1; else max = count2;
ps.printf("data1[%d]=0x%x data2[%d]=0x%x",
max-1, data1[max-1], max-1, data2[max-1]);
System.err.println(baos.toString());
baos.reset();
if(count2 > count1) {
for(int i=count1; i<count2; i++) {
ps.printf("Extra data was: data2[%d]=0x%x|0%o", i, data2[i], data2[i]);
System.err.println(baos.toString());
baos.reset();
}
} else {
for(int i=count2; i<count1; i++) {
ps.printf("Extra data was: data1[%d]=0x%x|0%o", i, data1[i], data1[i]);
System.err.println(baos.toString());
baos.reset();
}
}
return false;
}
for(int i=0; i<count1; i++) {
if(data1[i] != data2[i]) {
System.err.println(attach+" data content is not equal in attachment");
System.err.println("Failed at byte "+i+", data1["+i+"]="+data1[i]+
", data2["+i+"]="+data2[i]);
return false;
}
}
System.out.println(attach+" data count ["+count1+"] and content is equal in attachment");
return true;
}
}
Step 3
Build and compile the client code.
a) ant compile-client
Buildfile: build.xml
compile-client:
[echo] compile-client
[javac] Compiling 1 source files to /home/af70133/swatest/classes
Step 4
Run the client code which will communicate with the deployed webservices endpoint and demonstrate the sending and receiving of soap messages with attachments.
a) ant runclient
Buildfile: build.xml
checkPlatform:
configUnix:
configWindows:
filter.password.file:
[copy] Copying 1 file to /home/af70133/swatest/build
configPlatform:
runclient:
[echo] runclient swatest.client.Client
[exec] ------------------------------------------
[exec] GetMultipleAttachmentsTest
[exec] Get 2 attachments (text/plain) and (text/html)
[exec] Validating the request, the response, and the attachments
[exec] Check if the mime types are correct
[exec] The mime types are correct
[exec] Check if the response result is correct
[exec] The response result is correct
[exec] Check if the attachment contents are correct
[exec] Attachment1 data count [33] and content is equal in attachment
[exec] Attachment2 data count [289] and content is equal in attachment
[exec] The attachment contents are equal
[exec] ------------------------------------------
[exec] PutMultipleAttachmentsTest
[exec] Put 2 attachments (text/plain) and (text/html)
[exec] ------------------------------------------
[exec] EchoMultipleAttachmentsTest
[exec] Echo 2 attachments (text/plain) and (text/html)
[exec] Validating the request, the response, and the attachments
[exec] Check if the mime types are correct
[exec] The mime types are correct
[exec] Check if the response result is correct
[exec] The response result is correct
[exec] Check if the attachment contents are correct
[exec] Attachment1 data count [33] and content is equal in attachment
[exec] Attachment2 data count [289] and content is equal in attachment
[exec] ------------------------------------------
[exec] EchoAttachmentsAndThrowAFaultTest
[exec] Echo attachments and throw a fault
[exec] Caught expected MyFault exception: This is my fault
[exec] ------------------------------------------
[exec] EchoAttachmentsWithHeaderTest
[exec] Echo attachments with a header
[exec] Validating the request, the response, and the attachments
[exec] Check if the mime types are correct
[exec] The mime types are correct
[exec] Check if the response result is correct
[exec] The response result is correct
[exec] Check if the attachment contents are correct
[exec] Attachment1 data count [33] and content is equal in attachment
[exec] Attachment2 data count [289] and content is equal in attachment
[exec] The attachment contents are equal
[exec] ------------------------------------------
[exec] EchoAttachmentsWithHeaderAndThrowAFaultTest
[exec] Echo attachments with a header and throw a fault
[exec] Caught expected MyFault exception: This is my fault
[exec] ------------------------------------------
[exec] EchoMultipleAttachmentsSwaRefTest
[exec] Echo 2 attachments (text/plain) and (text/html) using SwaRef
[exec] Validating the request, the response, and the attachments
[exec] Check if the mime types are correct
[exec] The mime types are correct
[exec] Check if the response result is correct
[exec] The response result is correct
[exec] *********************************************
[exec] * Test Summary Results *
[exec] *********************************************
[exec] GetMultipleAttachmentsTest ....... PASSED
[exec] PutMultipleAttachmentsTest ....... PASSED
[exec] EchoMultipleAttachmentsTest ....... PASSED
[exec] EchoAttachmentsAndThrowAFault ....... PASSED
[exec] EchoAttachmentsWithHeaderTest ....... PASSED
[exec] EchoAttachmentsWithHeaderAndThrowAFaultTest ....... PASSED
[exec] EchoMultipleAttachmentsSwaRefTest ....... PASSED
For a working example of this client and server code download here.Posted at 11:47AM Feb 16, 2006 by alanf760 in Sun | Comments[3]