You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Nikolay Aleksiev <ni...@alexiev.net> on 2012/05/22 17:52:04 UTC
Missing xsi:type in derrived types
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
Re: Missing xsi:type in derrived types
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
On 08/06/12 08:53, Nikolay Aleksiev wrote:
> Hi Sergey,
>
> I test the fix both in 2.4.7 and 2.6.1 and everything is OK!
>
Great, thanks for your help in getting this fixed too
Cheers, Sergey
> Thank you very much for the support!
>
> Cheers,
> Nikolay
>
> On 05/29/2012 08:46 PM, Sergey Beryozkin wrote:
>> Hi Nikolay,
>>
>> I fixed it on all the branches except 2.3.x as the changes were a bit
>> sensitive
>>
>> Thanks for the help
>> Sergey
>>
>> https://issues.apache.org/jira/browse/CXF-4349
>>
>> On 29/05/12 08:25, Nikolay Aleksiev wrote:
>>> Hi Sergey,
>>>
>>> I tried your test and created a test app. There are two issues I
>>> noticed:
>>>
>>> 1. In 2.4.7 JAXBElementProvider is not generic. Anyway the test works
>>> with the one available.
>>>
>>> 2. The actual call to writeTo is:
>>>
>>> provider.writeTo(b, Item.class, Base.class, ...);
>>>
>>> The second param value is retrieved in
>>> JAXRSOutInterceptor.getRawResponseClass and it returns the real class of
>>> the object.
>>>
>>> When the test is run with /provider.writeTo(b, Item.class, Base.class,
>>> ...); /it behaves exactly as in the container and returns:
>>>
>>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>>> <base/>
>>>
>>> Thanks for the help!
>>> Cheers,
>>> Nikolay
>>>
>>>
>>> On 05/28/2012 08:03 PM, Sergey Beryozkin wrote:
>>>> Hi
>>>>
>>>> The following:
>>>>
>>>> @Test
>>>> public void testWriteDerivedType() throws Exception {
>>>> JAXBElementProvider<Base> provider = new JAXBElementProvider<Base>();
>>>>
>>>> provider.setJaxbElementClassNames(Collections.singletonList(Base.class.getName()));
>>>>
>>>>
>>>> Base b = new Item();
>>>>
>>>> ByteArrayOutputStream bos = new ByteArrayOutputStream();
>>>> provider.writeTo(b, Base.class, Base.class,
>>>> new Annotation[0], MediaType.TEXT_XML_TYPE, new MetadataMap<String,
>>>> Object>(), bos);
>>>> System.out.println(bos.toString());
>>>> }
>>>>
>>>> public static abstract class Base0 {
>>>> }
>>>>
>>>> @XmlType(name = "content")
>>>> @XmlRootElement
>>>> @XmlSeeAlso({ Item.class })
>>>> public static abstract class Base extends Base0 {
>>>> }
>>>>
>>>> @XmlRootElement(name = "content")
>>>> @XmlType(name = "item")
>>>> public static class Item extends Base {
>>>> }
>>>>
>>>> produces
>>>>
>>>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>>>> <base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>>> xsi:type="item"/>
>>>>
>>>> You are confirming that the code branch to do with wrapping the
>>>> response type in JAXBElement is executed, so I'm not really sure what
>>>> is missing in your case.
>>>>
>>>> Perhaps some of JAXB annotations are not even visible to
>>>> JAXBElementProvider and hence to JAXB Marshaller ? Are you working
>>>> with WebSphere or WebLogic ? I vaguely remember that someone had few
>>>> problems with getting the JAX-RS annotations recognized in one of
>>>> those containers.
>>>>
>>>> If you can provider a sample test project or just a war then it would
>>>> help me to investigate further.
>>>>
>>>> Please keep me updated,
>>>>
>>>> thanks, Sergey
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On 28/05/12 16:12, Nikolay Aleksiev wrote:
>>>>> 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
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>
>>
Re: Missing xsi:type in derrived types
Posted by Nikolay Aleksiev <ni...@alexiev.net>.
Hi Sergey,
I test the fix both in 2.4.7 and 2.6.1 and everything is OK!
Thank you very much for the support!
Cheers,
Nikolay
On 05/29/2012 08:46 PM, Sergey Beryozkin wrote:
> Hi Nikolay,
>
> I fixed it on all the branches except 2.3.x as the changes were a bit
> sensitive
>
> Thanks for the help
> Sergey
>
> https://issues.apache.org/jira/browse/CXF-4349
>
> On 29/05/12 08:25, Nikolay Aleksiev wrote:
>> Hi Sergey,
>>
>> I tried your test and created a test app. There are two issues I
>> noticed:
>>
>> 1. In 2.4.7 JAXBElementProvider is not generic. Anyway the test works
>> with the one available.
>>
>> 2. The actual call to writeTo is:
>>
>> provider.writeTo(b, Item.class, Base.class, ...);
>>
>> The second param value is retrieved in
>> JAXRSOutInterceptor.getRawResponseClass and it returns the real class of
>> the object.
>>
>> When the test is run with /provider.writeTo(b, Item.class, Base.class,
>> ...); /it behaves exactly as in the container and returns:
>>
>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>> <base/>
>>
>> Thanks for the help!
>> Cheers,
>> Nikolay
>>
>>
>> On 05/28/2012 08:03 PM, Sergey Beryozkin wrote:
>>> Hi
>>>
>>> The following:
>>>
>>> @Test
>>> public void testWriteDerivedType() throws Exception {
>>> JAXBElementProvider<Base> provider = new JAXBElementProvider<Base>();
>>>
>>> provider.setJaxbElementClassNames(Collections.singletonList(Base.class.getName()));
>>>
>>>
>>> Base b = new Item();
>>>
>>> ByteArrayOutputStream bos = new ByteArrayOutputStream();
>>> provider.writeTo(b, Base.class, Base.class,
>>> new Annotation[0], MediaType.TEXT_XML_TYPE, new MetadataMap<String,
>>> Object>(), bos);
>>> System.out.println(bos.toString());
>>> }
>>>
>>> public static abstract class Base0 {
>>> }
>>>
>>> @XmlType(name = "content")
>>> @XmlRootElement
>>> @XmlSeeAlso({ Item.class })
>>> public static abstract class Base extends Base0 {
>>> }
>>>
>>> @XmlRootElement(name = "content")
>>> @XmlType(name = "item")
>>> public static class Item extends Base {
>>> }
>>>
>>> produces
>>>
>>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>>> <base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>>> xsi:type="item"/>
>>>
>>> You are confirming that the code branch to do with wrapping the
>>> response type in JAXBElement is executed, so I'm not really sure what
>>> is missing in your case.
>>>
>>> Perhaps some of JAXB annotations are not even visible to
>>> JAXBElementProvider and hence to JAXB Marshaller ? Are you working
>>> with WebSphere or WebLogic ? I vaguely remember that someone had few
>>> problems with getting the JAX-RS annotations recognized in one of
>>> those containers.
>>>
>>> If you can provider a sample test project or just a war then it would
>>> help me to investigate further.
>>>
>>> Please keep me updated,
>>>
>>> thanks, Sergey
>>>
>>>
>>>
>>>
>>>
>>> On 28/05/12 16:12, Nikolay Aleksiev wrote:
>>>> 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
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>
>>>
>
>
Re: Missing xsi:type in derrived types
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi Nikolay,
I fixed it on all the branches except 2.3.x as the changes were a bit
sensitive
Thanks for the help
Sergey
https://issues.apache.org/jira/browse/CXF-4349
On 29/05/12 08:25, Nikolay Aleksiev wrote:
> Hi Sergey,
>
> I tried your test and created a test app. There are two issues I noticed:
>
> 1. In 2.4.7 JAXBElementProvider is not generic. Anyway the test works
> with the one available.
>
> 2. The actual call to writeTo is:
>
> provider.writeTo(b, Item.class, Base.class, ...);
>
> The second param value is retrieved in
> JAXRSOutInterceptor.getRawResponseClass and it returns the real class of
> the object.
>
> When the test is run with /provider.writeTo(b, Item.class, Base.class,
> ...); /it behaves exactly as in the container and returns:
>
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <base/>
>
> Thanks for the help!
> Cheers,
> Nikolay
>
>
> On 05/28/2012 08:03 PM, Sergey Beryozkin wrote:
>> Hi
>>
>> The following:
>>
>> @Test
>> public void testWriteDerivedType() throws Exception {
>> JAXBElementProvider<Base> provider = new JAXBElementProvider<Base>();
>>
>> provider.setJaxbElementClassNames(Collections.singletonList(Base.class.getName()));
>>
>> Base b = new Item();
>>
>> ByteArrayOutputStream bos = new ByteArrayOutputStream();
>> provider.writeTo(b, Base.class, Base.class,
>> new Annotation[0], MediaType.TEXT_XML_TYPE, new MetadataMap<String,
>> Object>(), bos);
>> System.out.println(bos.toString());
>> }
>>
>> public static abstract class Base0 {
>> }
>>
>> @XmlType(name = "content")
>> @XmlRootElement
>> @XmlSeeAlso({ Item.class })
>> public static abstract class Base extends Base0 {
>> }
>>
>> @XmlRootElement(name = "content")
>> @XmlType(name = "item")
>> public static class Item extends Base {
>> }
>>
>> produces
>>
>> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
>> <base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>> xsi:type="item"/>
>>
>> You are confirming that the code branch to do with wrapping the
>> response type in JAXBElement is executed, so I'm not really sure what
>> is missing in your case.
>>
>> Perhaps some of JAXB annotations are not even visible to
>> JAXBElementProvider and hence to JAXB Marshaller ? Are you working
>> with WebSphere or WebLogic ? I vaguely remember that someone had few
>> problems with getting the JAX-RS annotations recognized in one of
>> those containers.
>>
>> If you can provider a sample test project or just a war then it would
>> help me to investigate further.
>>
>> Please keep me updated,
>>
>> thanks, Sergey
>>
>>
>>
>>
>>
>> On 28/05/12 16:12, Nikolay Aleksiev wrote:
>>> 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
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>
>>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: Missing xsi:type in derrived types
Posted by Nikolay Aleksiev <ni...@alexiev.net>.
Hi Sergey,
I tried your test and created a test app. There are two issues I noticed:
1. In 2.4.7 JAXBElementProvider is not generic. Anyway the test works
with the one available.
2. The actual call to writeTo is:
provider.writeTo(b, Item.class, Base.class, ...);
The second param value is retrieved in
JAXRSOutInterceptor.getRawResponseClass and it returns the real class of
the object.
When the test is run with /provider.writeTo(b, Item.class, Base.class,
...); /it behaves exactly as in the container and returns:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<base/>
Thanks for the help!
Cheers,
Nikolay
On 05/28/2012 08:03 PM, Sergey Beryozkin wrote:
> Hi
>
> The following:
>
> @Test
> public void testWriteDerivedType() throws Exception {
> JAXBElementProvider<Base> provider = new
> JAXBElementProvider<Base>();
>
> provider.setJaxbElementClassNames(Collections.singletonList(Base.class.getName()));
>
> Base b = new Item();
>
> ByteArrayOutputStream bos = new ByteArrayOutputStream();
> provider.writeTo(b, Base.class, Base.class,
> new Annotation[0], MediaType.TEXT_XML_TYPE, new
> MetadataMap<String, Object>(), bos);
> System.out.println(bos.toString());
> }
>
> public static abstract class Base0 {
> }
>
> @XmlType(name = "content")
> @XmlRootElement
> @XmlSeeAlso({ Item.class })
> public static abstract class Base extends Base0 {
> }
>
> @XmlRootElement(name = "content")
> @XmlType(name = "item")
> public static class Item extends Base {
> }
>
> produces
>
> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
> <base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> xsi:type="item"/>
>
> You are confirming that the code branch to do with wrapping the
> response type in JAXBElement is executed, so I'm not really sure what
> is missing in your case.
>
> Perhaps some of JAXB annotations are not even visible to
> JAXBElementProvider and hence to JAXB Marshaller ? Are you working
> with WebSphere or WebLogic ? I vaguely remember that someone had few
> problems with getting the JAX-RS annotations recognized in one of
> those containers.
>
> If you can provider a sample test project or just a war then it would
> help me to investigate further.
>
> Please keep me updated,
>
> thanks, Sergey
>
>
>
>
>
> On 28/05/12 16:12, Nikolay Aleksiev wrote:
>> 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
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>
>>>
>
>
Re: Missing xsi:type in derrived types
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
The following:
@Test
public void testWriteDerivedType() throws Exception {
JAXBElementProvider<Base> provider = new
JAXBElementProvider<Base>();
provider.setJaxbElementClassNames(Collections.singletonList(Base.class.getName()));
Base b = new Item();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
provider.writeTo(b, Base.class, Base.class,
new Annotation[0], MediaType.TEXT_XML_TYPE, new
MetadataMap<String, Object>(), bos);
System.out.println(bos.toString());
}
public static abstract class Base0 {
}
@XmlType(name = "content")
@XmlRootElement
@XmlSeeAlso({ Item.class })
public static abstract class Base extends Base0 {
}
@XmlRootElement(name = "content")
@XmlType(name = "item")
public static class Item extends Base {
}
produces
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<base xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="item"/>
You are confirming that the code branch to do with wrapping the response
type in JAXBElement is executed, so I'm not really sure what is missing
in your case.
Perhaps some of JAXB annotations are not even visible to
JAXBElementProvider and hence to JAXB Marshaller ? Are you working with
WebSphere or WebLogic ? I vaguely remember that someone had few problems
with getting the JAX-RS annotations recognized in one of those containers.
If you can provider a sample test project or just a war then it would
help me to investigate further.
Please keep me updated,
thanks, Sergey
On 28/05/12 16:12, Nikolay Aleksiev wrote:
> 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
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>
>>
Re: Missing xsi:type in derrived types
Posted by Nikolay Aleksiev <ni...@alexiev.net>.
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
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>
>>>
>
>
Re: Missing xsi:type in derrived types
Posted by Sergey Beryozkin <sb...@gmail.com>.
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
>>>>>
>>>>>
>>>>>
>>>>>
>>>>
>>>>
>>
>>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: Missing xsi:type in derrived types
Posted by Nikolay Aleksiev <ni...@alexiev.net>.
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.
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
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>
>
Re: Missing xsi:type in derrived types
Posted by Nikolay Aleksiev <ni...@alexiev.net>.
Hi Sergey,
I simplified my code. Now I have only two class Base and Item (Item
extends Base). My resource method returns base and base has both
@XMLRootElement and @XMLSeeAlso({Item.class}). I added jaxb.index and
modified my config so that only Base is in JaxbElementClassNames.
And.. still no success.
Any ideas?
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
>>>>
>>>>
>>>>
>>>>
>>>
>>>
>
>
Re: Missing xsi:type in derrived types
Posted by Sergey Beryozkin <sb...@gmail.com>.
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
>>>
>>>
>>>
>>>
>>
>>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: Missing xsi:type in derrived types
Posted by Nikolay Alexiev <ni...@alexiev.net>.
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.
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
>>
>>
>>
>>
>
>
Re: Missing xsi:type in derrived types
Posted by Sergey Beryozkin <sb...@gmail.com>.
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
>
>
>
>
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com