Difference between revisions of "EclipseLink/Examples/DBWS/AdvancedJavase6Containerless"
(25 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | <css> | ||
+ | .source-java5 {padding: 1em;border:1 px solid black; background-color: white;} | ||
+ | .source-xml {padding: 1em;border:1px solid black; background-color: white;} | ||
+ | .source-text {padding: 1em;border:1px solid black; background-color: white;} | ||
+ | </css> | ||
+ | __NOTOC__ | ||
==DBWS Services running 'containerless' using the Endpoint API == | ==DBWS Services running 'containerless' using the Endpoint API == | ||
− | It is possible to run a Web service <onlyinclude> using Javase 6's | + | It is possible to run a Web service <onlyinclude> using Javase 6's 'containerless' [http://java.sun.com/javase/6/docs/api/javax/xml/ws/Endpoint.html javax.xml.ws.Endpoint API]. |
Javase 6 ships with the JAX-WS 2.x APIx inside the JDK - versions prior to update 4 have JAX-WS 2.0 APIs, which may cause some issues | Javase 6 ships with the JAX-WS 2.x APIx inside the JDK - versions prior to update 4 have JAX-WS 2.0 APIs, which may cause some issues | ||
Line 7: | Line 13: | ||
===<tt>DBWSBuilder javase</tt> packager=== | ===<tt>DBWSBuilder javase</tt> packager=== | ||
When invoked from the command-line, the <tt>DBWSBuilder</tt> offers out-of-the-box support for building and packaging DBWS Services for either the WebLogic server or for running 'containerless' using the [http://java.sun.com/javase/6/docs/api/javax/xml/ws/Endpoint.html javax.xml.ws.Endpoint API] | When invoked from the command-line, the <tt>DBWSBuilder</tt> offers out-of-the-box support for building and packaging DBWS Services for either the WebLogic server or for running 'containerless' using the [http://java.sun.com/javase/6/docs/api/javax/xml/ws/Endpoint.html javax.xml.ws.Endpoint API] | ||
− | |||
− | |||
− | |||
<source lang="text"> | <source lang="text"> | ||
− | + | prompt > dbwsbuilder.cmd -builderFile {path_to_builder.xml} -stageDir {path_to_stageDir} -packageAs {packager} | |
− | prompt > dbwsbuilder.cmd -builderFile {path_to_builder.xml} -stageDir {path_to_stageDir} -packageAs | + | |
Available packagers: | Available packagers: | ||
-packageAs:[default=archive] wls [warFilename] | -packageAs:[default=archive] wls [warFilename] | ||
Line 19: | Line 21: | ||
</source> | </source> | ||
+ | ====Archive layout==== | ||
The content of the <tt>.jar</tt> file is arranged differently from how the <tt>wls</tt> packager builds a <tt>.war</tt> file: | The content of the <tt>.jar</tt> file is arranged differently from how the <tt>wls</tt> packager builds a <tt>.war</tt> file: | ||
<source lang="text"> | <source lang="text"> | ||
wls packager | wls packager | ||
− | + | \---web-inf (root of .war file) | |
− | \---web-inf | + | |
− | + | ||
| web.xml | | web.xml | ||
| | | | ||
Line 41: | Line 42: | ||
eclipselink-dbws-schema.xsd | eclipselink-dbws-schema.xsd | ||
eclipselink-dbws.wsdl | eclipselink-dbws.wsdl | ||
+ | |||
+ | vs. | ||
javase packager | javase packager | ||
− | + | \---meta-inf (root of .jar file) | |
− | + | | eclipselink-dbws.xml | |
− | | | + | | eclipselink-dbws-or.xml |
− | | | + | | eclipselink-dbws-ox.xml |
− | | | + | | eclipselink-dbws-sessions.xml |
− | | | + | | |
− | | | + | +---wsdl |
− | +---wsdl | + | | eclipselink-dbws-schema.xsd |
− | | | + | | eclipselink-dbws.wsdl |
− | | | + | | |
− | | | + | \---_dbws |
− | \---_dbws | + | |
DBWSProvider.class | DBWSProvider.class | ||
+ | </source> | ||
+ | |||
+ | ====Generated Web service Provider==== | ||
+ | The code-generated <code>_dbws.DBWSProvider</code> class is annotated slightly differently for 'containerless' deployment: | ||
+ | <source lang="java5"> | ||
+ | package _dbws; | ||
+ | |||
+ | //javase imports | ||
+ | import java.lang.reflect.Method; | ||
+ | |||
+ | //java eXtension libraries | ||
+ | import javax.annotation.PostConstruct; | ||
+ | import javax.annotation.PreDestroy; | ||
+ | import javax.servlet.ServletContext; | ||
+ | import javax.xml.soap.SOAPMessage; | ||
+ | import javax.xml.ws.Provider; | ||
+ | import javax.xml.ws.ServiceMode; | ||
+ | import javax.xml.ws.WebServiceProvider; | ||
+ | import static javax.xml.ws.Service.Mode.MESSAGE; | ||
+ | |||
+ | //EclipseLink imports | ||
+ | import org.eclipse.persistence.internal.dbws.ProviderHelper; | ||
+ | |||
+ | @WebServiceProvider( | ||
+ | /* wsdlLocation not present in @WebServiceProvider annotation for 'containerless' deployments */ | ||
+ | serviceName = "testService", | ||
+ | portName = "testServicePort", | ||
+ | targetNamespace = "urn:testService" | ||
+ | ) | ||
+ | @ServiceMode(MESSAGE) | ||
+ | public class DBWSProvider extends ProviderHelper implements Provider<SOAPMessage> { | ||
+ | public DBWSProvider() { | ||
+ | super(); | ||
+ | } | ||
+ | @PostConstruct | ||
+ | public void init() { | ||
+ | super.init(); | ||
+ | } | ||
+ | @Override | ||
+ | public SOAPMessage invoke(SOAPMessage request) { | ||
+ | return super.invoke(request); | ||
+ | } | ||
+ | @Override | ||
+ | @PreDestroy | ||
+ | public void destroy() { | ||
+ | super.destroy(); | ||
+ | } | ||
+ | ... | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | ====Example==== | ||
+ | For a DBWS service based on a <tt>DBWSBuilder</tt> <b><tt>table</tt></b> query operation: | ||
+ | <source lang="xml"> | ||
+ | <?xml version="1.0" encoding="UTF-8"?> | ||
+ | <dbws-builder xmlns:xsd="http://www.w3.org/2001/XMLSchema"> | ||
+ | <properties> | ||
+ | <property name="projectName">emp</property> | ||
+ | ... | ||
+ | </properties> | ||
+ | <table | ||
+ | catalogPattern="%" | ||
+ | tableNamePattern="EMP" | ||
+ | /> | ||
+ | </dbws-builder> | ||
+ | </source> | ||
+ | With the <tt>.jar</tt> on the classpath, an Endpoint can be created programmatically: | ||
+ | <source lang="java5"> | ||
+ | //javase imports | ||
+ | ... | ||
+ | import static javax.xml.ws.BindingProvider.ENDPOINT_ADDRESS_PROPERTY; | ||
+ | import static javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING; | ||
+ | ... | ||
+ | //domain imports | ||
+ | import _dbws.DBWSProvider; | ||
+ | |||
+ | public class ContainerlessTest { | ||
+ | |||
+ | static final String ENDPOINT_ADDRESS = | ||
+ | "http://localhost:9999/test"; | ||
+ | |||
+ | public static void main(String[] args) { | ||
+ | |||
+ | // build Endpoint | ||
+ | Endpoint endpoint = Endpoint.create(new DBWSProvider()); | ||
+ | endpoint.publish(ENDPOINT_ADDRESS); | ||
+ | |||
+ | // retrieve info from Provider's annotations | ||
+ | WebServiceProvider dbwsProvider = DBWSProvider.class.getAnnotation(WebServiceProvider.class); | ||
+ | String serviceNamspace = dbwsProvider.targetNamespace(); | ||
+ | String serviceName = dbwsProvider.serviceName(); | ||
+ | String portName = dbwsProvider.portName(); | ||
+ | |||
+ | // build service | ||
+ | QName serviceQName = new QName(serviceNamspace, serviceName); | ||
+ | QName portQName = new QName(serviceNamspace, portName); | ||
+ | Service testService = Service.create(serviceQName); | ||
+ | testService.addPort(portQName, SOAP11HTTP_BINDING, ENDPOINT_ADDRESS); | ||
+ | |||
+ | // build dispatch to send SOAP msg | ||
+ | Dispatch<SOAPMessage> dispatch = testService.createDispatch(portQName, SOAPMessage.class, | ||
+ | Service.Mode.MESSAGE); | ||
+ | BindingProvider bp = (BindingProvider)dispatch; | ||
+ | Map<String, Object> rc = bp.getRequestContext(); | ||
+ | rc.put(ENDPOINT_ADDRESS_PROPERTY,ENDPOINT_ADDRESS); | ||
+ | |||
+ | MessageFactory factory = MessageFactory.newInstance(); | ||
+ | SOAPMessage request = factory.createMessage(); | ||
+ | SOAPPart part = request.getSOAPPart(); | ||
+ | DOMSource domSource = new DOMSource(db.parse( | ||
+ | new InputSource(new StringReader(FIND_BY_PK_REQUEST)))); | ||
+ | part.setContent(domSource); | ||
+ | SOAPMessage response = null; | ||
+ | try { | ||
+ | response = dispatch.invoke(request); | ||
+ | } | ||
+ | catch (Exception e) { | ||
+ | e.printStackTrace(); | ||
+ | } | ||
+ | if (response != null) { | ||
+ | Source src = response.getSOAPPart().getContent(); | ||
+ | TransformerFactory tf = TransformerFactory.newInstance(); | ||
+ | Transformer transformer = tf.newTransformer(); | ||
+ | DOMResult result = new DOMResult(); | ||
+ | transformer.transform(src, result); | ||
+ | Document resultDoc = (Document)result.getNode(); | ||
+ | System.out.print(documentToString(resultDoc)); | ||
+ | } | ||
+ | |||
+ | // tearDown service | ||
+ | endpoint.stop(); | ||
+ | } | ||
+ | |||
+ | static final String FIND_BY_PK_REQUEST = | ||
+ | "<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">" + | ||
+ | "<env:Body>" + | ||
+ | "<ns1:findByPrimaryKey_empType xmlns:ns1=\"urn:testService\" xmlns=\"urn:test\">" + | ||
+ | "<ns1:id>7369</ns1:id>" + | ||
+ | "</ns1:findByPrimaryKey_empType>" + | ||
+ | "</env:Body>" + | ||
+ | "</env:Envelope>"; | ||
+ | |||
+ | static String documentToString(Document doc) { | ||
+ | DOMSource domSource = new DOMSource(doc); | ||
+ | StringWriter stringWriter = new StringWriter(); | ||
+ | StreamResult result = new StreamResult(stringWriter); | ||
+ | try { | ||
+ | Transformer transformer = TransformerFactory.newInstance().newTransformer(); | ||
+ | transformer.setOutputProperty("indent", "yes"); | ||
+ | transformer.transform(domSource, result); | ||
+ | return stringWriter.toString(); | ||
+ | } catch (Exception e) { | ||
+ | // e.printStackTrace(); | ||
+ | return "<empty/>"; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Result: | ||
+ | <source lang="xml"> | ||
+ | <?xml version="1.0"> | ||
+ | <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> | ||
+ | <SOAP-ENV:Header /> | ||
+ | <SOAP-ENV:Body> | ||
+ | <srvc:findByPrimaryKey_empTypeResponse xmlns="urn:test" xmlns:srvc="urn:testService"> | ||
+ | <srvc:result> | ||
+ | <empType> | ||
+ | <empno>7369</empno> | ||
+ | <ename>SMITH</ename> | ||
+ | <job>CLERK</job> | ||
+ | <mgr>7902</mgr> | ||
+ | <hiredate>1980-12-17T00:00:00.0-05:00</hiredate> | ||
+ | <sal>800</sal> | ||
+ | <deptno>20</deptno> | ||
+ | </empType> | ||
+ | </srvc:result> | ||
+ | </srvc:findByPrimaryKey_empTypeResponse> | ||
+ | </SOAP-ENV:Body> | ||
+ | </SOAP-ENV:Envelope> | ||
</source> | </source> | ||
</onlyinclude> | </onlyinclude> |
Latest revision as of 10:11, 7 October 2010
DBWS Services running 'containerless' using the Endpoint API
It is possible to run a Web service using Javase 6's 'containerless' javax.xml.ws.Endpoint API.
Javase 6 ships with the JAX-WS 2.x APIx inside the JDK - versions prior to update 4 have JAX-WS 2.0 APIs, which may cause some issues with later API requirements: to fix this, copy jaxws-api.jar and jaxb-api.jar into the endorsed directory (typically $JAVA_HOME/lib/endorsed or $JDK_HOME/jre/lib/endorsed). Please see this link for more details.
DBWSBuilder javase packager
When invoked from the command-line, the DBWSBuilder offers out-of-the-box support for building and packaging DBWS Services for either the WebLogic server or for running 'containerless' using the javax.xml.ws.Endpoint API
prompt > dbwsbuilder.cmd -builderFile {path_to_builder.xml} -stageDir {path_to_stageDir} -packageAs {packager} Available packagers: -packageAs:[default=archive] wls [warFilename] -packageAs:[default=archive] javase [jarFilename] ^^^^^^
Archive layout
The content of the .jar file is arranged differently from how the wls packager builds a .war file:
wls packager \---web-inf (root of .war file) | web.xml | +---classes | | | +---META-INF | | eclipselink-dbws.xml | | eclipselink-dbws-or.xml | | eclipselink-dbws-ox.xml | | eclipselink-dbws-sessions.xml | | | \---_dbws | DBWSProvider.class -- auto-generated JAX-WS 2.0 Provider | \---wsdl eclipselink-dbws-schema.xsd eclipselink-dbws.wsdl vs. javase packager \---meta-inf (root of .jar file) | eclipselink-dbws.xml | eclipselink-dbws-or.xml | eclipselink-dbws-ox.xml | eclipselink-dbws-sessions.xml | +---wsdl | eclipselink-dbws-schema.xsd | eclipselink-dbws.wsdl | \---_dbws DBWSProvider.class
Generated Web service Provider
The code-generated _dbws.DBWSProvider
class is annotated slightly differently for 'containerless' deployment:
package _dbws; //javase imports import java.lang.reflect.Method; //java eXtension libraries import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.servlet.ServletContext; import javax.xml.soap.SOAPMessage; import javax.xml.ws.Provider; import javax.xml.ws.ServiceMode; import javax.xml.ws.WebServiceProvider; import static javax.xml.ws.Service.Mode.MESSAGE; //EclipseLink imports import org.eclipse.persistence.internal.dbws.ProviderHelper; @WebServiceProvider( /* wsdlLocation not present in @WebServiceProvider annotation for 'containerless' deployments */ serviceName = "testService", portName = "testServicePort", targetNamespace = "urn:testService" ) @ServiceMode(MESSAGE) public class DBWSProvider extends ProviderHelper implements Provider<SOAPMessage> { public DBWSProvider() { super(); } @PostConstruct public void init() { super.init(); } @Override public SOAPMessage invoke(SOAPMessage request) { return super.invoke(request); } @Override @PreDestroy public void destroy() { super.destroy(); } ... }
Example
For a DBWS service based on a DBWSBuilder table query operation:
<?xml version="1.0" encoding="UTF-8"?> <dbws-builder xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <properties> <property name="projectName">emp</property> ... </properties> <table catalogPattern="%" tableNamePattern="EMP" /> </dbws-builder>
With the .jar on the classpath, an Endpoint can be created programmatically:
//javase imports ... import static javax.xml.ws.BindingProvider.ENDPOINT_ADDRESS_PROPERTY; import static javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING; ... //domain imports import _dbws.DBWSProvider; public class ContainerlessTest { static final String ENDPOINT_ADDRESS = "http://localhost:9999/test"; public static void main(String[] args) { // build Endpoint Endpoint endpoint = Endpoint.create(new DBWSProvider()); endpoint.publish(ENDPOINT_ADDRESS); // retrieve info from Provider's annotations WebServiceProvider dbwsProvider = DBWSProvider.class.getAnnotation(WebServiceProvider.class); String serviceNamspace = dbwsProvider.targetNamespace(); String serviceName = dbwsProvider.serviceName(); String portName = dbwsProvider.portName(); // build service QName serviceQName = new QName(serviceNamspace, serviceName); QName portQName = new QName(serviceNamspace, portName); Service testService = Service.create(serviceQName); testService.addPort(portQName, SOAP11HTTP_BINDING, ENDPOINT_ADDRESS); // build dispatch to send SOAP msg Dispatch<SOAPMessage> dispatch = testService.createDispatch(portQName, SOAPMessage.class, Service.Mode.MESSAGE); BindingProvider bp = (BindingProvider)dispatch; Map<String, Object> rc = bp.getRequestContext(); rc.put(ENDPOINT_ADDRESS_PROPERTY,ENDPOINT_ADDRESS); MessageFactory factory = MessageFactory.newInstance(); SOAPMessage request = factory.createMessage(); SOAPPart part = request.getSOAPPart(); DOMSource domSource = new DOMSource(db.parse( new InputSource(new StringReader(FIND_BY_PK_REQUEST)))); part.setContent(domSource); SOAPMessage response = null; try { response = dispatch.invoke(request); } catch (Exception e) { e.printStackTrace(); } if (response != null) { Source src = response.getSOAPPart().getContent(); TransformerFactory tf = TransformerFactory.newInstance(); Transformer transformer = tf.newTransformer(); DOMResult result = new DOMResult(); transformer.transform(src, result); Document resultDoc = (Document)result.getNode(); System.out.print(documentToString(resultDoc)); } // tearDown service endpoint.stop(); } static final String FIND_BY_PK_REQUEST = "<env:Envelope xmlns:env=\"http://schemas.xmlsoap.org/soap/envelope/\">" + "<env:Body>" + "<ns1:findByPrimaryKey_empType xmlns:ns1=\"urn:testService\" xmlns=\"urn:test\">" + "<ns1:id>7369</ns1:id>" + "</ns1:findByPrimaryKey_empType>" + "</env:Body>" + "</env:Envelope>"; static String documentToString(Document doc) { DOMSource domSource = new DOMSource(doc); StringWriter stringWriter = new StringWriter(); StreamResult result = new StreamResult(stringWriter); try { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty("indent", "yes"); transformer.transform(domSource, result); return stringWriter.toString(); } catch (Exception e) { // e.printStackTrace(); return "<empty/>"; } } }
Result:
<?xml version="1.0"> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header /> <SOAP-ENV:Body> <srvc:findByPrimaryKey_empTypeResponse xmlns="urn:test" xmlns:srvc="urn:testService"> <srvc:result> <empType> <empno>7369</empno> <ename>SMITH</ename> <job>CLERK</job> <mgr>7902</mgr> <hiredate>1980-12-17T00:00:00.0-05:00</hiredate> <sal>800</sal> <deptno>20</deptno> </empType> </srvc:result> </srvc:findByPrimaryKey_empTypeResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>