Additional Blogs by SAP
cancel
Showing results for 
Search instead for 
Did you mean: 
6,684

This blog aims to demonstrate how to create and run REST (Representational State Transfer) Web services using the SAP NetWeaver Composition Environment.

Contrary to popular believe getting REST to work with your code can be a bit tricky without the help from Jersey. Being a Sun product, it is developed as the open source Project Jersey and is the reference implementation of JSR 311 ("The Java API for RESTful Web Services").  Jersey takes care of the lower level HTTP processing and provides a way to map a RESTful HTTP Request directly to methods in your Java code. My aim is to get you to create a REST Web service on the SAP NetWeaver Composition Environment with the help from the Jersey libraries and to show you how to implement the most commonly used method calls.

This blog assumes that you are using the SAP NetWeaver Composition Environment (7.1, 7.11 or 7.2) including the corresponding SAP NetWeaver Developer Studio. Also, it is assumed that you have downloaded the required Jersey libraries from https://jersey.dev.java.net/.

 

Dealing with the Jersey libraries

Using the SAP NetWeaver Developer studio create an External Library Development Component (DC) project called ‘rest/ext/lib'

 

Download and import the necessary Jersey jar files into the libraries folder of the external libraries project. At the time of writing this article the following jar files were packaged within a jersey-archive-1.1.4.zip file obtained from the aforementioned URL.

 

 

Define 2 public parts of type Assembly and Compilation on the External Library Project; and add the libraries to each public part. The Assembly public part will ensure that your libraries are assembled and deployed with your Enterprise Application Project. The Compilation public part will ensure that your Java code that references the REST libraries will be able to compile. 

 

 

Create a Java EE Project

Create a Java EE Web Module Development Component Project and a Java EE Enterprise Application Development Component Project; remember to reference the Java EE Web Module Project. Name the Web Module Project ‘rest/web' and name the Enterprise Application Project ‘rest/ear'

 

 

Select the Web Module Project (rest/web) and assign a dependency to the (Compilation - API) public part of the External Library DC Project created in the first step.

 

 

Ensure that you select Build Time (on the API and ***) public part - this will ensure that you will be able to reference the Jersey API from within your web development component project.

 

 

In order to get Jersey to work you need to configure the Jersey servlet to a URL root. Also, you need to tell Jersey the location of the Java package to scan for REST annotations. This information is part of the web application's web.xml file. The com.sun.jersey.spi.container.servlet.ServletContainer servlet is the main REST class and is part of the JAX-RS API runtime. Notice the url-pattern tag, it indicates all URL requests prefixed with ‘/rest' relative to the context root of the war file needs to be forwarded to the Jersey REST servlet for processing. Note the param-value tag; this is where you specify your Java package that will contain your REST implementation Java files.

 

Enable the Jersey REST Servlet

 

 

 

Create the Java REST Web service code 

 

At this point you are finished with the setup and configuration and you can turn your attention over to your Java code. First create a package demo.sap.com.material and create 2 java files as shown in the image below.  

 

 

 

The Material java class will act as your POJO - add the fields and methods below to the class. Remember to add the XmlRootElement annotation before the class declaration. This will ensure that the material values will be represented as XML elements in an XML document that will be used within the HTTP response.

 

 

 

 

Start adding the Java code to the MaterialResouce Java file as shown below. This is your main Java class where the REST processing will occur. Note the annotations at the top of the class.

The Produces annotation is used to specify the MIME media types that will be returned back to the client. If the Produces annotation is applied at the class level, all the methods in a class can produce the specified MIME types by default. If it is applied at the method level, it overrides any Produces annotations applied at the class level. In our RESTful service example the material response information will be represented in XML format.

The Path annotation identifies the URI path to which the Java class responds, and is specified at the class level. The Path annotation's value is a partial URI path relative to the base URI of the server on which the application is deployed, the context root of the WAR, and the URL pattern to which the Jersey helper servlet responds. Later on you will see where the ‘materials' URI comes into play.

For simplicity sake we hard code the material list and added it to a Collection or type Material. The Material POJO should look familiar since we created this in one of the first steps.  

 

 

 

To return a complete list of all materials simply create the following method and add the GET annotation in front of the method declaration. Notice there is no Path annotation so therefore the class Path annotation materials will apply to this method.  Specifically this method will respond to both the HTTP GET method and the URI ‘/rest/materials'. Remember ‘/rest' is defined within the web.xml file and ‘/materials' are define at the class level; both will be inherited down to the method.

 

 

 

 

Eventually after you have deployed your application you can simply execute the URL below in your browser. Since browser requests are HTTP GET's by nature the above method will automatically get called and produce the XML output.

 

 

 

Let's take the example a step further; a complete list of all the materials may be sufficient however what if you only are interested in one specific material? The obvious approach would be to pass the material id as a variable to a method.  The way that REST handles variables are denoted by curly brackets, for example - look at the Path annotation below; this method can then be executed using the HTTP GET URI ‘/rest/materials/A1001'. This is how the material id can get passed into the method using the PathParam annotation.

 

 

 

 

Since the ‘materials' path URI parameter is defined at the class level you can simply append the material id. As a result the getMaterial method will get called passing in a single material id and the response will contain one instance of the Material class in XML format.

 

 

 

 

So far we have only looked at using REST to retrieve (READ) material information. The next sections will focus on modifying material data (ADD, UPDATE & DELETE). You might have found it interesting that the previous READ examples coincided nicely with the GET annotation and make use of the HTTP GET method. Similarly, to add data REST makes use of the standard HTTP POST method, to update information REST again makes use of the standard HTTP PUT method, and then finally to remove data REST makes use of the standard HTTP DELETE method.

Let's start by looking at addMaterial method and specifically at the annotations. Notice that the POST annotation is used, meaning that this method will respond to HTTP POST method calls but only if the URI matches ‘/rest/materials/add'. Since the method returns a simple non-XML string the Produces annotation is set to ‘text/plain'. The Consumes annotation however is mandating that the material request be in XML format; therefore the calling client application needs to ensure that the material request information is wrapped within a XML document.

 

 

 

 

At this point things can get a bit tricky trying to test your REST code to respond to HTTP POST, PUT or DELETE methods; a browser can no longer be used to test these methods. Therefore depending on the day I alternate between either cURL (a simple command line utility for getting and sending information using URL syntax) or my favorite is POSTER (a Mozilla Firefox add-on)  to test REST services. After you have installed the add-on you will see Poster within the Tools menu.

 

 

 

 

Start POSTER and as a first step supply the URL (notice the suffix ‘/add'). Next make sure to select the POST action. Since the Consumes annotation mandates ‘application/xml' make sure to also set the Content Type accordingly. Then finally add the XML material structure and press Submit.  

 

 

 

 

As a result you should see the response in plain text as returned by the REST method.

 

 

 

 

Note: Wonder why you are not seeing your newly added material when you try to execute the '/rest/materials' URL? Since this is a simple test you can define the Singleton annotation class declaration.  This will ensure that there is one instance of the class. Please use this annotation with caution and for testing purposes only otherwise it will have ambiguous affects when you have multiple users accessing this REST web service.

 

 

Now that you have some familiarity with sending data let's move on to the situation where you want to update data. As mentioned before REST uses the standard HTTP PUT method to accomplish updates. Notice the PUT annotation. Since the material id is critical to update the correct material you will notice the familiar looking {id} variable inside the Path annotation. In this case since the method returns void it's not mandatory to use the Produces annotation. However, it is required to specify the mime type within the Consumes annotation.  As before to update any material the representative information needs to be passed as an XML document.

 

 

 

 

To test REST updates using POSTER, simply append the material id to the URL, select the PUT Action and finally assign the Content Type and add the material XML structure. In our example we are simply updating the material price.

 

 

 

The last method that we will be looking at is the Delete method. The process is similar to those described above; however notice the Delete annotation that will respond to any HTTP Delete methods assuming the URI matches ‘/rest/materials/?’

 

 

 

 

As before simply add the URL, select the Delete Action and Click Submit. You do not have to supply a XML document for the DELETE method; also notice there is no Consumes annotation.

 

 

 

 

Create the Java Client

 

Since cURL and POSTER are only really good for testing purposes I have included some information if you need to execute REST services using Java Code instead. Jersey not only provides capabilities to easily create server side RESTful services but you can also use the Jersey libraries to consume RESTful services. If you look closely at all the Jersey libraries you should see a jersey-client*.jar file; this file includes the Jersey Client files to help you to consume REST services. Notice the package and files that you need to add in your import statement.

 

 

 

 

Good luck and have fun building your REST services.

11 Comments