Hi,
I'm already working with the latest 2.4.7. Here is the information:
@MappedSuperclass
@XmlType(name = "content")
@XmlRootElement
@XmlSeeAlso({ Item.class })
public abstract class Base extends OtherBase implements Comparable<Base> {
...
...
}
@Entity
@Table(name = "CONTENT")
@AttributeOverrides({
...
...
...
})
@ObjectTypeConverter(name = "charCodeToBooleanConverter", dataType =
String.class, objectType = Boolean.class, conversionValues = {
@ConversionValue(dataValue = "Y", objectValue = "TRUE"),
@ConversionValue(dataValue = "N", objectValue = "FALSE") })
@XmlRootElement(name = "content")
@XmlType(name = "item")
@Cacheable(false)
public class Item extends Base {
...
}
@WebMethod
@GET
@Path("/item/{contentType}/{id}")
@Secured("ROLE_RESTCLIENT")
public Base get(@PathParam("id") String contentId,
@PathParam("contentType") ContentType contentType)
throws WSException;
Cheers,
Nikolay
On 05/28/2012 05:44 PM, Sergey Beryozkin wrote:
Hi
On 28/05/12 15:18, Nikolay Aleksiev wrote:
Hi,
one more thing. I debugged the JAXBElementProvider. What I noticed is
that my object is converted to JAXBElement but xsi:type is still
missing.
When I create JAXB context, marshaller manually and construct a
JAXBElement, the xsi:type is added.
It seems I'm missing something, but I can't find what.
Can you try the latest 2.4.7 on the 2.4.x branch ?
Or send me the following info:
- the sample pair of Base and Base1 classes, with all the annotations
which are used on the actual classes that you work with
- sample JAX-RS method signature, example
@GET
public Base getBase() {
return new Base1();
}
Cheers, Sergey
Thanks for your help!
Regards,
Nikolay
On 05/23/2012 01:20 PM, Sergey Beryozkin wrote:
Hi Nikolay
On 23/05/12 09:16, Nikolay Alexiev wrote:
Hi Sergey,
basically - yes. I return a child of com.foo.Base and all the parents
have @XMLRootElement. The resource returns the child without xsi:type.
I don't know if this is useful, but when I return collection, the
elements in the collection have xsi:type.
Here is the code I wrote:
JAXBElementProvider<Book> provider = new JAXBElementProvider<Book>();
provider.setJaxbElementClassNames(Collections.singletonList(Book.class.getName()));
provider.setExtraClass(new Class[]{SuperBook.class});
Book is the base class, SuperBook extends it. For xsi:type to appear
one should have either @XmlSeeAlso({SuperBook.class }) on Book class or
configure the provider as in the code above.
Having a jaxb.index package resource will probably do it too.
So the jaxbElementClassNames property should only list the return
types of various resource methods and subclasses should be listed
using one of the options mentioned above.
How many base classes like Base.class do you have ? I think if one has
to list more than 3-5 base classes then it will probably make sense to
add wildcard jaxbElementClassNames property
Cheers, Sergey
Thanks,
Nikolay
On 05/23/2012 12:09 AM, Sergey Beryozkin wrote:
Hi,
So, for example, you have
com.foo.Base and com.foo.Base1 (extending com.foo.Base) with
XMLRootElement on both classes ? The resource method returns
com.foo.Base, when Base1 is returned no xsi:type is added, right ?
Cheers, Sergey
On 22/05/12 16:52, Nikolay Aleksiev wrote:
Hello,
I have a REST service which returns a com.foo.Base class. This
class is
part of a complex domain hierarchy which looks like this:
/com.foo.Base -> com.foo.Base1 -> com.foo.Base2 -> com.foo.Base3/
and
Base3 is extended by multiple Concrete implementors.
What I want to achieve is to have "xsi:type" set in the returned XML
when a concrete class instance is used. I went through the
documentation
and added "JaxbElementClassNames" to my JAXBProvider. Here is my
config:
<bean id="jaxbProvider"
class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
<property name="marshallerProperties"
ref="marshallerPropertiesMap" />
<property name="jaxbElementClassNames"
ref="myJaxbElementClassNames"/>
</bean>
<util:map id="marshallerPropertiesMap">
<entry key="jaxb.encoding">
<value type="java.lang.String">UTF-8</value>
</entry>
</util:map>
<util:list id="myJaxbElementClassNames">
<value>/com.foo.Base/</value>
<value>/com.foo.Base/1</value>
<value>/com.foo.Base/2</value>
<value>/com.foo.Base/3</value>
<value>/com.foo.Concrete1/</value>
<value>/com.foo.Concrete2/</value>
<value>/com.foo.Concrete3/</value>
<value>/com.foo.Concrete4/</value>
</util:list>
<jaxrs:server id="clientServer" address="/">
<jaxrs:providers>
<ref bean="systemExceptionMapper" />
<ref bean="jaxbProvider" />
<ref bean="jsonProvider"/>
<ref bean="followUpFilter" />
</jaxrs:providers>
...
</jaxrs:server>
The result is that the xsi:type attribute is not added. All the
concrete
classes and com.foo.Base have @XMLRootElement annotation (the other
base
ones DO NOT). @XMLSeeAlso is added in all the classes.
I'm using apache 2.4.7.
Thanks for the help. Any ideas are welcome!
Cheers,
Nikolay