reenabling soap using erjaxws

26
Reenabling SOAP using ERJaxWS Markus Stoll

Upload: wo-community

Post on 19-May-2015

621 views

Category:

Software


4 download

DESCRIPTION

Presentation made at WOWODC 2014, about a new SOAP framework from Project Wonder.

TRANSCRIPT

Page 1: Reenabling SOAP using ERJaxWS

Reenabling SOAP using ERJaxWSMarkus Stoll

Page 2: Reenabling SOAP using ERJaxWS

WebServices using SOAP

• Why SOAP? I do love REST!

• "Simple Object Access Protocol"

Page 3: Reenabling SOAP using ERJaxWS

SOAP

• Standardized

• self defining

Page 4: Reenabling SOAP using ERJaxWS

JavaWebServices

• known bugs (e. g. problems with https)

• bugs with mapping of complex data types (uses Axis 1.x)

• clumsy (Axis 1.x)

• complicated (Axis 1.x)

• slow (Axis 1.x)

• consider it broken

Page 5: Reenabling SOAP using ERJaxWS

Alternatives?

• AXIS 2

‣ POJO for services and mapped data

‣ service definitions in separate files

‣ rewritten from scratch

!

• Jax WS

‣ POJO for services and mapped data

‣ all definitions using Java Annotations

‣ part of Standard Java!

Page 6: Reenabling SOAP using ERJaxWS

ERJaxWS

• Jax WS RI Libraries

• ERJaxWebServiceRequestHandleradapting WORequest to Jax WS internal engine for handling servlet requests

• NOT API compatible to JavaWebServices

• provide new SOAP service

• provide SOAP service based on imported WSDL

• call external SOAP service based on imported WSDL

Page 7: Reenabling SOAP using ERJaxWS

Provide own SOAP service - 1

package your.app.ws;!import javax.jws.WebService;!@WebService!public class Calculator {! public int add(int a, int b) { return a + b; }}

Page 8: Reenabling SOAP using ERJaxWS

Provide own SOAP service - 2

package your.app;!import javax.xml.ws.Endpoint;!import er.extensions.appserver.ERXApplication;import er.extensions.appserver.ws.ERJaxWebService;import er.extensions.appserver.ws.ERJaxWebServiceRequestHandler;!public class Application extends ERXApplication {! public static void main(String[] argv) { ERXApplication.main(argv, Application.class); }! public Application() { setAllowsConcurrentRequestHandling(true); // do it the WONDER way ERJaxWebServiceRequestHandler wsHandler = new ERJaxWebServiceRequestHandler(); wsHandler.registerWebService("Calculator", new ERJaxWebService<Calculator>(Calculator.class)); this.registerRequestHandler(wsHandler, this.webServiceRequestHandlerKey());! // create a standalone endpoint using Jax WS mechanisms Endpoint.publish("http://localhost:9999/ws/Calculator", new Calculator());! }}

Page 9: Reenabling SOAP using ERJaxWS

Provide own SOAP service - 3 !

LIVE-DEMO

Page 10: Reenabling SOAP using ERJaxWS

Provide SOAP service based on WSDL

// Import WSDL and create interface and classes for mapped data$ wsimport -keep -s Sources http://localhost:port/cgi-bin/WebObjects/WebService1.woa/ws/Calculator?wsdl!// Import WSDL and create jar$ wsimport -clientjar Libraries/myservice.jar http://localhost:port/cgi-bin/WebObjects/WebService1.woa/ws/Calculator?wsdl!!!// create CalculatorImplementationpackage your.app;!import javax.jws.WebService;!@WebService(endpointInterface = "your.app.Calculator")!public class CalculatorImpl implements Calculator{! @Override public int add(int arg0, int arg1) { return arg0 + arg1; }!}

Page 11: Reenabling SOAP using ERJaxWS

Provide SOAP service based on WSDL !

LIVE-DEMO

Page 12: Reenabling SOAP using ERJaxWS

Java Annotations / WebService

• @WebService name, namespace, service interface

• @BindingType SOAP version

• @SOAPBinding WSDL document styles

• @WebMethod name, exclusion

• @WebParam name

• @WebResult name

Page 13: Reenabling SOAP using ERJaxWS

Call a remote SOAP service URL url = new URL("http://127.0.0.1:3333/cgi-bin/WebObjects/JaxServerTest.woa/ws/Hello?wsdl");! // 1st argument service URI, refer to wsdl document above // 2nd argument is service name, refer to wsdl document above QName qname = new QName("http://app.your/", "HelloImplService");! Service service = Service.create(url, qname);! Hello remoteHello = service.getPort(Hello.class);! remoteHello.hello("Jon Doe“);!!! // BETTER: use imported interface! HelloImplService service = new HelloImplService(url);! Hello remoteHello = service.getPort(Hello.class);! remoteHello.hello("Jon Doe“);!

Page 14: Reenabling SOAP using ERJaxWS

Data mapping

• JAXB

• all native Java data types

• all "Bean" classes

• custom type adaptors

Page 15: Reenabling SOAP using ERJaxWS

custom data mapping - 1!!!public class WSStruct {! public String name;! public int zip;! public MyCustomDate myDate; ! public NSTimestamp datetime;}

Page 16: Reenabling SOAP using ERJaxWS

custom data mapping - 2@XmlType(name = "WSStructType", propOrder = {"name", "zip", "datetime"})@XmlAccessorType(value = XmlAccessType.PUBLIC_MEMBER)!public class WSStruct { @XmlElement public String name; @XmlAttribute public int zip; @XmlTransient public MyCustomDate myDate; ! public NSTimestamp datetime;}

Page 17: Reenabling SOAP using ERJaxWS

custom data mapping - 3@XmlType(name = "WSStructType", propOrder = {"name", "zip", "datetime"})@XmlAccessorType(value = XmlAccessType.PUBLIC_MEMBER)!public class WSStruct { @XmlElement public String name; @XmlAttribute public int zip; @XmlTransient public MyCustomDate myDate; @XmlJavaTypeAdapter(value = NSTimestampAdapter.class) public NSTimestamp datetime;}class NSTimestampAdapter extends XmlAdapter<String, NSTimestamp>{ private final NSTimestampFormatter formatter = new NSTimestampFormatter(); public NSTimestamp unmarshal(String v) throws Exception { return (NSTimestamp) formatter.parseObject(v); } public String marshal(NSTimestamp v) throws Exception { return formatter.format(v); }}

Page 18: Reenabling SOAP using ERJaxWS

Data mapping

• Directly map EOs? NO!

• might change

• would need to adapt your EO templates

• avoid marshalling your complete data tree

Page 19: Reenabling SOAP using ERJaxWS

WebFaults

• WebServices exceptions can be defined as WebFaults

• Beware: serialized info is not in Exception but in a referred WebFault bean

• stack traces possible switch off with property com.sun.xml.ws.fault.SOAPFaultBuilder.disableCaptureStackTrace=false

Page 20: Reenabling SOAP using ERJaxWS

WebFault sample@WebFault(faultBean = "TestServiceFaultInfo")public class TestServiceException extends Exception { private TestServiceFaultInfo code; public TestServiceException(String message, TestServiceFaultInfo info) { super(message); this.code = info; } public TestServiceFaultInfo getFaultInfo() { return code; }}!public class TestServiceFaultInfo { public String msg;! public TestServiceFaultInfo() { }! public TestServiceFaultInfo(String msg) { this.msg = msg; }}

Page 21: Reenabling SOAP using ERJaxWS

Stateful Services

• @Stateful - makes no sense in WebObjects env

• Jax WS injects a RequestContext into your Service object

• gives access to WOContext and by that to your Session

• creates WebObjects Cookies as usual

• enable session persistence in your client proxy

Page 22: Reenabling SOAP using ERJaxWS

Stateful Services !

LIVE-DEMO

Page 23: Reenabling SOAP using ERJaxWS

Secure WebServices

• basic auth by common means

• create your own custom ERJaxWebService

• @SOAPMessageHandlerdeclare your own Jax WS message handlersfor example for handling signed SOAP messages

Page 24: Reenabling SOAP using ERJaxWS

Troubleshooting

• Test-Tools

• SoapUI

• http://wsdlbrowser.com

• test against original javax.xml.ws.Endpoint

• compare imported WSDL vs. recreated WSDL

Page 25: Reenabling SOAP using ERJaxWS

Resources

• https://github.com/markusstoll/wonder/tree/ERJaxWS

• https://jax-ws.java.net

• http://www.techferry.com/articles/jaxb-annotations.html

Page 26: Reenabling SOAP using ERJaxWS

Q&AMarkus Stoll junidas GmbH [email protected]