Hi,
No problems and thanks for raising this issue on this list - I reckon we've
ended up adding a pretty useful feature (optional JAXBElement wrapping) to
the default JAXBElementProvider wich can be generally useful.
By the way, that workaround I mentioned is a bit hacky though doable - but a
simpler workaround would be to create a custom JAXBElementProvider which
extends the default one and overrides
protected void marshal(Object obj, Class<?> cls, Type genericType,
String enc, OutputStream os, MediaType mt)
the way it's done currently on the trunk, perhaps explicitly checking for
BaseType
cheers, Sergey
Qzpmwo wrote:
>
> Hi Sergey,
>
> I'm really impressed with your help!
>
> Thanks a lot
> --- Alex
>
> On Tue, Jul 21, 2009 at 12:36 PM, Sergey Beryozkin <
> [email protected]> wrote:
>
>>
>> Hi
>>
>> OK, it's done now on the trunk/2.2.3-SNAPSHOT. Hopefully a 2.2.3 release
>> will be done next week.
>> You'd just need to explicitly register JAXBElementProvider and set a list
>> property with a list of class names whose instances need to be wrapped
>> prior
>> to serialization, here's a fragment :
>>
>> <beans xmlns:util="http://www.springframework.org/schema/util"
>> xsi:schemaLocation="http://www.springframework.org/schema/beans
>> http://www.springframework.org/schema/beans/spring-beans.xsd
>> http://www.springframework.org/schema/util
>> http://www.springframework.org/schema/util/spring-util-2.0.xsd ...">
>>
>> <util:list id="jaxbElementClassNames">
>> <value>org.apache.cxf.systest.jaxrs.BaseType</value>
>> </util:list>
>>
>> <jaxrs:server>
>> <jaxrs:providers>
>> <ref bean="jaxbProvider"/>
>> <jaxrs:providers>
>> </jaxrs:server>
>>
>> <bean id="jaxbProvider"
>> class="org.apache.cxf.jaxrs.provider.JAXBElementProvider">
>> <property name="jaxbElementClassNames" ref="jaxbElementClassNames"/>
>> </bean>
>> </beans>
>>
>> In meantime, till the release is done, you can register a response JAXRS
>> filter and wrap the BaseType instance in JAXBElement, it is a bit hacky,
>> but
>> you can do something like
>>
>> public class JAXBElementWrapper implements ResponseHandler {
>> private final static Method m;
>> static {
>> m = SomeClass.getMethod("get", new Class[0]);
>> }
>>
>>
>> public Response handleResponse(Message m, OperationResourceInfo ori,
>> Response response) {
>>
>> if (BaseType.class == ori.getMethodToInvoke().getReturnType()) {
>> // this is a hacky bit
>> OperationResourceInfo ori2 = new OperationResourceInfo(m,
>> ori.getAnnotatedMethod(), ori.getClassResourceInfo());
>> message.getExchange().put(OperationResourceInfo.class, ori2);
>> Object instance =
>> MessageContentsList.getContentsList(message).get(0);
>> // convert as Wolfgang suggested or check JAXBElementProvider
>> source
>> JAXBElement el = convertToJAXBElement(instance);
>> message.setContent(new MessageContentsList(el));
>> }
>> return null;
>> }
>>
>> private static class SomeClass {
>> public JAXBElement<BaseType> get();
>> }
>> }
>>
>>
>> Also, Wolfgang suggested some additional schema updates - not sure if it
>> will work for you
>>
>> thanks, Sergey
>>
>>
>> Qzpmwo wrote:
>> >
>> > Hi,
>> >
>> > I'm having a strange problem with CXF RESTful service marsahlling base
>> and
>> > derived xsd types.
>> >
>> > XSD:
>> >
>> > <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
>> > xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
>> > xmlns="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>> > targetNamespace="http://www.cisco.com/dms/xml/ns/dsmCommonService"
>> > elementFormDefault="unqualified" jaxb:version="2.0">
>> >
>> > <xs:complexType name="BaseType">
>> > <xs:sequence>
>> > </xs:sequence>
>> > </xs:complexType>
>> >
>> > <xs:complexType name="DerivedType">
>> > <xs:complexContent>
>> > <xs:extension base="BaseType">
>> > <xs:sequence>
>> > </xs:sequence>
>> > </xs:extension>
>> > </xs:complexContent>
>> > </xs:complexType>
>> >
>> > <xs:complexType name="ListType">
>> > <xs:sequence>
>> > <xs:element name="item" type="BaseType" minOccurs="0"
>> > maxOccurs="unbounded" />
>> > </xs:sequence>
>> > </xs:complexType>
>> >
>> > <xs:element name="base" type="BaseType" />
>> > <xs:element name="derived" type="DerivedType" />
>> > <xs:element name="list" type="ListType" />
>> >
>> > </xs:schema>
>> >
>> > xjc has been used to jenerate java code from xsd. After that:
>> >
>> > 1) @XmlSeeAlso pointing to DerivedType class and @XmlRootElement
>> > annotations have been added to BaseType java class code
>> > 2) @XmlRootElement has been added to DerivedType java class code
>> > 3) @XmlRootElement has been added to ListType java class code
>> >
>> > When my CXF rest service returns list of the Derived objects it
>> produces
>> > xml
>> > correctly:
>> >
>> > <list>
>> > <base xsi:type="DerivedType">...</base>
>> > ...
>> > <base xsi:type="DerivedType">...</base>
>> > </list>
>> >
>> > But when I'm requesting 1 instance of the Derived object XML is wrong
>> (as
>> > I
>> > understand)
>> >
>> > <derived>...</derived>
>> >
>> > Since I did not specify substitution group in my opinion xml should be
>> > like
>> > in list:
>> >
>> > <base xsi:type="DerivedType">...</base>
>> >
>> > Could you please clarify the issue for me and may be help me to solve
>> this
>> > problem.
>> >
>> > Forgot to mention that I'm using CXF 2.2
>> >
>> > Thanks in advance
>> > --- Karen
>> >
>> >
>>
>> --
>> View this message in context:
>> http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24591197.html
>> Sent from the cxf-user mailing list archive at Nabble.com.
>>
>>
>
>
--
View this message in context:
http://www.nabble.com/Possible-problem-with-JAXB-marshalling-tp24549727p24593397.html
Sent from the cxf-user mailing list archive at Nabble.com.