REST/JSON in MAF

Tweet about this on TwitterShare on Facebook15Share on LinkedIn18Share on Google+0

REST/JSON has several advantages over SOAP/XML, so it is preferred for mobile web services. As REST/JSON is a smaller than SOAP/XML, you will be passing much less data over the network. For mobile devices, it is a very important point.

In this post we will create a CRUD of employees in Oracle MAF 2.0 using REST/JSON.
I will use this REST application (Expose ADF BC as RESTful Web Service).
Download the sample application: MAFRESTJSONApp.zip.

Initialize the REST Web Service.

restjson-in-maf1

Create a Mobile Application Framework Application, and name it as MAFRESTJSONApp.
In the maf-feature.xml file, create a new feature and call it as employees.
Click the Content tab, and then click green plus button near File field, to create the EmployeesTF Task Flow.

Create the REST Connection.
Go to Projects panel, right-click ViewController project and choose New > From Gallery.
In the New Gallery dialog, choose General > Connections > REST Connection.
If you click Test Connection button, you will receive an error.
It is intentional, because I want to use the same REST Connection for all operations.

restjson-in-maf2

Create the Employee Entity.
Go to Projects panel, right-click ViewController project and choose New > Java Class.
In this application, Employee class must implement the Cloneable class.

restjson-in-maf3

Copy the following code inside Employee class.

private Integer employeeId;
private String firstName;
private String lastName;
private String email;
private String phoneNumber;
private java.sql.Date hireDate;
private String jobId;
private BigDecimal salary;
private BigDecimal commissionPct;
private Integer managerId;
private Integer departmentId;

protected Object clone() throws CloneNotSupportedException {
  return super.clone();
}

Generate the accessors.
Mark this option: “Notify listeners when property changes”.

restjson-in-maf4

Create the Employees Entity.
Go to Projects panel, right-click ViewController project and choose New > Java Class.

restjson-in-maf5

Copy the following code inside Employees class.

private Employee [] employee;

public void setEmployee(Employee[] employee) {
  this.employee = employee;
}

public Employee[] getEmployee() {
  return employee;
}

public List getEmployeesAsList() {
  return Arrays.asList(this.employee);
}

Create the RestServiceUtil Utility class.
Go to Projects panel, right-click ViewController project and choose New > Java Class.
Unmark this option: “Constructors from Superclass”.

restjson-in-maf6

Copy the following code inside RestServiceUtil class.

private String connectionName;

public RestServiceUtil(String connectionName) {
  super();
  this.connectionName = connectionName;
}

public String invokeCreate(String requestURI, Object postData) {
  return invokeRestService(RestServiceAdapter.REQUEST_TYPE_PUT, requestURI, postData);
}

public String invokeUpdate(String requestURI, Object postData) {
  return invokeRestService(RestServiceAdapter.REQUEST_TYPE_POST, requestURI, postData);
}

public String invokeDelete(String requestURI) {
  return invokeRestService(RestServiceAdapter.REQUEST_TYPE_DELETE, requestURI, null);
}

public String invokeFind(String requestURI, Object postData) {
  return invokeRestService(RestServiceAdapter.REQUEST_TYPE_GET, requestURI, postData);
}

private String invokeRestService(String requestType, String requestURI, Object postData) {
  RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
  restServiceAdapter.clearRequestProperties();
  restServiceAdapter.setConnectionName(connectionName);
  restServiceAdapter.setRequestType(requestType);
  restServiceAdapter.setRetryLimit(0);
  restServiceAdapter.setRequestURI(requestURI);
  restServiceAdapter.addRequestProperty("Content-Type", "application/json");
  restServiceAdapter.addRequestProperty("Accept", "application/json; charset=UTF-8");

  String response = "";
  String postDataStr = "";

  try {
    if (postData != null) {
      JSONObject jsonObj = (JSONObject) JSONBeanSerializationHelper.toJSON(postData);
      removeNullsAndTypeFromJSON(jsonObj);
      postDataStr = jsonObj.toString();
    }

    response = restServiceAdapter.send(postDataStr);

  } catch (AdfInvocationException ex) {
    if (AdfInvocationException.CATEGORY_WEBSERVICE.compareTo(ex.getErrorCategory()) == 0) {
      throw new RuntimeException("Error with the server. Please try later.");
    }
  } catch (Exception e) {
    throw new AdfException(e.getLocalizedMessage(), AdfException.ERROR);
  }

  return response;
}

private void removeNullsAndTypeFromJSON(JSONObject jsonObj) throws JSONException {
  jsonObj.remove(".type");

  for (int i = 0; i < jsonObj.length(); i++) {
    String key = jsonObj.names().getString(i);
    if (JSONBeanSerializationHelper.isObjectNull(jsonObj.get(key))) {
      jsonObj.remove(key);
      i--;
    }
  }
}

Create the EmployeesPojoDC class.
Go to Projects panel, right-click ViewController project and choose New > Java Class.

restjson-in-maf7

Copy the following code inside EmployeesPojoDC class.

private final String connectionName = "RESTWebServiceConn";
private final String requestURI = "/employees";
private RestServiceUtil restServiceUtil = new RestServiceUtil(connectionName);
private Employee employee;
private List employees = new ArrayList();

public EmployeesPojoDC() {
  super();


public void setEmployee(Employee employee) {
  this.employee = employee;
}

public Employee getEmployee() {
  return employee;
}

public Employee[] getEmployees() {
  return (Employee[]) employees.toArray(new Employee[employees.size()]);
}

public void initEmployeeToAdd() {
  employee = new Employee();
}

public void initEmployeeToEdit(Employee employee) throws CloneNotSupportedException {
  this.employee = (Employee) employee.clone();
}

public void findAll() {
  this.employees.clear();

  try {
    String response = restServiceUtil.invokeFind(requestURI, null);
    Employees employees = (Employees) JSONBeanSerializationHelper.fromJSON(Employees.class, response);
    this.employees.addAll(employees.getEmployeesAsList());

  } catch (Exception e) {
    throw new AdfException(e.getLocalizedMessage(), AdfException.ERROR);
  }
}

public void update(Employee employee) {
  restServiceUtil.invokeUpdate(requestURI, employee);
}

public void create(Employee employee) {
  restServiceUtil.invokeCreate(requestURI, employee);
}

public void delete(Employee employee) {
  restServiceUtil.invokeDelete(requestURI + "/" + employee.getEmployeeId());
}

Create the EmployeesPojoDC Data Control.
Go to Projects panel, right-click EmployeesPojoDC.java file and choose Create Data Control.
In the Create Bean Data Control dialog, click Next and Finish.

restjson-in-maf8

restjson-in-maf9

Open the EmployeesTF.xml file.
Go to Data Controls panel and expand EmployeesPojoDC.
Drag the findAll, initEmployeeToAdd and initEmployeeToEdit operations and drop inside the EmployeesTF.
In the Edit Action Binding dialog, set the value of employee to #{pageFlowScope.employeeSelected}.

restjson-in-maf10

Drag three View and a Router components and drop inside EmployeesTF.
Connect them using the Control Flow Case component.

restjson-in-maf11

Double-click all View components and click OK to create the AMX Pages.

restjson-in-maf12

Click in Router component and configure it like the following image.

restjson-in-maf13

Open the empList page.
Go to Data Control panel, drag the employees collection and drop inside page as MAF List View.
In the ListView Gallery, click Ok twice.

restjson-in-maf14

restjson-in-maf15

Change the empList page like the following image.

restjson-in-maf16

Go to Bindings and edit the employees binding.
Add lastName and firstName as Display Attributes.

restjson-in-maf17

Open the empDetail page.
Go to Data Control panel, drag the employees collection and drop inside page as MAF Read-only Form.
In the Edit Form Fields dialog, click Ok.

restjson-in-maf18

Go to Data Control panel, drag the delete operation and drop inside the secondary facet as MAF Button.
In the Edit Action Binding, set the value of employee to #{bindings.employeesIterator.currentRow.dataProvider}.

restjson-in-maf19

Change the empDetail page like the following image.

restjson-in-maf20

Open the empEdit page.
Go to Data Control panel, drag the employee Structured Attribute and drop inside page as MAF Form.
In the Edit Form Fields dialog, click Ok.

restjson-in-maf21

Go to Data Control panel, drag the create and update operations and drop inside secondary facet as MAF Button.
In the Edit Action Binding, set the value of employee to #{bindings.employeeIterator.currentRow.dataProvider}.

restjson-in-maf22

restjson-in-maf23

Change the empEdit page like the following image.

restjson-in-maf24

Go to Application Resources panel and expand Descriptors > ADF META-INF.
Open the connections.xml file and change the host to 10.0.2.2.
Android uses this host to access your localhost.

restjson-in-maf25

Deploy the application and enjoy!

restjson-in-maf26

restjson-in-maf27

Tweet about this on TwitterShare on Facebook15Share on LinkedIn18Share on Google+0

Author: Waslley Souza

Consultor Oracle com foco em tecnologias Oracle Fusion Middleware e SOA. Certificado Oracle WebCenter Portal, Oracle ADF e Java.

2 thoughts on “REST/JSON in MAF”

  1. Nice article. However, the Web Service would not actually be interacting with the mobile client directly. While the premise for JSON and it’s smaller size is important for mobile, it doesn’t actually pertain to this example. Correct? All the service is doing is working on the server, nothing to do with async calls from the client. Regardless, working with JSON payloads vs SOAP / XML should be a lot faster regardless. Thanks for sharing!

Leave a Reply

Your email address will not be published. Required fields are marked *