We can follow MAF tutorial http://docs.oracle.com/cd/E53569_01/tutorials/tut_jdev_maf_json/tut_jdev_maf_json.html to invoke a REST service using MAF infrastructure.
In this blog I am just trying to add how we can call SECURED REST service, which requires HTTP Basic authentication.
Before going for actual blog, few lines about tutorial api to execute REST.
Basic approach in tutorial is
a. MAF page will invoke a datacontrol method
b. Create URL for REST request
c. Call REST service
d. Populate POJO objects using REST response
e. Return POJO objects
Main code to invoke REST service looks like
private String invokeRestRequest(String httpMethod, String requestURI, String payload){
String restPayload = "";
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
restServiceAdapter.setConnectionName("REST-Public"); //Change it as per your connection name
//set GET, POST, DELETE, PUT
restServiceAdapter.setRequestType(httpMethod);
//this sample uses JSON only. Thus the media type can be hard-coded in this class
//the content-type tells the server what format the incoming payload has
restServiceAdapter.addRequestProperty("Content-Type", "application/json");
//the accept header indicates the expected payload fromat to the server
restServiceAdapter.addRequestProperty("Accept", "application/json; charset=UTF-8");
restServiceAdapter.setRequestURI(requestURI);
restServiceAdapter.setRetryLimit(0);
//variable holding the response
String response = "";
//set payload if there is payload passed with the request
if(payload != null){
//send with empty payload
restPayload = payload;
}
try {
response = (String)restServiceAdapter.send(restPayload);
} catch (Exception e) {
//log error
Trace.log("REST_JSON",Level.SEVERE, this.getClass(),"invokeRestRequest", "Invoke of REST Resource failed for "+httpMethod+" to "+requestURI);
Trace.log("REST_JSON",Level.SEVERE, this.getClass(),"invokeRestRequest", e.getLocalizedMessage());
}
return response;
};
OK, now what if service is secured and needs HTTP authentication.
When a REST service needs authentication we need to add 'Authrization' entry in http header.
Authorization: Basic a3Zlcm1hQGtiYWNlLmNvbTpLYmFjZUAwMDE=
It means if we know username and password we can concatenate them as username:password and then somehow get base64 encoding. Once we have that we can append it with word 'Basic' and set complete string as a value for 'Authorization'. Simple
Only tricky part is getting base64 encoding. We have multiple ways to get base64 encoded string.
Solution 1: Using Java API:
We can use below lines of code to add 'Authorization' in request
String base64 = null;
String cred = "sanjeev" + ":" + "myPassword";
try {
base64 = Base64.getEncoder().encodeToString(cred.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
//Handle your exception
}
restServiceAdapter.addRequestProperty("Authorization", "Basic " + base64);
After this you should be able to call HTTP basic secured REST service. You will require to import java.util.Base64 class.
I think this class is added in java8 so it may not work if have older version of java installed in your mobile.
Solution 2: Using JavaScript api
Another solution could be to use javascript api to get base64 encoding. We have javascript api btoa available that can encode a string. For this approach we need to following these steps
a. Create js file: Create a javascript file and add following lines in it
base64encode = function (){
var input = arguments[0];
return window.btoa(input);
}
b. Register js against a feature: In feature.xml file add js file against the feature which needs base64 encoding
c. Call js from java code
String cred = "sanjeev" + ":" + "myPassword";
String base64 = (String)AdfmfContainerUtilities.invokeContainerJavaScriptFunction("Test",
"base64encode", new Object[] {cred});
restServiceAdapter.addRequestProperty("Authorization", "Basic " + base64);
For simplicity I have hard coded username/password within method but you can accept them as a parameter to make method more generic.
In this blog I am just trying to add how we can call SECURED REST service, which requires HTTP Basic authentication.
Before going for actual blog, few lines about tutorial api to execute REST.
Basic approach in tutorial is
a. MAF page will invoke a datacontrol method
b. Create URL for REST request
c. Call REST service
d. Populate POJO objects using REST response
e. Return POJO objects
Main code to invoke REST service looks like
private String invokeRestRequest(String httpMethod, String requestURI, String payload){
String restPayload = "";
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
restServiceAdapter.setConnectionName("REST-Public"); //Change it as per your connection name
//set GET, POST, DELETE, PUT
restServiceAdapter.setRequestType(httpMethod);
//this sample uses JSON only. Thus the media type can be hard-coded in this class
//the content-type tells the server what format the incoming payload has
restServiceAdapter.addRequestProperty("Content-Type", "application/json");
//the accept header indicates the expected payload fromat to the server
restServiceAdapter.addRequestProperty("Accept", "application/json; charset=UTF-8");
restServiceAdapter.setRequestURI(requestURI);
restServiceAdapter.setRetryLimit(0);
//variable holding the response
String response = "";
//set payload if there is payload passed with the request
if(payload != null){
//send with empty payload
restPayload = payload;
}
try {
response = (String)restServiceAdapter.send(restPayload);
} catch (Exception e) {
//log error
Trace.log("REST_JSON",Level.SEVERE, this.getClass(),"invokeRestRequest", "Invoke of REST Resource failed for "+httpMethod+" to "+requestURI);
Trace.log("REST_JSON",Level.SEVERE, this.getClass(),"invokeRestRequest", e.getLocalizedMessage());
}
return response;
};
OK, now what if service is secured and needs HTTP authentication.
When a REST service needs authentication we need to add 'Authrization' entry in http header.
Authorization: Basic a3Zlcm1hQGtiYWNlLmNvbTpLYmFjZUAwMDE=
It means if we know username and password we can concatenate them as username:password and then somehow get base64 encoding. Once we have that we can append it with word 'Basic' and set complete string as a value for 'Authorization'. Simple
Only tricky part is getting base64 encoding. We have multiple ways to get base64 encoded string.
Solution 1: Using Java API:
We can use below lines of code to add 'Authorization' in request
String base64 = null;
String cred = "sanjeev" + ":" + "myPassword";
try {
base64 = Base64.getEncoder().encodeToString(cred.getBytes("utf-8"));
} catch (UnsupportedEncodingException e) {
//Handle your exception
}
restServiceAdapter.addRequestProperty("Authorization", "Basic " + base64);
After this you should be able to call HTTP basic secured REST service. You will require to import java.util.Base64 class.
I think this class is added in java8 so it may not work if have older version of java installed in your mobile.
Solution 2: Using JavaScript api
Another solution could be to use javascript api to get base64 encoding. We have javascript api btoa available that can encode a string. For this approach we need to following these steps
a. Create js file: Create a javascript file and add following lines in it
base64encode = function (){
var input = arguments[0];
return window.btoa(input);
}
b. Register js against a feature: In feature.xml file add js file against the feature which needs base64 encoding
c. Call js from java code
String cred = "sanjeev" + ":" + "myPassword";
String base64 = (String)AdfmfContainerUtilities.invokeContainerJavaScriptFunction("Test",
"base64encode", new Object[] {cred});
restServiceAdapter.addRequestProperty("Authorization", "Basic " + base64);
For simplicity I have hard coded username/password within method but you can accept them as a parameter to make method more generic.