Published on dev2dev (http://dev2dev.bea.com/)
http://dev2dev.bea.com/pub/a/2007/10/jax-ws-jaxb-customization.html
See this if you're having trouble printing code examples
by Mike Wooten
10/30/2007
Using JAX-WS and JAXB with WebLogic Server 10 introduces the JAX-WS Web service stack and the JAXB Java/XML binding technology available in BEA WebLogic Server 10. These implementations are based on JAR files from the Glassfish JAX-WS 2.0 and Glassfish JAXB 2.0 projects.
This article provides a set of tutorials devoted to JAX-WS customization binding—the part of the JAX-WS specification that covers WSDL-to-Java mappings. Some mention of JAXB customization binding appears here and there.
After introducing JAX-WS customization bindings, this article presents a set of tutorials showing how to carry out various customization tasks:
Using a JAX-WS binding declaration to specify Java package names
Using a JAX-WS binding declaration to specify SEI provider interface class name
Using a JAX-WS binding declaration to specify skeleton SEI class name
Using a JAX-WS binding declaration to specify method parameter names
Using a JAX-WS binding declaration to specify exception class names
Using a JAX-WS binding declaration to specify handler chains
Afterwards, I'll take a look at some code samples that use the results of applying JAX-WS and JAXB customization bindings. Customization bindings apply to both the service consumer and service provider, so this will be reflected in these code samples:
Sample JAX-WS code that uses binding declarations in the service provider
Sample JAX-WS code that uses binding declarations in the service consumer
JAX-WS customization binding is the part of the JAX-WS specification that covers WSDL-to-Java mappings. The JAXB specification includes a similar section that covers XSD-to-Java mappings.
This is all well and good, but why would you want to control WSDL-to-Java (or XSD-to-Java) mapping, anyway? I'll answer that question by using some situations you may have faced recently.
You've got a WSDL that uses the value parameters for the name attribute of every <message><part> element. Your JAX-WS tools complain that they can't produce JAX-WS artifacts from this WSDL because the value of the name attributes aren't unique. You obtain the WSDL by concatenating ?WSDL to the service endpoint, and the party hosting the service endpoint has stated that it has no control over the WSDL because it generated "automagically."
A customization binding will allow you to make the name attributes unique, and thereby solve this issue.
You have a project where you need the Java method names and parameters of your JAX-WS Web service to match UML artifacts generated by the corporate architecture team at your company. The WSDL you've already distributed to partners would need to be changed to accommodate this, but you can't do that.
A customization binding will allow you to make the method signature (for example, method name, input parameters) in the JAX-WS Web service match the ones in the UML artifacts.
Your group has a policy that all classes generated from an XML schema must have a fully-qualified name that includes the following, in the order specified:
A customization binding will allow you to instruct your JAXB tools to meet this requirement when they generate JAXB classes.
These are just a few situations where you would want (or need) to use a customization binding. I'll be talking about how to do this throughout this article, so I'll return to defining what it is for now.
Customization binding is frequently referred to as binding declaration, so I'll switch to using that term for the remainder of this article. Binding declarations essentially are "instructions" expressed in XML, which can either be embedded in a WSDL or XML Schema file, or placed in an external XML file. With the latter, XPath expressions are used to select the target section in the WSDL or XML Schema file. The XML file-based approach is the one preferred by SOA architects and developers because it offers flexibility without sacrificing maintainability or governance.
Binding declarations are XML elements that are processed by Sun's wsimport Ant task. In the first article, I pointed out that BEA's Ant tasks (that is, jwsc, wsdlc and clientgen) call the wsimport task internally. I'll be using BEA's wsdlc Ant task in the code associated with this article, so here's the run-wsdlc Ant target that contains it:
<target name="run-wsdlc" depends="clean">
<taskdef name="wsdlc" classname="weblogic.wsee.tools.anttasks.WsdlcTask" classpathref="compile.classpath" />
<mkdir dir="${src.dir}"/>
<property name="binding.declaration.files" value="server-jaxws.xbd,shared-jaxb.xbd"/>
<wsdlc
type="JAXWS"
srcWsdl="etc/${wsdl.file.name}.wsdl"
destJwsDir="WebContent/WEB-INF/lib"
destImplDir="${src.dir}"
explode="false"
verbose="${verbose}"
debug="${debug}"
failonerror="true"
>
<binding dir="etc" includes="${binding.declaration.files}"/>
<classpath>
<path refid="compile.classpath"/>
</classpath>
</wsdlc>
</target>
The type="JAXWS" attribute and child <binding> element are what matter for this discussion. The binding declarations reside inside the file(s) assigned to the includes attribute of the <binding>
element. I use .xbd (which stands for XML Binding Declaration) as the file extension, for binding declaration files. The type="JAXWS" attribute tells the wsdlc Ant task to pass the file(s) through to the wsimport Ant task.
The <property> element holds the names of the two binding customization files that are used. The first one, named etc/server-jaxws.xbd, is for service provider-side JAX-WS binding declarations. The second one, named etc/shared-jaxb.xbd, relates to JAXB and is used on both the service provider and service consumer side.
The simple answer is that you can specify how the information in the WSDL maps to Java code generated for a JAX-WS Web service and a JAX-WS Web service consumer. This Java code includes:
The interface class for the SEI provider
The skeleton class that implements the SEI provider interface class
The names of methods and parameters used in the skeleton class
The exception classes for faults
Using a java.util.Vector instead of a java.util.List in the method signature of a Web service*
Generating sub-classes, super-classes, and super-interfaces for Java objects used as the return value and input arguments of a Web service*
Generating enum classes and the values assigned to their members*
*Accomplished using a JAXB binding customization file
The next section of the article describes the JAX-WS binding declarations that allow you to do the non-asterisk items above.
Now I'll take a look at some of the ways you can use JAX-WS binding declarations.
This binding declaration is probably more valuable with JAXB than with JAX-WS, but it's an important one nonetheless.
I covered the JAX-WS aspect of this binding declaration in the first article, but this one is from the JAXB aspect. The purpose for using it is the same: to control the Java package name for the classes that are generated. Here are the contents of the shared-jaxb.xbd binding declaration file that is used to specify the Java package name for classes generated from an XML schema file:
<jxb:bindings
version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
>
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
schemaLocation="datastaging_exceptions.xsd"
node="/xs:schema"
>
<jxb:schemaBindings>
<jxb:package name="services.datastaging.exceptions"/>
</jxb:schemaBindings>
</jxb:bindings>
</jxb:bindings>
Using this shared-jaxb.xbd file will result in services.datastaging.exceptions being used for the Java package name in all the JAXB classes generated from the datastaging_exceptions.xsd
file. If you didn't specify a binding declaration file, the Java package name for the classes would be based on the targetNamespace attribute (of the <schemas> element) in the datastaging_exceptions.xsd file.
Note: Don't use the package attribute on the wsdlc, jwsc, or clientgen Ant tasks. Doing this will override the <package> binding declarations in your binding declaration file.
If your XML schema file uses <xs:include> or <xs:import> elements, things can be more challenging. The same holds true for a WSDL with a <xs:schema> that uses
<xs:import> elements. In either case, you'll want to use a JAXB binding declaration file to specify the Java package name. Here's an extract from a JAXB binding declaration file that illustrates how to do that using an XML schema from the OASIS WS-Notification
specification:
<jxb:bindings
version="1.0"
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
>
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
schemaLocation="schemas/oasis-wsn13.xsd"
node="/xs:schema"
>
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
node="//xs:schema/xs:import[@namespace='http://docs.oasis-open.org/wsn/b-2']"
>
<jxb:schemaBindings>
<jxb:package name="org.oasis_open.docs.wsn.b_2"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
node="//xs:schema/xs:import[@namespace='http://docs.oasis-open.org/wsn/br-2']"
>
<jxb:schemaBindings>
<jxb:package name="org.oasis_open.docs.wsn.br_2"/>
</jxb:schemaBindings>
</jxb:bindings>
<jxb:bindings
xmlns:xs="http://www.w3.org/2001/XMLSchema"
node="//xs:schema/xs:import[@namespace='http://docs.oasis-open.org/wsn/t-1']"
>
<jxb:schemaBindings>
<jxb:package name="org.oasis_open.docs.wsn.t_1"/>
</jxb:schemaBindings>
</jxb:bindings>
...
</jxb:bindings>
</jxb:bindings>
The bold typeface sections highlight the fact that the XPath expression in the node attribute is what makes things click. The first nested <jxb:bindings> element contains the
schemaLocation attribute, which establishes the XML schema file to be operated on. The node attribute in the other nested <jxb:bindings> elements is where you deal with the various <xs:import> elements in the XML schema file.
You can have more than one nested <jxb:bindings> element with a schemaLocation attribute in a single binding declaration file. If modularity and ease of reuse are high on your list of priorities, then you may not want to do that. Using a separate binding declaration file for each XML schema allows them to be easily used for other purposes. It also makes it easier to organize them into reusable software assets, for governance purposes.
|
The class binding declaration is used to specify the provider interface class for an SEI (Service Endpoint Implementation). Here's an extract from the etc/server-jaxws.xbd file, which shows the class binding declaration being used for this purpose:
<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"
>
...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:portType[@name = 'DataStaging']"
>
<jxb:javadoc>
<![CDATA[Name of Provider interface class for JAX-WS DataStagingService.]]>
</jxb:javadoc>
<class name="DataStagingService2"/>
</bindings>
...
</bindings>
Here, I'm telling the wsimport Ant task that I want the name of the SEI interface class it produces to be DataStagingService2. The wsdlLocation attribute gives the location of the WSDL file to process. This location is relative to where the binding declaration file is. I have it in the same directory as the WSDL file, so there is no path preceding it. The XPath expression selects the
portType element in the WSDL, which is where the name of the generated interface class comes from, by default.
You'll find the resulting services.datastaging.DataStaging2.java file in the WebContent/WEB-INF/lib/DataStagingService2_wsdl.jar file.
You can also use the class binding declaration to control the name of the skeleton Java source file, which is generated by the wsimport Ant task. This happens when the wsdlc Ant task is executed. This is the same class binding declaration that is used for other things, so don't be confused by that.
I put the class binding declaration to specify the name of the skeleton Java source file in the etc/server-jaxws.xbd file. Here's an extract showing what it looks like:
<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"
>
...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:service[@name = 'DataStagingService']"
>
<jxb:javadoc>
<![CDATA[Name of skeleton SEI class for JAX-WS DataStagingService.]]>
</jxb:javadoc>
<class name="DataStagingPortTypeImpl"/>
</bindings>
...
</bindings>
The bold typeface denotes the salient points. They tell the wsimport Ant task that you want the name of the skeleton class to be DataStagingPortTypeImpl. If you didn't have this binding declaration,
the name of the generated skeleton class would come from the value assigned to the name attribute of the <service> element in the WSDL.
Unfortunately, doing this didn't produce the desired outcome. The problems were:
The Java package name of the generated DataStagingPortTypeImpl class came out as
com.acmeworld.irad.services.datastaging, not services.datastaging. I tried using a " <package>services.datastaging</package> binding declaration, as well as one tied to a <jaxws:bindings> element with a node="wsdl:definitions" attribute. Neither provided the desired results.
DataStagingPortTypeImpl also becomes the name of the JAX-WS class that extends javax.xml.ws.Service. This is a class used by the service consumer, so I "let it slide" because I was on the service provider side.
If you also specify a method binding declaration to change Web service operation names, they are not propagated to the DataStagingPortTypeImpl class that gets generated in #1 above. It looks
like changes made with the parameter binding declaration don't get propagated either.
I think all of these anomalies are being caused by a bug in a class used with either the wsdlc or wsimport Ant tasks. There ended up being quite a few "side effects" to these anomalies, so as a workaround I chose to use Ant <replace> tasks on the skeleton SEI Java source that was generated.
Note: BEA support cases were filed to get the above issues "permanently resolved" in a WebLogic Server 10 patch or a future service pack.
The method binding declaration lets you control method names in code that is generated. One of the method names you can change is the getter for the proxy class in the generated Java source that extends javax.xml.ws.Service. Here's the associated extract from the etc/client-jaxws.xbd file. It appears in the etc/server-jaxws.xbd file as well:
<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"
>
...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:service[@name = 'DataStagingService']/wsdl:port[@name = 'DataStagingServicePort']"
>
<jxb:javadoc>
<![CDATA[Returns proxy object used as the Dynamic Proxy client API when invoking Web service operations on the DataStagingService Web service.]]>
</jxb:javadoc>
<method name="getDataStagingPort"/>
</bindings>
... </bindings>
Here I change the getter method name from getDataStagingServicePort (the default name) to
getDataStagingPort. You'll find the results in the test.consumers.datastaging.standalone.jaxws.DataStagingService.java
file, which is in the lib/UC-01Client.jar file.
You can also change the method names used for Web service operations:
<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"
>
...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:portType[@name='DataStaging']/wsdl:operation[@name='dataStaging']"
>
<jxb:javadoc>
<![CDATA[Sends URIs of resources to be staged]]>
</jxb:javadoc>
<method name="sendInputURIs"/>
</bindings>
...
</bindings>
Here I use a method binding declaration to change the name of the dataStaging Web service operation to
sendInputURIs. You'll find the results in the test.consumers.datastaging.standalone.jaxws.DataStaging.java
file, which is in the lib/UC-01Client.jar file.
The parameter binding declaration allows you to control the parameter names used in the methods of the skeleton SEI class. It uses:
A part attribute containing the XPath expression used to locate the parameter name to change.
The element attribute for the <part> element selected in the WSDL.
A name attribute to specify the new name for the parameter.
Here's the associated extract from the etc/server-jaxws.xbd file:
<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"
>
...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="http://services.irad.acmeworld.com/datastaging"
node="wsdl:definitions/wsdl:portType[@name='DataStaging']/wsdl:operation[@name='dataStaging']"
>
<jxb:javadoc>
<![CDATA[Input parameter for the dataStaging method.]]>
</jxb:javadoc>
<parameter
part="wsdl:definitions/wsdl:message[@name='dataStaging']/wsdl:part[@name='parameters']"
element="tns:dataStaging"
name="inputURIs"
/>
</bindings>
...
</bindings>
Earlier, I used a class binding declaration to change the method name from dataStaging to sendInputURIs. Here, I'm trying to use a parameter binding declaration to change the
parameter name from parameters to inputURIs. It didn't work, and the reason why appears to be because of the following important discovery:
The parameter binding declaration doesn't work if you also have a <enableWrapperStyle>true</enableWrapperStyle> binding declaration in the file.
It turns out that using the <enableWrapperStyle>true< enableWrapperStyle> binding declaration "automagically" results in the parameter name being changed to inputURIs. I decided to use
<enableWrapperStyle>false</enableWrapperStyle> on the service consumer side instead. That way I could at least demonstrate this parameters binding declaration.
The class binding declaration has yet another use: allowing you to control the name of exception classes used on methods in the skeleton SEI class. Here's the associated extract from the etc/server-jaxws.xbd file:
<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"
>
...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:portType[@name='DataStaging']/wsdl:operation[@name='dataStaging']/wsdl:fault[@name='JAXWSArticleException']"
>
<jxb:javadoc>
<![CDATA[General purpose exception for JAX-WS DataStagingService.]]>
</jxb:javadoc>
<class name="DataStagingServiceException"/>
</bindings>
...
</bindings>
This will cause a DataStagingServiceException class to be generated. It will be placed in the services.datastaging directory inside the WebContent/WEB-INF/lib/DataStagingService2_wsdl.jar file.
The JAX-WS specification defines two paradigms for writing asynchronous clients:
Polling This paradigm uses polling to determine if the response is available. The return type from the invocation of the operationAsync method is an instance of the javax.xml.ws.Response object. This javax.xml.ws.Response object contains methods that allow you to:
Callback In this paradigm, the client provides a callback handler to accept and process the inbound response object. This callback handler needs to implement javax.xml.ws.AsyncHandler, which has
a single void handleResponse(Response) callback method. javax.xml.ws.AsyncHandler extends javax.xml.ws.Response, but you really only need to use the get() method.
Both paradigms allow the JAX-WS client to continue doing things while the request is being processed at the service provider. Here's an extract from our etc/client-jaxws.xbd file, which shows how to specify the <enableAsyncMapping> binding declaration:
<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"
>
...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions/wsdl:portType[@name='DataStaging']/wsdl:operation[@name='dataStaging']"
>
<enableAsyncMapping>true</enableAsyncMapping>
</bindings>
...
</bindings>
This generates only an asynchronous version of the dataStaging method. If you want all the methods to have asynchronous versions, move the <enableAsyncMapping>true</enableAsyncMapping> to where the
first ... is. The asynchronous methods will be in the test.consumers.datastaging.standalone.jaxws.DataStaging.java file, which is JARed up inside the lib/UC-01Client.jar file.
|
The <javaee:handler-chains> binding declaration allows you to specify that JSR-181 (Web Services Metadata for the Java Platform) artifacts be generated. It will:
javax.jws.HandlerChain annotation in code that is generated.Here's an extract of the <javaee:handler-chains> binding declaration I used on the service provider side:
<bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns="http://java.sun.com/xml/ns/jaxws"
wsdlLocation="DataStagingService2.wsdl"
>
...
<bindings
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
node="wsdl:definitions"
>
<javaee:handler-chains xmlns:javaee="http://java.sun.com/xml/ns/javaee">
<javaee:handler-chain>
<javaee:handler>
<javaee:handler-name>VendorSOAPHandler</javaee:handler-name>
<javaee:handler-class>services.datastaging.VendorSOAPHandler</javaee:handler-class>
</javaee:handler>
</javaee:handler-chain>
</javaee:handler-chains>
</bindings>
...
</bindings>
Writing the JAX-WS handler was a rather involved process, so I'll skip discussing it in this article. The only thing I'll point out is that the VendorSOAPHandler class processes a SOAP header, which was created by a service consumer side JAX-WS handler. If you're interested in in-depth information on how to write JAX-WS handlers, you should check out Young Yang's "Get a handle on the JAX-WS
API's handler framework" article.
Until now, I've focused primarily on the binding declarations file and the things you can do in it. Now I'm going to switch it up a little bit and look at some service consumer and service provider code that:
Was generated during the running of BEA's wsdlc Ant task, or
Uses the JAX-WS artifacts generated during the running of BEA's wsdlc Ant task.
I've done a complete 180 from the service provider code used in the first article. The key differences are:
I switched from the "Start from Java" to the "Start from WSDL" programming model.
I added a binding declaration to change the name of the Web service operation from dataStaging to sendInputURIs.
I added a binding declaration that causes wrapper style types to be used in the skeleton SEI class that's generated.
I added a binding declaration that changes the name of the generated SEI interface class to DataStagingService2.
I added a binding declaration to control the name of a new Exception class
(DataStagingServiceException) I added.
I added a JAX-WS SOAP Handler to process the Vendor SOAP Header added by a service consumer-side JAX-WS SOAP Handler.
The skeleton SEI class generated by BEA's wsdlc Ant task is so small that I decided to include it here in its totality:
package services.datastaging;
import javax.jws.WebService;
import javax.xml.ws.BindingType;
import javax.jws.HandlerChain;
/**
* services.datastaging.DataStagingServiceImpl class implements web service endpoint interface services.datastaging.DataStagingService2
*/
@WebService(
portName="DataStagingServicePort",
serviceName="DataStagingService",
targetNamespace="http://services.irad.acmeworld.com/datastaging",
endpointInterface="services.datastaging.DataStagingService2",
wsdlLocation="/wsdls/DataStagingService2.wsdl"
)
@BindingType(value="http://schemas.xmlsoap.org/wsdl/soap/http")
@HandlerChain(
file="jar:file:WebContent/WEB-INF/lib/DataStagingService2_wsdl.jar!/services/datastaging/DataStagingService2_handler.xml"
)
public class DataStagingServiceImpl implements services.datastaging.DataStagingService2
{
public DataStagingServiceImpl()
{
}
public com.acmeworld.irad.services.datastaging.DataStagingResponse.OutputURIs sendInputURIs(com.acmeworld.irad.services.datastaging.DataStaging.InputURIs inputURIs)
throws services.datastaging.DataStagingServiceException
{
//replace with your impl here
return null;
}
}
This skeleton SEI class will be overwritten every time you run BEA's wsdlc Ant task, so you need to guard against code losses resulting from running it accidentally. The safest way to do this is to make periodic backup copies of it. I also combat this by removing the run-wsdlc Ant target from all the depends attributes appearing in the build.xml file.
I used the Dispatch client API approach in the JAX-WS client code for the first article. In this article, I switch to the Dynamic Proxy client API approach. The Dynamic Proxy client API involves using a service proxy class that was generated by BEA's clientgen Ant task. That Ant task calls Sun's wsimport Ant task internally.
Our etc/client-jaxws.jbd file contains the binding declarations I use on the service consumer side. It includes binding declarations to:
I'll show you the code for doing the asynchronous method invocation first:
... DataStagingService service = new DataStagingService(); service.setExecutor(Executors.newSingleThreadExecutor()); DataStaging port = service.getDataStagingServicePort(); ...
This code extract shows that a single-threaded threading model is used to invoke the void handleResponse(Response) callback method. The setExecutor() method on the client's java.xml.ws.Service instance is used to designate this. Here's a code extract of the class that implements the javax.xml.ws.AsyncHandler interface:
... private class ClientCallback implements AsyncHandler{ public void handleResponse(Response response) { try { log("handleResponse(Response )", (new StringBuffer()).append("Callback method was invoked.").toString()); printDataStagingResponse(response.get()); } catch (Exception e) { e.printStackTrace(); } } } ...
These tutorials reveal that you can do a lot of useful things with binding declarations. They also provide lots of details about how to use them with WebLogic Server 10. The reason for providing this level of detail was twofold:
I've seen quite a few "unanswered" posts on the BEA NewsWeb newsgroup, where individuals are seeking assistance with doing JAX-WS and JAXB on WebLogic Server 10. I used this article to answer some of these, plus did a little "knowledge transfer" on JAX-WS development with WebLogic Server 10.
I wanted to provide something that could function as a "complementary reference" to the documentation provided by Sun on this topic.
This level of detail should reduce the number of Google searches you need to do, when you encounter issues while using the JAX-WS implementation in WebLogic Server 10.
Using the Table of Tutorials is the recommended way to go directly to the use case you need to implement.
JAX-WS binding declarations provide you with a powerful mechanism for influencing the artifacts generated by Sun's wscompile and wsimport Ant tasks. These binding declarations can either be embedded in a WSDL or
placed in a file containing an XML document that conforms to the XML Schema with the
http://java.sun.com/xml/ns/jaxws namespace. Using a file is the recommended method.
The WebLogic Server 10 Web services stack provides BEA Ant tasks (that is, clientgen, wsdlc, and jwsc) that call the above-mentioned Sun Ant tasks internally. They provide a
<binding child element for you to specify the JAX-WS (and/or JAXB) binding declaration file to use.
Having this kind of control is great, but it does come at a cost complexity-wise. Java EE development has a history of being perceived as "overly complex," and JAX-WS binding declarations don't do anything to change this. "Hand-coding" JAX-WS binding declarations files in a text editor is not an activity that most Java developers will find appealing and better IDE support is required.
The final article in this series will be devoted to some of the advanced capabilities in the Glassfish JAX-WS Commons project. My research revealed that the JARs from that project can be used along side the Glassfish JAX-WS 2.0 ones already being used in a WebLogic Server 10. I'll primarily be covering things like:
Using Spring beans as service implementations.
Using the Spring configuration framework to create a JAX-WS service that supports multiple binding types simultaneously. The javax.xml.ws.BindingType annotation allows you to use only one.
Creating, hosting, and invoking RESTful services on WebLogic Server 10. These are "true" RESTful services, not just some HTTP endpoint that uses the HTTP GET method and a long query string.
Creating, hosting, and invoking JSON (Java-Script Object Notation) services on WebLogic Server 10.
Creating JSON service consumers that invoke JSON services.
See you then.
The following links provide additional information on things discussed in this article:
Mike Wooten is a Sr. Principal Solutions Engineer in BEA's prestigious TSG (Technical Solutions Group). His waking hours are usually spent helping BEA customers turn their abstract technical notions/concepts, into revenue-generating solutions that exceed the capabilties offered by their competitors.
Return to Dev2Dev.