Technology Blogs by Members
Explore a vibrant mix of technical expertise, industry insights, and tech buzz in member blogs covering SAP products, technology, and events. Get in the mix!
cancel
Showing results for 
Search instead for 
Did you mean: 
hofmann
Active Contributor

Java EE standard includes a REST specification and Jersey is an implementation of it. You can use Jersey with NetWeaver Java 7.3 without a problem. But you can do so only in Java EE applications. If you want to expose a SAP Portal application as a REST interface? What are your options in doing so?

Remember that a SAP Portal application is executed from within the SAP Portal framework. In the context of a portal, you are developing portlets that are executed by a portal. The portal itself is a Java EE application. Now it gets clear that using Jersey in that context isn't that simply: the incoming and outgoing calls are handled by the portal framework.

The EJB and Java EE tasks is normally not executed by a SAP Portal application. A Portal application may call them, but normally won`t do the JPA et al stuff. Now, why use a SAP Portal application with a REST interface? Of course to use the Portal framework. A scenario can be to retrieve user information and to secure this by the portal security and by having the user been assigned to the right iView and role.

REST

A browser supports the usual HTTP commands like GET, POST and so does the SAP Portal. The portlet specification and SAP’s implementation allow to have a listener for each HTTP command, so the foundation is already laid. The method called independently of the method specified by the browser is doContent. A enum in the portlet class defines the HTTP types:


private enum Rest {
                GET, POST, PUT, DELETE;
}

The doContent method is used to identify how the client invoked the portlet. While the IPortalComponentRequest is SAP Portal specific, it contains a method to retrieve the HttpServletRequest object. That one is form the Java EE servlet and contains the information needed to know how the servlet was called. Using the enum it is easy to find out how the portlet was called:



public void doContent(IPortalComponentRequest request, IPortalComponentResponse response)
{
                HttpServletRequest servletRequest = request.getServletRequest();
                String method = servletRequest.getMethod();
                Rest rest = Rest.valueOf(method);
                switch (rest) {
                case GET:
                                break;
                case POST:                           
                                break;
                }
}

Of course this will only work when the client uses the URL of the portlet without specifying any other information directly path. For instance, to get the data of a specific object identified by id, the Id parameter must be passed as a query. Something like /path/to/servlet/portal.component/{id} won`t work, while /path/to/servlet/portal.component?id=2 will work.

JSON

To return a JSON object, the SAP Portal output must be overwritten. If not, the portal framework will add it`s typical additional portal information. To prevent the portal from doing so, the writer object from the servlet response must be obtained.

1. Get the HttpServletResponse. Providing the parameter true means that we want to overwrite the output with our own information (effectively eliminating the portal framework HTML).

HttpServletResponse servletResponse = request.getServletResponse(true);

2. Get the writer.

PrintWriter out = servletResponse.getWriter();

Now only the JSON object is missing. There is a nice library available at json.org for creating JSON objects in Java. Using this library, creating a JSON object is really simple:


JSONObject retObj = new JSONObject();
retObj.put("status", 1);

As just sending back a JSON object is actually not a JSON response, the content type must be set to JSON too.


servletResponse.setCharacterEncoding("UTF-8");
servletResponse.setHeader("Content-Type", "application/json; charset=UTF-8");

Now the portal application can send back a JSON response to the browser:


out.write(retObj.toString());
out.close();

Source Code

This is just the portal component class. For JSON to work, the library from json.org must be imported. The link to access the portlet is defined by the portal component name or the iView.

The class javax.servlet.http.HttpServletRequest is included in the jar jee5.facade.jar found at DCs\sap.com\engine.jee5.facade\_comp\gen\default\public\api\lib\java

The source code can be found here: tobiashofmann/JSONwithSAPPortal · GitHub

The class ScnBlog:


package com.tobias.blog.json;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sap.tc.logging.Location;
import com.sapportals.portal.prt.component.AbstractPortalComponent;
import com.sapportals.portal.prt.component.IPortalComponentRequest;
import com.sapportals.portal.prt.component.IPortalComponentResponse;
import java.io.IOException;
import java.io.PrintWriter;
import org.json.JSONObject;
public class ScnBlog extends AbstractPortalComponent {
                private static final Location loc = Location.getLocation("com.tobias.blog");
                private static Category category = Category.getCategory(Category.APPLICATIONS, "com/tobias/blog");
                private enum Rest {
                                GET, POST, PUT, DELETE;
                }
                public void doContent(IPortalComponentRequest request,
                                                IPortalComponentResponse response) {
                                String subloc = "doContent";                                                             
                                loc.entering(subloc);
HttpServletResponse servletResponse = request.getServletResponse(true);
                                HttpServletRequest servletRequest = request.getServletRequest();
                                String method = servletRequest.getMethod();
                                Rest rest = Rest.valueOf(method);
                                switch (rest) {
                                case GET:
                                                try {
                                                                PrintWriter out;
                                                                out = servletResponse.getWriter();
                                                                JSONObject retObj = new JSONObject();

retObj.put("status", 1);
servletResponse.setCharacterEncoding("UTF-8");
                                                                servletResponse.setHeader("Content-Type", "application/json; charset=UTF-8");
                                                                out.write(retObj.toString());
                                                                out.close();
}
                                                catch (IOException e1) {
                                                                loc.errorT(subloc, "IOException: {0}" , new Object[]{e1.getMessage()});
                                                }
                                                break;
                                }
                }
}



Labels in this area