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 :
By default, JAXB creates nested classes when it can. This is caused by
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
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.
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.
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
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 !
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.