Upload
raymond-lynch
View
213
Download
0
Embed Size (px)
Citation preview
Web Services – Java/.Net(The Real Deal)
Nathan Chitty - NelnetMark Malinoski - AES
Outline
Introduction Web Services Interoperability Simple, Right? Adding Headers
WSDL Container classes Simple example construct
SOAP is the Key Analyze working examples Demo working examples
Why are we here?
PESC/Data Transport Standard (DTS) Project Web Service Transport to support higher education
industry Business Requirement – Transport must work with
common industry technologies (Java, .Net)
Disclaimer- Issues faced and resolution to them based on experience with “basic” tool sets/libraries
A little DTS History
January 2004 - Started Project July 2004
Solved .Net to Java Interoperability SOAP Headers (Client to Server)
Sept 2004 Solved .Net to Java Interoperability SOAP Headers (Server to
Client) Finalized Core WSDL Finalized Core exception handling
March 2005 Digitally signed and verified payload
Web Services InteroperabilityHurdles… Differences in Interpretation of Standards
SOAPWSDLWS-IWS-S
Differences in Implementation of StandardsJava (Sun, Apache, IBM, BEA, Oracle) .Net (Microsoft – WSE 1.0, 2.0)
Interoperability – SimpleRight? Wrong! DTS Issues
Interpretation of the WSDLSending and Receiving SOAP Headers!!!X509 Key Exchange Incorporating extended standards
WS-S/XML Signatures
Summary
Hello World Service Add simple header (string) Add complex header (structure) Add other headers and attributes
WS-S Digital SignaturesMust understand attribute
Adding SOAP Headers
Change WSDL Create Container Classes Container Classes require serialization/de-
serialization directives Augment Service code Augment Client code
Modifying the WSDL (Types)
<s:element name=“HeaderIn“ type="s1:HeaderElement"/>
<s:element name=“HeaderOut" type="s1:HeaderElement"/>
<s:complexType name=“HeaderElement">
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="value” type="s:string"/>
</s:sequence>
</s:complexType>
Modifying the WSDL (Messages)<message name="Headers">
<part name=“HeaderContainerIn” element="s1:HeaderIn"/>
<part name=“HeaderContainerOut" element="s1:HeaderOut"/>
</message>
Modifying the WSDL (Binding)
<input>
<soap:body use="literal"/>
<soap:header message="Headers" part=“HeaderContainerIn" use="literal"/>
</input>
<output>
<soap:body use="literal"/>
<soap:header message="Headers” part=“HeaderContainerOut" use="literal"/>
</output>
Java: Creating Container In Class
package com.example.serializable;import java.io.Serializable;
public class HeaderContainerIn implements Serializable {
private String value = null;public HeaderContainerIn(){}public HeaderContainerIn(String newValue){
setValue(newValue);}public String getValue(){ return value;}
public void setValue(String newValue){ value = newValue;}
}
Java: Creating Container Out Class
package com.example.serializable;import java.io.Serializable;
public class HeaderContainerOut implements Serializable {
private String value = null;public HeaderContainerOut(){}public HeaderContainerOut(String newValue){
setValue(newValue);}public String getValue(){ return value;}
public void setValue(String newValue){ value = newValue;}
}
Java Examples (Service)
Modify the WSDD <beanMapping languageSpecificType="java:com.example.serializable.HeaderContainerIn"
qname="ns2:HeaderContainerIn" xmlns:ns2="http://www.someurl.com"/><beanMapping
languageSpecificType="java:com.example.serializable.HeaderContainerOut" qname="ns3:HeaderContainerOut" xmlns:ns3="http://www.someurl.com"/>
Augment the Code (inbound)MessageContext ctx = MessageContext.getCurrentContext();SOAPEnvelope requestEnv = ctx.getRequestMessage().getSOAPEnvelope();
SOAPHeaderElement requestHeader = requestEnv.getHeaderByName("http://www.someurl.com",
“HeaderContainerIn");HeaderContainerIn incontainer = (HeaderContainerIn) requestHeader.getObjectValue();System.out.println(“Value = “ + incontainer.getValue());
Java Examples (Service)
Augment the Code (outbound)HeaderContainerOut outcontainer = new HeaderContainerOut("Response
Header”);
SOAPHeaderElement responseHeader = new SOAPHeaderElement("http://www.someurl.com",“HeaderContainerOut")
responseHeader.setObjectValue(outcontainer);
SOAPEnvelope responseEnv = ctx.getResponseMessage().getSOAPEnvelope();
responseEnv.addHeader(responseHeader);
Java Examples (Client)
Augment the Code (General)QName qn = new QName("http://www.someurl.com",“HeaderContainerIn");
call.registerTypeMapping(HeaderContainerIn.class, qn,new
BeanSerializerFactory(HeaderContainerIn.class, qn),new
BeanDeserializerFactory(HeaderContainerIn.class, qn));
QName qn1 = new QName("http://www.someurl.com",“HeaderContainerOut");
call.registerTypeMapping(HeaderContainerOut.class, qn1,new
BeanSerializerFactory(HeaderContainerOut.class, qn1),new
BeanDeserializerFactory(HeaderContainerOut.class, qn1));
Java Examples (Client)
Augment the Code (outbound)
HeaderContainerIn incontainer
= new HeaderContainerIn(“HELLO WORLD HEADER”);
SOAPHeaderElement requestHeader = new SOAPHeaderElement("http://www.someurl.com", “HeaderContainerIn");
requestHeader.setObjectValue(incontainer);
call.addHeader(requestHeader);
Java Examples (Client)
Augment the Code (inbound)SOAPEnvelope responseEnv =
call.getMessageContext().getResponseMessage().getSOAPEnvelope();
SOAPHeaderElement responseHeader = responseEnv.getHeaderByName("http://www.someurl.com",“HeaderContainerOut");
HeaderContainerOut outcontainer = (HeaderContainerOut) responseHeader.getObjectValue();
System.out.println(“Header Value: “ + outcontainer.getValue());
.Net: Creating the Container classes (Service)
using System.Xml.Serialization;using System.Web.Services.Protocols;
[XmlTypeAttribute(Namespace="http://www.someurl.com")][XmlRootAttribute(ElementName=“HeaderContainerOut",
Namespace="http://www.someurl.com ", IsNullable=false)][XmlInclude(typeof(HeaderContainerOut))]public class BaseContainerClass : SoapHeader{ public string value; }
[XmlTypeAttribute(Namespace="http:// www.someurl.com ")]public class HeaderContainerOut : BaseContainerClass{}
[XmlTypeAttribute(Namespace="http:// www.someurl.com ")][XmlRootAttribute(ElementName=“HeaderContainerIn",
Namespace="http://www.someurl.com ", IsNullable=false)]public class HeaderContainerIn : SoapHeader { public string value;}
.Net: Augment the Service
Add declarations to service ClassPublic HeaderContainerIn LocalHeaderVariableIn
Public BaseContainerClass LocalHeaderVariableOut
Add serialization directives to WebMethod()[SoapHeaderAttribute(“LocalHeaderVariableIn”)]
[SoapHeaderAttribute(“LocalHeaderVariableOut”, Direction=SoapHeaderDirection.Out)]
.Net: Creating the Container classes (Client)
using System.Xml.Serialization;using System.Web.Services.Protocols;
[XmlTypeAttribute(Namespace="http://www.someurl.com")][XmlRootAttribute(ElementName=“HeaderContainerIn",
Namespace="http://www.someurl.com ", IsNullable=false)][XmlInclude(typeof(HeaderContainerIn))]public class BaseContainerClass : SoapHeader{ public string value; }
[XmlTypeAttribute(Namespace="http:// www.someurl.com ")]public class HeaderContainerIn : BaseContainerClass{}
[XmlTypeAttribute(Namespace="http:// www.someurl.com ")][XmlRootAttribute(“HeaderContainerOut", Namespace="http://www.someurl.com ",
IsNullable=false)]public class HeaderContainerOut : SoapHeader { public string value;}
.Net: Augment the Client
Add declarations to Client Web Reference/Proxy ClassPublic BaseContainerClass LocalHeaderVariableInPublic HeaderContainerOut LocalHeaderVariableOut
Add serialization directives to WebMethod() [SoapHeaderAttribute(“LocalHeaderVariableIn”)][SoapHeaderAttribute(“LocalHeaderVariableOut”, Direction=SoapHeaderDirection.Out)]
.Net Example (Client)
//declare headerProxyClass.HeaderContainerIn oInHeader = new
ProxyClass.HeaderContainerIn();oInHeader.value = “Value of Header to Pass”;
//Set local header object to proxy class “in” header variablemySvc.LocalHeaderVariableIn = oInHeader;
//Invoke Service Methodstring responseVal = mySvc.submit(“Payload to Send”);
//Retrieve response header by reference to proxy class “out” variableConsole.write mySvc.LocalHeaderVariableOut.value;
.Net Example (Service)
submit(InboundPayload){
//create header object to hold the incoming headerHeaderContainerIn oHdr = LocalHeaderVariableIn;
//Create return header object to send backHeaderContainerOut oRtnHeader = new HeaderContainerOut ();oRtnHeader.value = "Returned : " + oHdr.value;
//set the return header variable = local header objectthis.LocalHeaderVariableOut = oRtnHeader;
return "Returned : " + InboundPayload;}
SOAP is the Key
SOAP across the wire is of primary importanceElement NamesType attributeNot necessarily the namespace moniker
How it got there is of less importance
Analyze Working Examples
Simple Payload HelloWorld
Add Simple Header string Simple Header Simple Header xsi:type (.Net)
Add Complex Header structure Simple Complex Simple Complex xsi:type (.Net)
Hello World Works interoperable
Java Request SOAP<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Body> <HelloWorldRequest xmlns="http://www.datatransportstandard.com">Hello World</HelloWorldRequest> </soapenv:Body> </soapenv:Envelope>
.Net Request SOAP<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <HelloWorldRequest xmlns="http://www.datatransportstandard.com">Hello World</HelloWorldRequest> </soap:Body> </soap:Envelope>
Simple Header Not interoperable (out of the box)
Java Request SOAP<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:SimpleHeaderIn soapenv:mustUnderstand="0" xsi:type="xsd:string" xmlns:ns1="http://www.datatransportstandard.com">Simple Header - Header </ns1:SimpleHeaderIn> </soapenv:Header> <soapenv:Body> <SimpleHeaderRequest xmlns="http://www.datatransportstandard.com">Simple Header - Payload</SimpleHeaderRequest> </soapenv:Body> </soapenv:Envelope>
.Net Request SOAP<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <SimpleHeaderIn
xmlns="http://www.datatransportstandard.com">Header Value</SimpleHeaderIn> </soap:Header> <soap:Body> <SimpleHeaderRequest xmlns="http://www.datatransportstandard.com">Payload</SimpleHeaderRequest> </soap:Body> </soap:Envelope>
Simple Header (xsi:type .Net) Still not interoperable
Java Request SOAP<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:SimpleHeaderIn soapenv:mustUnderstand="0" xsi:type="xsd:string" xmlns:ns1="http://www.datatransportstandard.com">Simple Header - Header </ns1:SimpleHeaderIn> </soapenv:Header> <soapenv:Body> <SimpleHeaderRequest xmlns="http://www.datatransportstandard.com">Simple Header - Payload</SimpleHeaderRequest> </soapenv:Body> </soapenv:Envelope>
.Net Request SOAP<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <SimpleHeaderIn xsi:type="SimpleHeaderIn" xmlns="http://www.datatransportstandard.com">Header Value</SimpleHeaderIn> </soap:Header> <soap:Body> <SimpleHeaderRequest xmlns="http://www.datatransportstandard.com">Payload</SimpleHeaderRequest> </soap:Body> </soap:Envelope>
Complex Header Not interoperable (out of the box)
Java Request SOAP<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:SimpleComplexHeaderIn soapenv:mustUnderstand="0" xsi:type="ns1:SimpleComplexHeaderIn" xmlns:ns1="http://www.datatransportstandard.com"> <ns1:value>Simple Complex Header - Header </ns1:value> </ns1:SimpleComplexHeaderIn> </soapenv:Header> <soapenv:Body> <SimpleComplexHeaderRequest xmlns="http://www.datatransportstandard.com">Simple Complex Header - Payload</SimpleComplexHeaderRequest> </soapenv:Body> </soapenv:Envelope>
.Net Request SOAP<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <SimpleComplexHeaderIn
xmlns="http://www.datatransportstandard.com"> <value>Simple Complex Header - Header</value> </SimpleComplexHeaderIn> </soap:Header> <soap:Body> <SimpleComplexHeaderRequest xmlns="http://www.datatransportstandard.com">Simple Complex Header - Payload</SimpleComplexHeaderRequest> </soap:Body> </soap:Envelope>
Complex Header (xsi:type .Net) Works Interoperable
Java Request SOAP<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:SimpleComplexHeaderIn soapenv:mustUnderstand="0" xsi:type="ns1:SimpleComplexHeaderIn" xmlns:ns1="http://www.datatransportstandard.com"> <ns1:value>Simple Complex Header - Header </ns1:value> </ns1:SimpleComplexHeaderIn> </soapenv:Header> <soapenv:Body> <SimpleComplexHeaderRequest xmlns="http://www.datatransportstandard.com">Simple Complex Header - Payload</SimpleComplexHeaderRequest> </soapenv:Body> </soapenv:Envelope>
.Net Request SOAP<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Header> <SimpleComplexHeaderIn
xsi:type="SimpleComplexHeaderIn" xmlns="http://www.datatransportstandard.com"> <Simple Complex Header -Header</value> </SimpleComplexHeaderIn> </soap:Header> <soap:Body> <SimpleComplexHeaderRequest xmlns="http://www.datatransportstandard.com">Simple Complex Header -Payload</SimpleComplexHeaderRequest> </soap:Body> </soap:Envelope>
Working Examples
DEMO
Questions?
Contact InformationNathan ChittySoftware Architect - [email protected]
Mark MalioskiTechnical Coordinator/Web Development – [email protected]