Design and implement POJO Web services using Spring and ...

4 downloads 70 Views 74KB Size Report
Sep 25, 2008 ... Spring and Apache CXF, Part 2: Create a RESTful. Web service ... as a RESTful Web service that uses CXF and Spring. This Web service ...
Design and implement POJO Web services using Spring and Apache CXF, Part 2: Create a RESTful Web service Skill Level: Intermediate Rajeev Hathi ([email protected]) Senior Software Consultant IBM Naveen Balani ([email protected]) Software Architect IBM

25 Sep 2008 Create a RESTful Web service, which is defined as a Spring bean, using Apache CXF, an open source Web service framework. This article explores the features and benefits of using the Representational State Transfer (REST) architecture and illustrates the use of the REST API in CXF to easily develop a RESTful service.

Introduction In this article, you build an order application. The application functionality is exposed as a RESTful Web service that uses CXF and Spring. This Web service performs read and add operations on an order resource. After reading the article, you can apply the concepts and features of the REST architecture style and use a CXF-based REST API to build and develop a RESTful Web service. System requirements To run the examples in this article, make sure the following software is installed and set up on your machine: • Java™ 5 or higher

Create a RESTful Web service © Copyright IBM Corporation 1994, 2007. All rights reserved.

Page 1 of 12

developerWorks®

ibm.com/developerWorks

• Tomcat 5 or higher • Ant build tool • CXF binary distribution 2.1 After the above distribution is installed, set up the following environment variables: • JAVA_HOME (for Java) • CATALINA_HOME (for Tomcat) • ANT_HOME (for Ant) • CXF_HOME (for CXF) By way of example, set CXF_HOME=C:\apache-cxf-2.1 and add the following to the PATH env variable: • JAVA_HOME\bin • CATALINA_HOME\bin • ANT_HOME\bin

REST -- A Web architecture A Web service can be very complex because Web service development involves implementing various infrastructural components, such as Web Services Description Language (WSDL) and SOAP, which in turn bind to various other standards. Every Web server that offers a Web services solution has to invest a lot in terms of creating a robust Web service infrastructure model. From the point of view of developers, it becomes increasingly complex to learn the technology. But never fear! REST comes to the rescue. RESTful Web services are simply XML-over-HTTP services. Unlike a usual Web service, which has various contracts to be defined and negotiated between the provider and consumer, RESTful services encapsulate data in a simple XML form and transport it over HTTP just like a Web page request to the Web server. REST is more of an architecture than an implementation or a standard. The REST architecture style is related to a Web resource, which is a representation identified by a Uniform Resource Indicator (URI) (for example, http://myweb.com/myresource). The resource can be any persistent entity, including Order, Customer, Employee, and so on. The client queries or updates the resource through the URI and, therefore, influences a state change in its representation. In simple terms, a client program can access, update, add, or remove a Web resource through URI using

Create a RESTful Web service Page 2 of 12

© Copyright IBM Corporation 1994, 2007. All rights reserved.

ibm.com/developerWorks

developerWorks®

various HTTP methods, thereby changing its representational state. HTTP methods include GET, POST, PUT, and DELETE. To summarize, REST is simply a specification that indicates a standard approach for a user to invoke operations on a Web resource using HTTP request methods in a Web service style. REST is closely associated with HTTP and leverages all HTTP features, such as methods, headers, and types. REST and CXF CXF is an open source Web service framework that provides a simple API to conveniently build and develop a Web service. In Part 1 of this series, you saw how simple it is to develop a Web service using a Spring-based CXF configuration. This second article shows how equally simple it is to develop a RESTful service. CXF provides a RESTful style of Web service implementation in three flavors: • JAX-RS (JSR-311) • HTTP binding • Java API for XML Web Services (JAX-WS) Provider and Dispatch APIs

Order application Now you can create an order application that lets the user create and read or view order details. You use the RESTful architectural style with CXF to invoke these functions and manage your order application. Before developing the application, let's define the use cases: 1.

User creates the order (generates unique order ID).

2.

User queries the order details (based on order ID).

3.

User queries all the orders.

Each operation is invoked using a URI, which is typically how a Web service is invoked. Each operation is associated with one of the following HTTP request methods: GET, POST, PUT, and DELETE. The API uses Java Rest Annotations (JRAs) to map operations to HTTP/URI verb combinations. Table 1 shows the JRA/verb combination. Table 1. JRA/Verb mapping table JRA

HTTP request

Verb

Create a RESTful Web service © Copyright IBM Corporation 1994, 2007. All rights reserved.

Page 3 of 12

developerWorks®

ibm.com/developerWorks

method @Get

GET

get

@Post

POST

add /create

@Put

PUT

update

@Delete

DELETE

delete

Develop a RESTful service To develop a RESTful Web service, you start by creating a Service Endpoint Interface (SEI) and an implementation class. Then you wire it using a Spring-based CXF configuration file. You perform the following steps: 1.

Create an SEI and annotate with REST annotations.

2.

Create the implementation class.

3.

Create beans.xml, define the service class as a Spring bean using HTTP binding, and publish it as a JAX-WS endpoint.

4.

Create web.xml.

You create an SEI named OrderProcess that acts as a resource representation interface. The Order class is a resource class. Listing 1 shows the OrderProcess SEI. Listing 1. OrderProcess SEI @WebService(targetNamespace = "http://demo.order") public interface OrderProcess { // Get all the orders @Get @HttpResource(location = "/orders") @WebResult(name = "Orders") public Orders getOrders(); // Get order data based on the specified order ID @Get @HttpResource(location = "/orders/{id}") public Order getOrder(@WebParam(name = "GetOrder") GetOrder getOrder); // Add an order @Post @HttpResource(location = "/orders") public void addOrder(@WebParam(name = "Order") Order order); }

The OrderProcess SEI has three methods: Create a RESTful Web service Page 4 of 12

© Copyright IBM Corporation 1994, 2007. All rights reserved.

ibm.com/developerWorks

developerWorks®

• getOrder returns a single order data based on the specified order ID. • getOrders returns all the orders. • addOrder lets you add an order. This method takes the Order bean as a parameter. You define these methods using REST annotations and identify them by a URI. The @GET annotation is used for the getOrder and getOrders methods, and @POST is used for the addOrder method. Each of these methods is identified by a URI defined by the @HttpResource annotation. Now you have the URI mapping, as shown in Table 2. Table 2. Method/URI mapping table Method

URI

getOrder

/orders/{id}

getOrders

/orders

addOrder

/orders

You can now create an OrderProcessImpl implementation class, shown in Listing 2. Listing 2. OrderProcessImpl service implementation @WebService(endpointInterface = "demo.order.OrderProcess") public class OrderProcessImpl implements OrderProcess { Map orders = new HashMap(); private int i; public Orders getOrders() { Orders o = new Orders(); o.setOrder(orders.values()); return o; } public Order getOrder(GetOrder order) { String orderID = order.getId(); return orders.get(orderID); } public void addOrder(Order order) { String orderID = "ORD0" + (++i); // Added as a POST request String customerName = order.getName(); Order newOrder = new Order(); newOrder.setOrderID(orderID); newOrder.setName(customerName); orders.put(orderID, newOrder); System.out.println("Order added successfully");

Create a RESTful Web service © Copyright IBM Corporation 1994, 2007. All rights reserved.

Page 5 of 12

developerWorks®

ibm.com/developerWorks

} }

The REST interface is ready. Let's walk through its implementation. The OrderProcessImpl class implements the SEI and thus its methods. The addOrder method populates the order details in the HashMap with the key as the order ID and the value as the Order instance. The Order bean has two properties: orderID and customer name. The customer name is added using the POST request method, while the order ID is generated. The getOrder method takes the order ID as a parameter, gets the corresponding order from the HashMap, and returns the same. The getOrders method returns all the orders from the HashMap. The next step is to create the beans.xml configuration file, shown in Listing 3. Listing 3. beans.xml configuration file

The bean definition for OrderProcessImpl is wrapped as a JAX-WS endpoint and the binding URI as http://apache.org/cxf/binding/http. The binding URI signifies that the service is bound to the resources using the HTTP binding method. The address is /, which is relative to the Web context. The JaxWsServiceFactoryBean specifies a wrapped attribute as set to false. It means the bean's request/response XML-based data should not be wrapped with the root element as the operation name.

Create a RESTful Web service Page 6 of 12

© Copyright IBM Corporation 1994, 2007. All rights reserved.

ibm.com/developerWorks

developerWorks®

Listing 4. web.xml Web configuration file contextConfigLocation WEB-INF/beans.xml org.springframework.web.context.ContextLoaderListener CXFServlet CXF Servlet org.apache.cxf.transport.servlet.CXFServlet 1 CXFServlet /*

Finally you create web.xml, which loads the CXF configuration file. Then you need to use the Spring context loader to load the configuration file. You also have to register a CXFServlet, which handles all the requests coming from the client program. Develop a client For the POST request, you create a client class, Client. Listing 5 shows the Client class that adds a new order. Listing 5. The Client class that handles the POST request public final class Client { public static void main(String[] args) throws Exception { String xml = null; try { // Make an HTTP connection to the server URL u = new URL("http://localhost:8080/orderapp_rest/orders"); HttpURLConnection httpCon = (HttpURLConnection) u.openConnection(); // Set the request method as POST httpCon.setRequestMethod("POST"); httpCon.setDoOutput(true); OutputStream os = httpCon.getOutputStream(); // XML encoded in UTF-8 format OutputStreamWriter wout = new OutputStreamWriter(os, "UTF-8"); wout.write("\r\n"); // Add customer name as XML fragment wout.write("

Create a RESTful Web service © Copyright IBM Corporation 1994, 2007. All rights reserved.

Page 7 of 12

developerWorks®

ibm.com/developerWorks

Rajeevr\n"); wout.flush(); // Make implicit connection to the server httpCon.getContentLength(); httpCon.disconnect(); os.close(); } catch (IOException e) { e.printStackTrace(); } } }

The class makes an HTTP connection to http://localhost:8080/orderapp_rest/orders and sends XML data as a POST request. The XML consists of order details to be added. You add a customer name, while the order ID is automatically generated. Once the URL is called, the order ID and the customer name are added to the Map collection. For the GET request, simply navigate to http://localhost:8080/orderapp_rest/orders/ORD01 in the browser to get the order details. It displays the XML elements containing the order data for the order ID ORD01. Similarly, to display all the orders placed by the customers, navigate to http://localhost:8080/orderapp_rest/orders in the browser. Figure 1 shows the output of the URI http://localhost:8080/orderapp_rest/orders/ORD01 when specified in a browser. Figure 1. Browser output for GET request

Conclusion This article illustrated the use of GET and POST methods. You learned about the

Create a RESTful Web service Page 8 of 12

© Copyright IBM Corporation 1994, 2007. All rights reserved.

ibm.com/developerWorks

developerWorks®

features and concepts of the REST architectural style and how to use it with CXF to develop RESTful services. RESTful HTTP provides a unique concept to the way resources are accessed and manipulated and a completely new dimension to Web service development. With Web-based development becoming more popular and common, REST technology is only going to get better.

Create a RESTful Web service © Copyright IBM Corporation 1994, 2007. All rights reserved.

Page 9 of 12

developerWorks®

ibm.com/developerWorks

Downloads Description

Name

Size

Order application

orderapp_rest.zip 12KB

Download method HTTP

Information about download methods

Create a RESTful Web service Page 10 of 12

© Copyright IBM Corporation 1994, 2007. All rights reserved.

ibm.com/developerWorks

developerWorks®

Resources Learn • Read the tutorial "Design and develop JAX-WS 2.0 Web services" (developerWorks, Sep 2007), a step-by-step guide to developing Web services using JAX-WS technology. • Read the Hands on Web Services book for comprehensive hands-on information about how to design and develop real-world Web services applications. • Check out the article "Web services architecture using MVC style" (developerWorks, Feb 2002) to learn how to apply the MVC architecture to invoke static or dynamic Web services. • Take the tutorial "Deliver Web services to mobile apps" (developerWorks, Jan 2003) to learn how to access Web services using Java 2 Platform, Micro Edition (J2ME)-enabled mobile devices. • The SOA and Web services zone on IBM developerWorks hosts hundreds of informative articles and introductory, intermediate, and advanced tutorials on how to develop Web services applications. • Play in the IBM SOA Sandbox! Increase your SOA skills through practical, hands-on experience with the IBM SOA entry points. • The IBM SOA Web site offers an overview of SOA and how IBM can help you get there. • Stay current with developerWorks technical events and webcasts. • Browse for books on these and other technical topics at the Safari bookstore. • Check out a quick Web services on demand demo. • Get an RSS feed for this series. (Find out more about RSS.) Get products and technologies • Download IBM product evaluation versions and get your hands on application development tools and middleware products from DB2®, Lotus®, Rational®, Tivoli®, and WebSphere®. Discuss • Participate in the discussion forum for this content. • Get involved in the developerWorks community by participating in developerWorks blogs.

Create a RESTful Web service © Copyright IBM Corporation 1994, 2007. All rights reserved.

Page 11 of 12

developerWorks®

ibm.com/developerWorks

About the authors Rajeev Hathi Rajeev Hathi works as a software consultant for the J2EE platform. His interests are architecting and designing J2EE-based applications. Rajeev attained SUN certifications in Java and J2EE technologies (Web, EJB, Architect). He has contributed to IBM developerWorks by writing articles about Ajax, Web services, DB2, and XML. In addition, he was involved in writing a book about applying Java 6 and Hands to Web services. He is based in Mumbai, India. His hobbies are watching sports and listening to rock music.

Naveen Balani Naveen Balani works as an architect with IBM India Software Labs (ISL). He leads the design and development activities for WebSphere Business Services Fabric out of ISL. He likes to research new technologies and is a regular contributor to IBM developerWorks, having written about such topics as Web services, ESB, JMS, SOA, architectures, open source frameworks, semantic Web, J2ME, pervasive computing, Spring, Ajax, and various IBM products. He's also a coauthor of Beginning Spring Framework 2 and Getting Started with IBM WebSphere Business Services Fabric V6.1.

Trademarks IBM, the IBM logo, ibm.com, DB2, developerWorks, Lotus, Rational, Tivoli, and WebSphere are trademarks or registered trademarks of International Business Machines Corporation in the United States, other countries, or both. These and other IBM trademarked terms are marked on their first occurrence in this information with the appropriate symbol (® or ™), indicating US registered or common law trademarks owned by IBM at the time this information was published. Such trademarks may also be registered or common law trademarks in other countries. See the current list of IBM trademarks. Adobe, the Adobe logo, PostScript, and the PostScript logo are either registered trademarks or trademarks of Adobe Systems Incorporated in the United States, and/or other countries. Java and all Java-based trademarks are trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.

Create a RESTful Web service Page 12 of 12

© Copyright IBM Corporation 1994, 2007. All rights reserved.