I made a little ADF Mobile demo based on the Google Maps Geocoder and use this url to test it
http://maps.googleapis.com/maps/api/geocode/json?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA&sensor=true
with this as result
We start by creating an Url Connection with http://maps.googleapis.com/maps/api/geocode/json as value
Next is a new Class which can be used a managed bean or as a Java DataControl.
Here we do the following steps.
Create the RestServiceAdapter
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
restServiceAdapter.clearRequestProperties();
Use our Url Connection
restServiceAdapter.setConnectionName("GoogleGeocodeJSON");
HTTP Get operartion
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_GET);
Append the url with our search parameters
restServiceAdapter.setRequestURI("?address="+search+"&sensor=true");
Send and wait for the result.
response = restServiceAdapter.send("");
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package nl.amis.rest.model; | |
import oracle.adfmf.dc.ws.rest.RestServiceAdapter; | |
import oracle.adfmf.framework.api.Model; | |
import com.sun.util.logging.Level; | |
import nl.amis.rest.model.maps.GeocoderResultList; | |
import oracle.adfmf.framework.api.JSONBeanSerializationHelper; | |
import oracle.adfmf.util.Utility; | |
import oracle.adfmf.util.logging.Trace; | |
public class MapsClient { | |
public MapsClient() { | |
} | |
private String search = "1600+Amphitheatre+Parkway,+Mountain+View,+CA"; | |
private String result = "empty"; | |
private GeocoderResultList geoResult = null; | |
public void setSearch(String search) { | |
this.search = search; | |
} | |
public String getSearch() { | |
return search; | |
} | |
public void setResult(String result) { | |
this.result = result; | |
} | |
public String getResult() { | |
return result; | |
} | |
public void searchAction() { | |
// Add event code here... | |
Trace.log(Utility.ApplicationLogger, Level.INFO, MapsClient.class, "Mapsclient", "begin2"); | |
System.out.println("begin"); | |
this.result = "called"; | |
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter(); | |
// Clear any previously set request properties, if any | |
restServiceAdapter.clearRequestProperties(); | |
// Set the connection name | |
restServiceAdapter.setConnectionName("GoogleGeocodeJSON"); | |
// Specify the type of request | |
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_GET); | |
restServiceAdapter.addRequestProperty("Content-Type", "application/json"); | |
restServiceAdapter.addRequestProperty("Accept", "application/json; 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("?address="+search+"&sensor=true"); | |
String response = "not found"; | |
JSONBeanSerializationHelper jsonHelper = new JSONBeanSerializationHelper(); | |
try { | |
// For GET request, there is no payload | |
response = restServiceAdapter.send(""); | |
ServiceResult responseObject = (ServiceResult)jsonHelper.fromJSON(ServiceResult.class, response); | |
if ( "OK".equalsIgnoreCase( responseObject.getStatus()) ) { | |
geoResult = GeocoderHelper.transformObject(responseObject).getResults(); | |
} | |
this.result = responseObject.getStatus(); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
this.result = "error"; | |
} | |
} | |
public void setGeoResult(GeocoderResultList geoResult) { | |
this.geoResult = geoResult; | |
} | |
public GeocoderResultList getGeoResult() { | |
return geoResult; | |
} | |
} |
ServiceResult responseObject = (ServiceResult)jsonHelper.fromJSON(ServiceResult.class, response);
ServiceResult class will be used as output, too bad I can't use generics or annotations to control the JSON deserialization. So I will use JSONArray in case of 1 or more results.
import oracle.adfmf.json.JSONArray;
public class ServiceResult {
private String status;
private JSONArray results;
JSONBeanSerializationHelper will look for attributes called .type and if that contains a class name then it will use that class for deserialization but I can't change the Google Maps service.
So I made my own Helper class which converts all JSONArray or JSONObject to the right class and attributes.
geoResult = GeocoderHelper.transformObject(responseObject).getResults();
Here is my the helper class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package nl.amis.rest.model; | |
import nl.amis.rest.model.maps.AddressDetails; | |
import nl.amis.rest.model.maps.GeocodeResponse; | |
import nl.amis.rest.model.maps.GeocoderGeometry; | |
import nl.amis.rest.model.maps.GeocoderResult; | |
import nl.amis.rest.model.maps.GeocoderResultList; | |
import nl.amis.rest.model.maps.LatLng; | |
import nl.amis.rest.model.maps.LatLngBounds; | |
import oracle.adfmf.json.JSONArray; | |
import oracle.adfmf.json.JSONException; | |
import oracle.adfmf.json.JSONObject; | |
public class GeocoderHelper { | |
public GeocoderHelper() { | |
super(); | |
} | |
public static GeocodeResponse transformObject(ServiceResult service) { | |
GeocodeResponse response = new GeocodeResponse(); | |
response.setStatus(service.getStatus()); | |
GeocoderResultList results = new GeocoderResultList(); | |
response.setResults(results); | |
JSONArray resultList = service.getResults(); | |
for ( int i = 0 ; i < resultList.length() ; i++ ) { | |
try { | |
GeocoderResult geoResult = new GeocoderResult(); | |
JSONObject result = resultList.getJSONObject(i); | |
AddressDetails geoAddress = new AddressDetails(); | |
JSONArray addresses = (JSONArray)result.get("address_components"); | |
for ( int m = 0 ; m < addresses.length() ; m++ ) { | |
JSONObject addressObj = addresses.getJSONObject(m); | |
String vLongName = null; | |
String vShortName = null; | |
if (addressObj.getString("long_name") != null ) { | |
vLongName = addressObj.getString("long_name"); | |
} | |
if (addressObj.getString("short_name") != null ) { | |
vShortName = addressObj.getString("short_name"); | |
} | |
if ( addressObj.get("types") != null ) { | |
JSONArray types = (JSONArray)addressObj.get("types"); | |
for ( int p = 0 ; p < types.length() ; p++ ) { | |
String addressType = types.getString(p); | |
if ( "locality".equalsIgnoreCase(addressType) ) { | |
geoAddress.setSubLocality(vShortName); | |
} else if ("administrative_area_level_1".equalsIgnoreCase(addressType)) { | |
geoAddress.setAdministrativeAreaLevel1(vShortName); | |
} else if ("country".equalsIgnoreCase(addressType)) { | |
geoAddress.setCountry(vShortName); | |
} else if ("administrative_area_level_2".equalsIgnoreCase(addressType)) { | |
geoAddress.setLocality(vShortName); | |
} else if ("route".equalsIgnoreCase(addressType)) { | |
geoAddress.setRoute(vShortName); | |
} | |
} | |
} | |
} | |
geoResult.setAddressComponents(geoAddress); | |
if ( result.getString("formatted_address") != null ) { | |
geoResult.setFormattedAddress(result.getString("formatted_address")); | |
} | |
if ( result.get("types") != null ) { | |
JSONArray types = (JSONArray)result.get("types"); | |
String geoType = ""; | |
for ( int p = 0 ; p < types.length() ; p++ ) { | |
geoType += types.get(p) + ","; | |
} | |
geoResult.setTypes(geoType); | |
} | |
results.AddGeocoderResult(geoResult); | |
if ( result.get("geometry") != null ) { | |
JSONObject geometry = (JSONObject)result.get("geometry"); | |
GeocoderGeometry geo = new GeocoderGeometry(); | |
if (geometry.getString("location_type") != null ) { | |
geo.setLocationType(geometry.getString("location_type")); | |
} | |
if (geometry.get("location") != null ) { | |
JSONObject location = (JSONObject)geometry.get("location"); | |
LatLng latLng = new LatLng(); | |
latLng.setLat( location.getDouble("lat") ); | |
latLng.setLng( location.getDouble("lng") ); | |
geo.setLocation(latLng); | |
} | |
if (geometry.get("viewport") != null ) { | |
LatLngBounds bounds = new LatLngBounds(); | |
JSONObject viewport = (JSONObject)geometry.get("viewport"); | |
if ( viewport.get("northeast") != null ) { | |
JSONObject northeast = (JSONObject)viewport.get("northeast"); | |
LatLng latLngNorth = new LatLng(); | |
latLngNorth.setLat( northeast.getDouble("lat") ); | |
latLngNorth.setLng( northeast.getDouble("lng") ); | |
bounds.setNortheast(latLngNorth); | |
} | |
if ( viewport.get("southwest") != null ) { | |
JSONObject southWest = (JSONObject)viewport.get("southwest"); | |
LatLng latLngSouth = new LatLng(); | |
latLngSouth.setLat( southWest.getDouble("lat") ); | |
latLngSouth.setLng( southWest.getDouble("lng") ); | |
bounds.setSouthwest(latLngSouth); | |
} | |
geo.setViewport(bounds); | |
} | |
geoResult.setGeometry(geo); | |
} | |
} catch (JSONException e) { | |
e.printStackTrace(); | |
} | |
} | |
return response; | |
} | |
} |
Now we are ready to use it in a managed bean or generate an ADF DataControl on it.
with this as result.
You can find my demo code on Github https://github.com/biemond/jdev11gR2_examples/tree/master/MapsMobileRest
Here the pictures of the application in the IPad emulator.
Hey regarding this json web service call, how to ignore certificate warnings?
ReplyDeletehttps://forums.oracle.com/forums/thread.jspa?threadID=2466149
Hi Edwin.!
ReplyDeleteNeed a help!
i have a 30mb xml file which has 3 ubounded elements into into
like
orderheaderdetils is just complex type
order----- list----listof itemes
in an order we get number of listitemnames(list)ubounded and listofitems(descriptions)ubounded
the file size is increasing.. upto.. 30mb
loading in bpel is itself consuming lot of time and processing to database is still more taking lot of time.
and this cannot be controlled from senders end also..
is there any idea that we can.. split before sending to bpel.
coz we have many root elements we cannot batch it equally..
so.. any help will be helpfull
Hi,
DeleteCan you use OSB and do a split join or try to do the same in a memory BPEL and use a for each parallel async invoke.
thanks