Actually, another option is to add a custom JAX-RS provider which handles Order/etc using the EMF itself (which will produce XMI - though it's a complex XML indeed)
Sergey On Thu, Apr 7, 2011 at 5:21 PM, Sergey Beryozkin <[email protected]>wrote: > Hi > > Please see comments inline > > On Thu, Apr 7, 2011 at 4:55 PM, Simon Chen <[email protected]> wrote: > >> I have some new findings... >> >> My class files are generated by EMF (ecore/genmodel). > > > I guess it can help in time if CXF has an EMF binding or JAX-RS provider > > >> Thus, I have >> both Customer.class and CustomerImpl.class. The code is as simple as: >> >> @XmlRootElement(name = "Customer") >> public class CustomerImpl implements Customer { >> private String name; >> private EList<Order> orders; >> public String getName() { >> return name; >> } >> public void setName(String name) { >> this.name = name; >> } >> public Order getOrder(String name) { >> // return the order with the specified name >> return null; >> } >> public void deleteOrder(String name) { >> // remove the order with the specified name >> } >> } >> >> @XmlRootElement(name = "Order") >> public class OrderImpl implements Order { >> private String name; >> private Customer customer; >> public String getName() { >> return name; >> } >> public void setName(String name) { >> this.name = name; >> } >> public Customer getCustomer() { >> return this.customer; >> } >> public void setCustomer(Customer c) { >> this.customer = c; >> } >> } >> >> >> The problem is that under "CustomerService" class, which contains a >> list of Customers and Orders, I have: >> >> @Path("/customerservice/') >> public class CustomerService { >> ... >> @POST >> @Path("/customers/") >> public Response addCustomer(Customer c) { >> ...... >> } >> .... >> } >> >> In this case, if I post a CustomerImpl object to >> "/customerservice/customers/", I have the error of "No message body >> reader has been found for request class Customer". If I change the >> function definition to be as follows, it works... >> @POST >> @Path("/customers/") >> public Response addCustomer(CustomerImpl c) { >> ...... >> } >> >> So, my first question is, is there a more elegant work-around such >> that "addCustomer" function would take "CustomerImpl" objects, even >> when the function parameter says "Customer c"? >> >> My second question is, let's say I want to post an "OrderImpl" object >> to "/customerservice/orders", but the OrderImpl object contains a >> reference to a customer. What is the best way to transfer the >> reference relationship between the client and the server? For some >> reason, the direct XML marshaling would ignore the reference. >> >> > > Looks like it does not work because Order and Customer interfaces, > presumably generated by EMF, have no @XmlRootElement annotations themselves. > > Adding these annotations to concrete implementations is problematic, as you > can add many components in EMF all the time. Some options to consider: > > - I recall it is possible to add custom metadata to the EMF model. Is it > possible to have @XmlRootElement added to the generated interfaces ? > - Explicitly configure CXF JAXBElementProvider and set it to use > JAXBElement internally - that should handle types such as Customer and > Order, see > http://cxf.apache.org/docs/jax-rs-data-bindings.html#JAX-RSDataBindings-HandlingJAXBbeanswithoutXmlRootElementannotations > > Hope that helps > > Sergey > > >> Thanks. >> -Simon >> >> >> >> On Thu, Apr 7, 2011 at 7:56 AM, Sergey Beryozkin <[email protected]> >> wrote: >> > Hi Simon >> > >> > On Wed, Apr 6, 2011 at 10:59 PM, Simon Chen <[email protected]> >> wrote: >> >> >> >> Hi all, >> >> >> >> I am trying to build a RESTful web service... In short, I am having >> >> trouble posting Java objects with member references from client side >> >> to server side. >> >> >> >> I have mostly followed the example under >> >> "apache-cxf-2.3.3/samples/jax_rs/basic". I have two major problems >> >> now... >> >> >> >> 1) Handle objects with references. For example, a customer may have a >> >> list of orders, and an order may be linked back to a customer. So, how >> >> can I (or indeed what is the best way to) post an "Order" object with >> >> a link to a "Customer" object to "/customerservice/orders"? >> >> >> >> 2) The example uses annotations like "XmlRootElement" to enable sort >> >> of automated conversioning from java objects to XML/json data. But >> >> this conversion seems to be broken when I add references into a class >> >> definition. For example, when I post an "Order" object to >> >> "/customerservice/orders", the server reports "No message body reader >> >> has been found for request class Order", (even though the customer ref >> >> is set to null). >> >> >> > >> > Is that Order class also annotated ? Can you post some sample structures >> > showing what exactly you'd like to do ? >> > >> > Thanks, Sergey >> > >> >> >> >> Thanks. >> >> -Simon >> > >> > >> > >> > > > > -- > Sergey Beryozkin > > Application Integration Division of Talend <http://www.talend.com> > http://sberyozkin.blogspot.com >
