One of the great difficulties in building a mobile application is building a strong web service back-end. If you are using ADF BC as your data access layer, service-enabled application modules are a compelling option. My good friend Frank Nimphius published an article in Oracle Magazine on that very topic, titled Consume Early; Consume Often.
In the perspective of an ADF Mobile application, the web service methods exposed by the SDO interfaces of ADF BC view objects are accessed through the web service data control. It is worth remembering that, at this point, SDO interfaces can be reached through the SOAP protocol only. Support for REST interactions is currently planned for ADF 12c. Fortunately, the WSDL description for the service is generated by JDeveloper.
It is possible to bind directly your AMX pages to the web service data control. Shay Shmeltzer has posted a few blog entries where he uses this technique, even for calling web services with complex parameters. Some use cases, however, can be implemented more cleanly by calling the web service data control in Java code, which implies the page is bound to a bean or to a POJO-based data control. But how does one invoke the web service data control from code?
The first step is to look at the structure for the data control. Suppose I want to call the createVisit
method exposed by the VisitsWS
data control. The method accepts a single input parameter of type java.lang.Object
Calling the method with any random object will not work. The data control expects an object of a very specific type, with attributes matching its own definition. It is possible to determine the name of the type expected by the data control by hovering above the parameter with the mouse pointer, as shown in the screenshot below.
VisitsWS.Types.createVisit.visit
is not implemented through a Java class; it is a virtual type managed by the data control. In ADF Mobile, the web service data control, when operating over the SOAP protocol, requires parameters to be passed as instances of the oracle.adfmf.util.GenericType
interface. The only way to instantiate such objects is to use the GenericTypeBeanSerializationHelper
class provided by the framework. This class will transform POJO instances to and from GenericType.
Below is a code sample that shows how to build the GenericType and invoke the web service through the data control.
Visit visit = new Visit();
// Set attribute values for visit here.
List namesList = new ArrayList(1);
List paramsList = new ArrayList(1);
List typesList = new ArrayList(1);
GenericType gtVisit =
GenericTypeBeanSerializationHelper.toGenericType("VisitsWS.Types.createVisit.visit", visit);
namesList.add("visit");
paramsList.add(gtVisit);
typesList.add(Object.class);
try {
AdfmfJavaUtilities.invokeDataControlMethod("VisitsWS", null, "createVisit", namesList, paramsList,
typesList);
} catch (AdfInvocationException ex) {
// If the web service is not available throw a nice exception
if (AdfInvocationException.CATEGORY_WEBSERVICE.compareTo(ex.getErrorCategory()) == 0) {
throw new RuntimeException("Error with the server. Please try later.");
}
}
There are a few things you should take into account when creating your POJO objects.
java.lang.String
. Other types may work, but you may run into problems.oracle.adfmf.misc.ISO8601DateTimeUtil
class.By the way, if you found this post interesting, one of the two presentations I will make at the ODTUG Kaleidoscope 2013 conference in June will show you how to build flexible and SOA-compliant back-ends using Oracle ADF. See you in New Orleans!
hi,
great explanation.
above is about sending a single record.
i need to send multiple record as a parameter.
i have a List type of parameter. how to pass that to the WebserviceDC?
thanks,
ad
Dear « Guest »,
You cannot use a List directly for the time being. Simply declare an array of the appropriate type.
Thank you for reading.
Excellent...
Thanks alot for posting such kind of great information.
Hi...
Followed your tutorial but Im having problem with my request data. Web service is returning error 500 because it is receiving a null request. I logged the values of the request, the GenericType variable, before invokeDataControlMethod and it has values. But when I logged the values received by the web service it is already null. Any solutions?
Thanks.
-River
Hi River.
It is difficult for me to know what is happening without having a look at your code. However, the symptoms you describe seem to point to a problem with your Data Control. Have you tested your web service by accessing its WebLogic-generated test page?
Hi Frederic,
I am Trying to pass the two parameters to webservice method
public void rejectTaskList (List taskIds, String userName )
{
CustomWorklistClient workFlowClient = new CustomWorklistClient( userName ) ;
try
{
workFlowClient.rejectTaskList( taskIds ) ;
}
catch ( Exception e )
{
e.printStackTrace() ;
}
}
one parameter is taskids and another one is user name
could you please help me how can i pass the multiple taskids as a parameter
Regards,
Shankar.
Hi Shankar.
You should pass the task IDs as an array, not as a List. If the IDs are of type String, then the signature for your method should be public void rejectTaskList (String[] taskIds, String userName).
Best Regards,
Frédéric.