Mapping XML dateTime to Date and other customizations
When working with XML schemas, I often find the generated classes ugly by default. That’s why I always customize the generated classes. Although you’ll find many good tutorials and articles about this on the net, I just wanted to show you the basic customizations I usually apply.
For this example I’ve used a WSDL emitted by a belgian government institution since I had to implement a client for it a few years ago.
It is available at this address : http://www.rsvz-inasti.fgov.be/schemas/WS/Loopbaan.
Be also warned that customization like this is mostly a matter of personal taste !
The hideous XMLGregorianCalendar
I really hate the way Java handles date and time - at least before JDK 8 and JSR-310 - especially the Calendar family.
So the first thing I do is to get rid of XMLGregorianCalendar
and only use a java.util.Date
. By the way, I often use CXF as JAX-WS implementation so I tend to use the facilities given by this framework.
You can find the class DataTypeAdapter
by adding a tiny dependency in your project :
Separate classes
By default, JAXB creates nested classes when it can. This is caused by
from bindingschema_2_0.xsd
.
In my example, it produces 75 files.
I don’t really like nested classes, I prefer separate classes. One can argue in favor of them with the encapsulation argument, for example. That’s true, but I won’t debate this in here. As I said, it’s mostly a matter of aesthetic preferences in this case.
So, let’s change the localScoping attribute of globalBindings element :
After that I get 87 files :
$ find . -type f -iname *.java |wc -l 87
As you can see, the number of classes has slightly raised. There are no nested classes anymore.
Class name customization
Sometimes when creating separate classes it happens some class name clashing : two generated classes have the same name.
I have to admit that I’ve encountered this only once so far; it is clear that the cause is the localScoping
attribute set to topLevel
.
In order to avoid that, you have to define some XPath expression in order to isolate the XML data type that will be converted to a Java class and assign it a name you’ve defined, like this :
Here we have two datatypes with the same name, but with different scopes, so they don’t clash in the schema. So if we let localScoping=nested
, the generated classes will be nested. No problem then. But here it’s a bit different, JAXB tries to create two classes with the same name (Activities
for instance) and fails.
Luckily we instructed JAXB to create two different classes by telling it with a XPath expression.
WSDL customization
Parameter types
As stated before the schemas are imported from a WSDL. When generating classes for the latter we can also do some customization.
For this, you have to use a JAX-WS binding file. I’ll show you a very simple one shortly.
A customization I really always do for SOAP webservices is to disable the wrapper style, enabled by default.
If enabled, it gives you something like this - I’ve removed nearly all annotations for readability :
This method has void
as return type. So you’re tempted to think that it doesn’t return anything. That’s a bit misleading : the first parameter, which is a Holder
holds the response too.
When you look a bit closer, you see the @WebParam(mode = WebParam.Mode.INOUT)
annotation. The meaning should be pretty obvious, it just tells that the
As I said it’s misleading, so I prefer the version generated with
which looks like this :
I really prefer the second version. By the way, if someone has technical arguments in favor of the first version, please let me know.
Package name
I like clean packages names, no underscores, least numbers as possible, …
But by default the generated package names are guessed from the XML namespaces where the datatypes live. That’s a sane default after all, but that often leads to horrible package names, like be.fgov.rsvz_inasti.schemas.ws.loopbaan.v1
or org.w3._2001.xmlschema
. Huh !
That’s why I use custom name mapping between namespaces and packages. The cxf-codegen-plugin
, used from Maven, have an option so you can do this easily :
That’s better !
Conclusion
Here I showed you some basic customizations I tend to use everytime I deal with JAXB and JAX-WS.
Of course there many other ways to customize the way classes are generated, either for XML schemas or WSDL’s, that’s why I give you some links hereafter.
I hope it will help you generating more appealing classes.