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