Re: Programmatically publishing a REST endpoint
On 08/11/2007, at 7:37 PM, Liu, Jervis wrote: Here you go, a brief document on how to build RESTful services in CXF using JAX-RS (JSR-311): http://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+%28JSR-311%29 Hi Jervis, Thanks for the information. One clarification: as I'm using the servlet transport, I don't want to set an explicit address, just a path component, so that the REST API is under the URL my CXFServlet maps to. So given that I have this code to publish my SOAP services: public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); Bus bus = this.getBus(); BusFactory.setDefaultBus(bus); Endpoint.publish(/review, SpringContext.getComponent(rpcReviewService)); Endpoint.publish(/auth, SpringContext.getComponent(rpcAuthService)); ... REST publishing goes here ... } Can I use something like: JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); sf.setResourceClasses(RestReviewService.class); //default lifecycle is per-request, change it to singleton sf.setResourceProvider(RestReviewService.class, new SingletonResourceProvider()); sf.setBus(bus); sf.setAddress(/rest); // will this work? sf.create(); A more general question: What are the pros and cons of using CXF HTTP binding vs. JSR-311 for REST? Thanks again, Tom -- ATLASSIAN - http://www.atlassian.com Our products help over 8,500 customers in more than 95 countries to collaborate
RE: Programmatically publishing a REST endpoint
Here you go, a brief document on how to build RESTful services in CXF using JAX-RS (JSR-311): http://cwiki.apache.org/confluence/display/CXF20DOC/JAX-RS+%28JSR-311%29 BTW, at the moment we do not support the return of a List in JAX-RS (e.g., ListReviewData getAllReviews() ), I am even not sure whether or not this should be supported. The main problem is a direct mapping from List to XML would result in an invalid XML as it has multiple root elements, thus can not be displayed on browsers. You will need a wrapper object, i.e., ReviewDataList getAllReviews(), where ReviewDataList is defined as: @XmlRootElement(name = ReviewDataList) public class ReviewDataList { private CollectionReviewData rds; public CollectionReviewData getReviewData() { return rds; } public void setReviewData(CollectionReviewData r) { this.rds= r; } } Jervis -Original Message- From: Liu, Jervis [mailto:[EMAIL PROTECTED] Sent: 2007?11?8? 15:06 To: cxf-user@incubator.apache.org Subject: RE: Programmatically publishing a REST endpoint Currently there are three ways to build a RESTful service in CXF. [1] and [2] should give you enough information on how to use CXF HTTP binding and JAX-WS Dispatch/Provider to build a RESTful service. Now we have a third option - using JSR-311. You are very welcome to try this new feature out, any feedbacks would be hightly appreciated. This has not been documented yet, but I will do this soon. At the same time, there are couple of examples under system test directory [3], which hopefully will help you out. To answer your specific question, if you want to use CXF HTTP binding, you need to write your server mainline as below: JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean(); sf.setServiceClass(PeopleService.class); sf.getServiceFactory().setWrapped(true); sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID); sf.setAddress(http://localhost:9001/;); PeopleService peopleService = new PeopleServiceImpl(); sf.getServiceFactory().setInvoker(new BeanInvoker(peopleService)); Server svr = sf.create(); Your RestReviewService.class suggests that you are actually using JSR-311, in this case, your server main line is as below: JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); sf.setResourceClasses(RestReviewService.class); //default lifecycle is per-request, change it to singleton sf.setResourceProvider(RestReviewService.class, new SingletonResourceProvider()); sf.setAddress(http://localhost:9001/;); sf.create(); [1]. http://cwiki.apache.org/CXF20DOC/http-binding.html [2]. http://cwiki.apache.org/CXF20DOC/rest-with-jax-ws-provider-and -dispatch.html [3]. https://svn.apache.org/repos/asf/incubator/cxf/trunk/systests/ src/test/java/org/apache/cxf/systest/jaxrs Hope this helps, Jervis -Original Message- From: Tom Davies [mailto:[EMAIL PROTECTED] Sent: 2007?11?8? 9:03 To: cxf-user@incubator.apache.org Subject: Programmatically publishing a REST endpoint Hi, I have a SOAP services working fine, using the servlet transport. The servlet is configured in web.xml, and the end point publishing happens in the init method of the servlet (which is a subclass of CXFServlet: public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); Bus bus = this.getBus(); BusFactory.setDefaultBus(bus); Endpoint.publish(/review, SpringContext.getComponent(rpcReviewService)); Endpoint e = Endpoint.create(HTTPBinding.HTTP_BINDING, SpringContext.getComponent(restReviewService)); e.publish(/rest); Endpoint.publish(/auth, SpringContext.getComponent(rpcAuthService)); } My RestReviewService class (based on the CustomerService example) looks like: @Component(restReviewService) @WebService @UriTemplate(/review/) public class RestReviewService { @Autowired private ReviewService reviewService; @HttpContext UriInfo uriInfo; @HttpMethod(GET) @UriTemplate(/all/) public ListReviewData getAllReviews() { return reviewService.getAllReviews(); } } When I start my server the log says: ... [java] Nov 8, 2007 11:34:53 AM org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass [java] INFO: Creating Service {http://rpc.spi.crucible.atlassian.com/ }RestReviewServiceService from class com.atlassian.crucible.spi.rpc.RestReviewService [java] Nov 8, 2007 11:34:53 AM org.apache.cxf.endpoint.ServerImpl initDestination [java] INFO: Setting the server's publish address to be /rest [java] Nov 8, 2007 11:34:53 AM org.apache.cxf.service.factory.ReflectionServiceFactoryBean
RE: Programmatically publishing a REST endpoint
Currently there are three ways to build a RESTful service in CXF. [1] and [2] should give you enough information on how to use CXF HTTP binding and JAX-WS Dispatch/Provider to build a RESTful service. Now we have a third option - using JSR-311. You are very welcome to try this new feature out, any feedbacks would be hightly appreciated. This has not been documented yet, but I will do this soon. At the same time, there are couple of examples under system test directory [3], which hopefully will help you out. To answer your specific question, if you want to use CXF HTTP binding, you need to write your server mainline as below: JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean(); sf.setServiceClass(PeopleService.class); sf.getServiceFactory().setWrapped(true); sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID); sf.setAddress(http://localhost:9001/;); PeopleService peopleService = new PeopleServiceImpl(); sf.getServiceFactory().setInvoker(new BeanInvoker(peopleService)); Server svr = sf.create(); Your RestReviewService.class suggests that you are actually using JSR-311, in this case, your server main line is as below: JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); sf.setResourceClasses(RestReviewService.class); //default lifecycle is per-request, change it to singleton sf.setResourceProvider(RestReviewService.class, new SingletonResourceProvider()); sf.setAddress(http://localhost:9001/;); sf.create(); [1]. http://cwiki.apache.org/CXF20DOC/http-binding.html [2]. http://cwiki.apache.org/CXF20DOC/rest-with-jax-ws-provider-and-dispatch.html [3]. https://svn.apache.org/repos/asf/incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/jaxrs Hope this helps, Jervis -Original Message- From: Tom Davies [mailto:[EMAIL PROTECTED] Sent: 2007?11?8? 9:03 To: cxf-user@incubator.apache.org Subject: Programmatically publishing a REST endpoint Hi, I have a SOAP services working fine, using the servlet transport. The servlet is configured in web.xml, and the end point publishing happens in the init method of the servlet (which is a subclass of CXFServlet: public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); Bus bus = this.getBus(); BusFactory.setDefaultBus(bus); Endpoint.publish(/review, SpringContext.getComponent(rpcReviewService)); Endpoint e = Endpoint.create(HTTPBinding.HTTP_BINDING, SpringContext.getComponent(restReviewService)); e.publish(/rest); Endpoint.publish(/auth, SpringContext.getComponent(rpcAuthService)); } My RestReviewService class (based on the CustomerService example) looks like: @Component(restReviewService) @WebService @UriTemplate(/review/) public class RestReviewService { @Autowired private ReviewService reviewService; @HttpContext UriInfo uriInfo; @HttpMethod(GET) @UriTemplate(/all/) public ListReviewData getAllReviews() { return reviewService.getAllReviews(); } } When I start my server the log says: ... [java] Nov 8, 2007 11:34:53 AM org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass [java] INFO: Creating Service {http://rpc.spi.crucible.atlassian.com/ }RestReviewServiceService from class com.atlassian.crucible.spi.rpc.RestReviewService [java] Nov 8, 2007 11:34:53 AM org.apache.cxf.endpoint.ServerImpl initDestination [java] INFO: Setting the server's publish address to be /rest [java] Nov 8, 2007 11:34:53 AM org.apache.cxf.service.factory.ReflectionServiceFactoryBean buildServiceFromClass ... But the service endpoint seems to be another SOAP service, as when I go to http://localhost:6060/foo/services/rest/review/all I get: soap:Envelope xmlns:soap=http://schemas.xmlsoap.org/soap/ envelope/soap:Bodysoap:Faultfaultcodesoap:Server/ faultcodefaultstringNo such operation: review/faultstring/ soap:Fault/soap:Body/soap:Envelope Thanks for any tips or pointers to documentation other than http://cwiki.apache.org/CXF20DOC/rest-with-jax-ws-provider-and -dispatch.html I suspect I need to set the JAXRS binding for the endpoint, but I don't know how to do it... Tom -- ATLASSIAN - http://www.atlassian.com Our products help over 8,500 customers in more than 95 countries to collaborate IONA Technologies PLC (registered in Ireland) Registered Number: 171387 Registered Address: The IONA Building, Shelbourne Road, Dublin 4, Ireland