Thursday, September 5, 2013

ADF Mobile - Programmatically call RestServiceAdapter for POST Request

In my previous blog entry we saw how to get Rest WebService based form values in managed bean programmatically. In this entry will see how RestServiceAdapter interface lets you trigger execution of web service operations without the need to create a web service data control or interact with it directly.

Below code will explain how to get REST WebService based form values in managed bean and programmatically call the RestServiceAdapter for the POST request . Already there is a documentation on this, but here I'm trying to explain the end to end scenario as mentioned in below steps.
  1. Get the form values from departmentsIterator programmatically. 
  2. Dynamically construct the response xml based on departmentsIterator.
  3. Set the Rest WebService Connection with POST request option.
Take an example with mobile application having two screen. First screen consists of departments list and in second screen you can add new department for the Save button I have created the managed bean with actionListener method as below. 
public class DeptBean {
    public DeptBean() {
    }

    public void addDeptAction(ActionEvent actionEvent) {
        RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
        // Clear any previously set request properties, if any
        restServiceAdapter.clearRequestProperties();
        // Set the connection name
        restServiceAdapter.setConnectionName("RestServerEndpoint");
        restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_POST);
        // Specify the type of request
        restServiceAdapter.addRequestProperty("Content-Type", "application/xml");
        restServiceAdapter.addRequestProperty("Accept", "application/xml; charset=UTF-8");
        // Specify the number of retries
        restServiceAdapter.setRetryLimit(0);
        // Set the URI which is defined after the endpoint in the connections.xml.
        // The request is the endpoint + the URI being set
        restServiceAdapter.setRequestURI("/EJBRestServiceDemo/jersey/EJBRestServiceDemo");

        ValueExpression ve =
            AdfmfJavaUtilities.getValueExpression("#{bindings.departmentsIterator.currentRow.dataProvider}",
                                                  Object.class);
        Object obj = ve.getValue(AdfmfJavaUtilities.getAdfELContext());
        if (obj instanceof VirtualJavaBeanObject) {
            try {
                VirtualJavaBeanObject vjbo = (VirtualJavaBeanObject)obj;
                String postData = this.constructXMlResponse(vjbo);
                response = restServiceAdapter.send(postData);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Construct the XMLResponse based on the VirtualJavaBeanObject dynamically
     * @param vjbo
     * @return
     */
    public static String constructXMlResponse(VirtualJavaBeanObject vjbo) {
        String XMLResponse = "";
        if (vjbo.getAttributeInfoCount() > 0) {
            String xmlRootTag = getClassName(vjbo.getName());
            XMLResponse += "<" + xmlRootTag + ">";
            int count = vjbo.getAttributeInfoCount();
            for (int i = 0; i < count; i++) {
                AttributeInfo fieldName = vjbo.getAttributeInfo(i);
                XMLResponse +=
                        "<" + fieldName.name + ">" + vjbo.getAttribute(fieldName.name).toString() + "</" + fieldName.name +
                        ">";
            }
            XMLResponse += "</" + xmlRootTag + ">";
        }
        return XMLResponse;
    }


    /**
     * Get the class name with/without the package
     * @param className
     * @return
     */
    public static String getClassName(String className) {
        int firstChar = className.lastIndexOf('_') + 1;
        if (firstChar > 0) {
            className = className.substring(firstChar);
        }
        return className.toLowerCase();
    }
}
Note:- The GenericType is only exposed in SOAP data controls, so Rest Webservice data control can't be executed directly using AdfmfJavaUtilities.invokeDataControlMethod.

You can download the sample workspace from here.
[Runs with Oracle JDeveloper 11.1.2.4.0]

9 comments:

  1. awesome post thanks for this post i like it.

    ReplyDelete
  2. Hi Deepak,
    I have content type as application/x-www-form-urlencoded in my Rest Service.
    Can you let me know how to pass parameters as payload.

    Regards.
    Kaustubh Patel.

    ReplyDelete
  3. Hi Deepak,
    I am calling a POST, REST web service in which I have to send username and password as parameters. Content type is JSON.

    Please help me in solving the issue.
    Thanks.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete
    2. hi,
      please tell me how to do that if you had solved the issue.
      I too have same requirement but with GET request.
      Thanks

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Nice & Informative Blog !
    Finding adequate technical services for QuickBooks in this competitive world is quite challenging. Our team at QuickBooks Customer Service Number 1-(855)-738-7873 is always available to offer you the best technical help for QuickBooks.

    ReplyDelete