Inspired by an
article RESTify your world..of Emiliano Pecis, I decided to make my own OSB Rest service which can return XML and JSON. To make this work I will use the XMLdb oradb servlet of the Oracle database. T o transform the oradb xml output to the JSON format I used the
JSON-LIB libraries.
Here some pictures of the OSB rest service.
Request for order 1000 with XML as output

The same, with now JSON as output.

Request for all the employees with xml as output

Before we start we need to setup de Oracle Database.
Login with sqlplus as xdb. Now we can set the http port of XMLdb.
exec dbms_xdb.sethttpport(8080);
Give your Oracle schema's rights to the oradb servlet. For example the user HR.
grant xdb_webservices to hr;
grant xdb_webservices_over_http to hr;
We can test this by using this url http://localhost:8080/oradb/HR/EMPLOYEES , you will need to authenticate so use the HR account for this. The output would look this.

We can also get one employee by using this url. http://localhost:8080/oradb/HR/EMPLOYEES/ROW[EMPLOYEE_ID=198]

Now we are ready to start with the OSB. First create the Business services where we call the XMLdb servlets. Select any xml as input and http as transport. We need also to create a Service Account with the hr username / password and add this to the Business service.

The next step is to create the OSB Proxy Service. Select messaging as service type and as use text as response messaging type( because we want to return something, else you will get some errors). The transport is http with as endpoint url "/rest". In the message flow we add a Routnode with some If-then.

because the first thing we need to know which type of data is requested. For example employees or orders. In the second If-then we need to know if all the employees are requested or just one. If all is requested then we can call the HR Business Service. If not then we need to retrieve the requested Id and rewrite the endpoint url of the HR Business service. You can achieve this with a routing options component.

This is not enough the new endpoint url has to processed else it won't work. (escape-uri($url/text(), false()) )

The incoming part is ready, we can focus now on the output. Here we have to create a Pipeline Pair.

In the request parameter we need to retrieve the request url and the parameters. To get the url we can use. $inbound/ctx:transport/ctx:request/http:relative-URI/text() and the get the requested output we can use $inbound/ctx:transport/ctx:request/http:query-string/text() . These parameters will be used by the java callout. In the response pipeline I will add a java callout.

This java code transform the XML to JSON. To succesfull use a java methoud in OSB, it need to be a static method and because I need to process the $body variable, I must have a org.apache.xmlbeans.XmlObject method argument.
The JSON output can return output with datatypes, This datatype information isn't provided in the xml output of XMLdb so I made a convertor class for employees and orders. To make this work I use java reflection.
here is a fragment of the code.
private static void invoke(Object inst,Method m, JSONObject obj){
try {
m.invoke(inst, new Object[] { obj });
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private static JSONArray convert(JSONArray json,String type) {
ListIterator list = json.listIterator();
Class dynamicConvertorClass = null;
Object clazzInst =null;
Method m = null;
try {
dynamicConvertorClass = Class.forName("nl.whitehorses.json.convertor."+type.substring(0, 1).toUpperCase() + type.substring(1).toLowerCase());
clazzInst = dynamicConvertorClass.newInstance();
m = dynamicConvertorClass.getMethod("changeType", new Class[] { JSONObject.class });
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
while ( list.hasNext() ) {
JSONObject obj = (JSONObject)list.next();
invoke (clazzInst,m,obj);
}
return json;
}
private static JSONObject convert(JSONObject json,String type) {
Class dynamicConvertorClass = null;
Object clazzInst =null;
Method m = null;
try {
dynamicConvertorClass = Class.forName("nl.whitehorses.json.convertor."+type.substring(0, 1).toUpperCase() + type.substring(1).toLowerCase());
clazzInst = dynamicConvertorClass.newInstance();
m = dynamicConvertorClass.getMethod("changeType", new Class[] { JSONObject.class });
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
invoke (clazzInst,m,json);
return json;
}
public static String xmlToJson(XmlObject xml, String type, String output)
{
if ( type.indexOf("/") > 0 ) {
type = type.substring(0,type.indexOf("/"));
}
System.out.println("type "+type);
System.out.println("content "+xml.xmlText());
if ( output.equalsIgnoreCase("output=json") ){
if ( !type.equalsIgnoreCase("not")) {
XMLSerializer ser = new XMLSerializer();
Object res = ser.read( xml.xmlText() );
if ( res instanceof JSONArray ) {
JSONArray json = (JSONArray) res;
json = convert(json,type);
return json.toString(1,0);
}
if ( res instanceof JSONObject ) {
JSONObject json = (JSONObject) res;
json = convert(json,type);
return json.toString(1,0);
}
}
}
return xml.xmlText();
}
The convertor of the employees request looks like this.
public void changeType(JSONObject obj){
Object a = obj.get("SALARY");
if ( a!= null) {
obj.put("SALARY",new Float(a.toString()));
}
a = obj.get("EMPLOYEE_ID");
if ( a!= null) {
obj.put("EMPLOYEE_ID",new Float(a.toString()));
}
a = obj.get("MANAGER_ID");
if ( a!= null) {
obj.put("MANAGER_ID",new Float(a.toString()));
}
a = obj.get("DEPARTMENT_ID");
if ( a!= null) {
obj.put("DEPARTMENT_ID",new Float(a.toString()));
}
a = obj.get("HIRE_DATE");
SimpleDateFormat sdfInput = new SimpleDateFormat ("d-MMM-yy") ;
Date date = null;
try {
date = sdfInput.parse(a.toString());
} catch (ParseException e) {
e.printStackTrace();
}
if ( a!= null) {
obj.put("HIRE_DATE",date);
}
In JDeveloper 11g I made a jar deployment and add this jar to the OSB project. Together with the required jars. Our json jar need a reference to the json-lib and the json-lib need a reference to the other jars.
That's all just deploy this to OSB server.
Here is my
OSB export jar and the
JDeveloper java callout project.