tags:

views:

1391

answers:

2

Hi All,

I have a number of JAXB beans that are directly marshalled and unmarshalled using Jersey.

E.g.

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Artifact", propOrder = {
    "artifactId",
    "artifactType",
    "contentHash"
})
@XmlSeeAlso({
    EmailArtifact.class,
    ManagedDocArtifact.class
})
@XmlRootElement(name ="Artifact")
public class Artifact {

    protected String artifactId;
    protected String artifactType;
    protected String contentHash;

...
...
...

}

If I create a GET method that returns a single artifact object. It correctly produces the XML:

<Artifact>
 <artifactId>293289392839283</artifactId>
 <artifactType>EMAIL</artifactType>
 <contentHash>2837873827322</contentHash>
</Artifact>

Here I have been able to successfully control the name of the Artifact element to have a capital "A" at the beginning.

However, I create a GET method that returns collection of artifact objects, I end up with:

<artifacts>
<Artifact>
 <artifactId>293289392839283</artifactId>
 <artifactType>EMAIL</artifactType>
 <contentHash>2837873827322</contentHash>
</Artifact>
<Artifact>
 <artifactId>293289392839283</artifactId>
 <artifactType>EMAIL</artifactType>
 <contentHash>2837873827322</contentHash>
</Artifact>
</artifacts>

As you can see the outer element for the collection has a lower case "A". In order to conform to our own internal standard I would like this to be a capital "A" - Artifacts.

I can not see where this is possible to define within JAXB, is it actually the Jersey framework that is controlling this?

Can we control of the element name generated for collections?

Many thanks,

James

+2  A: 

Try using @XmlElementWrapper which supports the name attribute:

@XmlElementWrapper(name="ELEMENTS")
@XmlElement(name="ELEMENT")
protected final List<String> elements = new LinkedList<String>();

Will procude

<ELEMENTS>
  <ELEMENT>one</ELEMENT>
  <ELEMENT>two</ELEMENT>
  ...
</ELEMENTS>

See the JAXB Tutorial for this feature.

java.is.for.desktop
Hi there, unfortunately I'm aware of the XmlElementWrapper but it does not apply to my use case. Within Jersey you can produce and consume collections of JAXB beans. e.g. public List<MyBean> getMyBeansYou can't use XmlElementWrapper to annotate the MyBean class - you can only use this annotation against a property of the class e.g. a collection within the class. So this would be no good. There is a solution in that I could use a new class which contains a collection - but to be honest that's creating a class within the design that's not really required.
jallch
The good thing about XML is: it can be transformed in 1000 ways ;)You could use **XSLT** or **DOM**.
java.is.for.desktop
+2  A: 

Hi All,

OK - I have had an update from the Java Jersey community leader - Paul Sandoz. This is currently an open issue with the Jersey framework and just something that we will have to workaround or accept until it is fixed in a future update.

The workaround as explained in one of the comments above is to introduce a new class for each web service method that returns a collection (e.g. List) of JAXB annotated beans. This class is effectively a class that contains just one member - a List of the JAXB beans. Instead of returning the List in the web service method we return the special class instead. Because we have control over the name of the new class in the XML, e.g. @XmlRootElement(name="Artifacts") we can workaround the problem in the short term.

Hope this helps.

Regards,

James

jallch