15 Using Web Services in MAF AMX

This chapter describes how to integrate a third-party web service into the MAF AMX application feature implementation.

This chapter includes the following sections:

15.1 Introduction to Using Web Services in MAF Applications

Web services allow applications and their features to exchange data and information through defined application programming interfaces. Using web services you can expose business functionality irrespective of the platform or language of the originating application because the business functionality is exposed in such a way that it is abstracted to a message composed of standard XML constructs that can be recognized and used by other applications.

In a MAF application, you use web services to interact with remote data sources. In particular:

  • To query data in remote data sources.

  • To write data to and from remote data sources.

Some of the most typical use cases for employing web services in MAF applications are:

  • To add functionality that is readily available as a web service, but which would be time-consuming to develop within the application.

  • To provide access to an application that runs on a different architecture.

Using web services in your MAF application enables you to do the following:

  • Choose from a subset of functionality exposed on the web service. Since you cannot request more enterprise data than offered by the web services, you can deal with the limitation of which enterprise data can and cannot be accessed by reducing the number of application features exposed in a web service data control.

  • Provide functionality that is too computationally intensive for the mobile device's resources. This could be due to either the actual amount of work the device would need to perform, or the fact that the functionality is based on a much larger data set than the one that is locally available on the device.

    Note:

    You may consider outsourcing the computationally intensive functionality to the service (the server side).

MAF supports consumption of both SOAP and REST web services. Before deciding which type to use, consider the following:

  • SOAP with its large payloads and verbose XML schemas can have an impact on performance of your MAF application. It is recommended to either use REST web services (if available) or inject a middleware solution such as Oracle Service Bus (see http://www.oracle.com/technetwork/middleware/service-bus/overview/index.html) to transform payloads from SOAP to REST JSON.

  • Since MAF is not an extract, transform and load tool (ETL), you would have to write code to accommodate complex web service payloads, which would result in decreased performance as well as code complexity. Using a middleware solution such as Oracle Service Bus can help with shaping the data payloads suitable for mobile environment.

The following web service scenarios usage demonstrate the data access (scenario 1) as well as computational and data-driven functionality (scenarios 2 and 3):

  • Fetch a set of Opportunity data from the enterprise data store to enable the end user to manipulate it on the device, and then post changes back to the enterprise data store through the web service.

  • Request a report be generated on some enterprise data, and then fetch the report.

  • Obtain a map image of a route to a customer site.

The most common way of using web services in an application feature developed with MAF is to create a data control for an external web service. For more information, see the following:

15.2 Creating a Web Service Data Control Using REST

JDeveloper lets you create a data control for an existing REST web service. This REST web service returns an XML response.

Note:

If you are working behind a firewall and you want to use a web service that is outside the firewall, you must configure the Web Browser and Proxy settings in JDeveloper. For more information, see Configuring the Browser Proxy Information.

You can associate a REST web service data control with one or more HTTP methods using the same connection. You should be able to access custom operations exposed by a REST service. These custom operations mat to one of the HTTP methods and allow you to create a data control to expose these custom operations on the client.

To use security and notifications functionality on mobile devices, you can add custom headers and custom values to standard HTTP headers for use with specific operations exposed by the REST data control.

Before you begin:

Ensure that you have access to the REST web service that the data control is to access.

To create a REST web service data control:

  1. In the Applications window, right-click the application name, and then select File > New > From Gallery from the main JDeveloper menu.

  2. In the New Gallery dialog, expand the Business Tier node on the left and select Web Services. From the Items list on the right select Web Service Data Control (SOAP/REST) (see Figure 15-4), and then click OK.

  3. On the Data Source page of the Create Web Service Data Control wizard, select REST, as Figure 15-1 shows.

    Figure 15-1 Defining Data Source for REST Web Service Data Control

    This image is described in the surrounding text

  4. Follow the Create Web Service Data Control wizard instructions to complete creation of the data control, keeping in mind the following:

    • MAF supports only basic authentication for web services (see Accessing Secure Web Services). When creating a new connection, select Basic in the Authentication Type field on the Create URL Connection dialog.

    • MAF supports all HTTP method types: GET, POST, PUT, and DELETE. You can select any of these method types when completing the Method Display Name fields on the Resources page, as Figure 15-2 shows.

      Note:

      You can include all four methods using the same connection and the same REST web service data control.

      Figure 15-2 Defining Resources for REST Web Service Data Control

      This image is described in the surrounding text
    • For each resource method on the Method Details page (see Figure 15-3), you must provide an XSD file reference for the XML payload and response content. The XSD has to be available as a file in the ViewController project.

      Figure 15-3 Defining Method Details for REST Web Service Data Control

      This image is described in the surrounding text

      Note:

      Since MAF creates internal definitions for the XSD structures at compile time, the XSD should not change after the application has been compiled. Therefore, it is recommended to reference the XSD file locally, which also provides a benefit of allowing to use a MAF application offline.

      Using the remote XSD negatively affects performance because MAF retrieves the XSD with each run of the application.

After the REST web services data control has been created by following the preceding steps, it behaves identically to its counterparts provided by other technologies available through JDeveloper.

A MAF sample application called RESTDemo (located in the PublicSamples.zip file within the jdev_install/jdeveloper/jdev/extensions/oracle.maf/Samples directory on your development computer) demonstrates how to use REST web services in a MAF application.

For information on how to use REST web services through Java bypassing data controls, see How to Use REST Web Services Adapter.

15.3 Creating a Web Service Data Control Using SOAP

JDeveloper lets you create a data control for an existing SOAP web service using only the Web Services Description Language (WSDL) file for the service. You can either browse to a WSDL file on the local file system, locate one in a Universal Description, Discovery and Integration (UDDI) registry, or enter the WSDL URL directly.

Note:

If you are working behind a firewall and you want to use a web service that is outside the firewall, you must configure the Web Browser and Proxy settings in JDeveloper. For more information, see Configuring the Browser Proxy Information.

To create a SOAP web service data control:

  1. In the Applications window, right-click the application name, and then select File > New > From Gallery from the main JDeveloper menu.

  2. In the New Gallery dialog, expand the Business Tier node on the left and select Web Services. From the Items list on the right select Web Service Data Control (SOAP/REST) (see Figure 15-4), and then click OK.

    Figure 15-4 Creating a New SOAP Web Service Data Control

    This image is described in the surrounding text

  3. On the Data Source page of the Create Web Service Data Control wizard, select SOAP.

  4. Follow the wizard instructions to complete creation of the data control.

Note:

MAF supports the following encoding styles for both SOAP 1.1 and 1.2 versions:

  • Document/literal

  • Document/wrapped

  • RPC

15.3.1 How to Customize SOAP Headers

MAF allows you to specify a custom provider class in your DataControls.dcx file. This custom class extends oracle.adfinternal.model.adapter.webservice.provider.soap.SOAPProvider. You can use it to specify an implementation of the SoapHeader[] getAdditionalSoapHeaders() method.

The following example shows how to extend the SOAPProvider and create a custom header demonstrated in the next example.

package provider.ebs.soap; 

import oracle.adfinternal.model.adapter.webservice.provider.soap.SOAPProvider;
import oracle.adfinternal.model.adapter.webservice.provider.soap.SoapHeader;

public class EBSSOAPProvider extends SOAPProvider {

public SoapHeader[] getAdditionalSoapHeaders() {
   SoapHeader header[] = new SoapHeader[2]; 
   SoapHeader token = null; 
   SoapHeader user = null; 
   SoapHeader pass = null; 

   header[0] = new SoapHeader("http://xmlns.oracle.com/apps/fnd/soaprovider/plsql/fnd_user_pkg/",
                              "SOAHeader"); 
   header[0].addChild(new SoapHeader(
                              "http://xmlns.oracle.com/apps/fnd/soaprovider/plsql/fnd_user_pkg/",
                              "Responsibility",
                              "SYSTEM_ADMINISTRATOR"));
   header[0].addChild(new SoapHeader(
                              "http://xmlns.oracle.com/apps/fnd/soaprovider/plsql/fnd_user_pkg/",
                              "RespApplication",
                              "SYSADMIN")); 
   header[0].addChild(new SoapHeader(
                              "http://xmlns.oracle.com/apps/fnd/soaprovider/plsql/fnd_user_pkg/",
                              "SecurityGroup",
                              "STANDARD"));
   header[0].addChild(new SoapHeader(
                              "http://xmlns.oracle.com/apps/fnd/soaprovider/plsql/fnd_user_pkg/",
                              "NLSLanguage", 
                              "AMERICAN")); 
   header[0].addChild(new SoapHeader(
                              "http://xmlns.oracle.com/apps/fnd/soaprovider/plsql/fnd_user_pkg/",
                              "Org_Id", 
                              "0"));

   header[1] = new SoapHeader(
               "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
               "Security");
   token = new SoapHeader(
              "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
              "UsernameToken");
   user = new SoapHeader(
              "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
              "Username",
              "sysadmin");
   pass = new SoapHeader(
              "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",
              "Password",
              "sysadmin");

   header[1].addChild(token);
   token.addChild(user);
   token.addChild(pass); 

   return header;
   }
}

The following example shows the new custom header.

<soap:Header xmlns:ns1="http://xmlns.oracle.com/apps/fnd/soaprovider/plsql/fnd_user_pkg/">
   <ns1:SOAHeader> 
      <ns1:Responsibility>SYSTEM_ADMINISTRATOR</ns1:Responsibility>
      <ns1:RespApplication>SYSADMIN</ns1:RespApplication>
      <ns1:SecurityGroup>STANDARD</ns1:SecurityGroup>
      <ns1:NLSLanguage>AMERICAN</ns1:NLSLanguage>
      <ns1:Org_Id>0</ns1:Org_Id>
   </ns1:SOAHeader>
   <wsse:Security xmlns:wsse=
      "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
      xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
      xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" 
      soap:mustUnderstand="1">
      <wsse:UsernameToken xmlns:wsse=
      "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" 
      xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
         <wsse:Username>sysadmin</wsse:Username>
         <wsse:Password Type=
          http://docs.oasis-open.org/wss/2004/01/
          oasis-200401-wss-username-token-profile-1.0#PasswordText">sysadmin</wsse:Password>
      </wsse:UsernameToken>
   </wsse:Security>
</soap:Header>

@return

Note:

There is no predefined mechanism for passing variables into a class that extends SOAPProvider. Standard Java techniques should be sufficient. For example, you can add member variables and accessors to the class; then you can refer to them when setting the SoapHeader[] content returned by the getAdditionalSoapHeaders() method.

The following example demonstrates a sample DataControls.dcx file entry with the SOAPProvider registration.

<definition xmlns="http://xmlns.oracle.com/adfm/adapter/webservice"
                   name="SoapService" version="1.0"
                   provider="provider.ebs.soap.EBSSOAPProvider"
                   wsdl="http://@SRG_WS_HOST@:@SRG_WS_PORT@/SoapService/SoapServicePort?wsdl" >
   <service name="SoapService" namespace="http://model/"
            connection="SoapService"> 
      <port name="SoapServicePort">
         <operation name="echoSoapHeader"/>
      </port> 
   </service>
</definition>

Note:

You cannot specify dynamic SOAP headers using MAF.

15.3.2 How to Access Objects Returned by SOAP Calls

JDeveloper adds a dcStructureVersion property to the DataControls.dcx file for every web service data control created from a SOAP service reference. By default, this property is set to 2.

Tip:

If your application was developed using one of the previous versions of MAF and you intend to continue using the same code to access the response from Java, you should remove this property or change its value to 1.

The dcStructureVersion property serves customization purposes and impacts the structure of the result returned by the web service data control.

To access an object returned from a SOAP call, you should use code similar to the following:

result = (GenericType)AdfmfJavaUtilities.invokeDataControlMethod("WeatherSOAP",
                                         null,
                                         "GetCityWeatherByZIP",
                                         pnames,
                                         pvals,
                                         ptypes);
// access SOAP object to obtain information about the returned object
result.get("City");

When working with collections, consider using code similar to the following:

result = (GenericType)AdfmfJavaUtilities.invokeDataControlMethod("WeatherSOAP", 
                                         null,
                                         "GetCityWeatherByZIP", 
                                         pnames, 
                                         pvals, 
                                         ptypes);
result = result!=null && result.getParent()!=null ? result.getParent() : result;

15.4 What You May Need to Know About Web Service Data Controls

After the web service data control has been created, the web service operations and return values of the operations are displayed in the Data Controls window, as illustrated in Figure 15-5.

Figure 15-5 Web Service Data Control

The surrounding text describes this image.

Like other data controls, you can drag and drop the objects returned by the web service operations to create user interface components in a MAF AMX page. For more information, see How to Add Data Controls to a MAF AMX Page. When data returned from a web service operation is displayed, the following object types are handled:

  • Collections

  • Complex objects returned by a web service operation

  • Nested complex objects returned by a web service operation

Using a web service operation, both standard and complex data types can be updated and deleted.

As illustrated by Figure 15-5, each data control object is represented by an icon. Table 15-1 describes what each icon represents, where it appears in the Data Controls panel hierarchy, and what components it can be used to create. For more information see Creating Databound UI Components from the Data Controls Panel.


Table 15-1 Data Controls Panel Icons and Object Hierarchy for Web Services

Icon Name Description Used to Create...
The surrounding text describes this image.

Data Control

Represents a data control. You cannot use the data control itself to create UI components, but you can use any of the child objects listed under it. Typically, there is one data control for each web service.

Serves as a container for other objects and is not used to create anything.

The surrounding text describes this image.

Collection

Represents a data collection returned by an operation on the service. Collections also appear as children under method returns, other collections, or structured attributes. The children under a collection may be attributes, other collections, custom methods, and built-in operations that can be performed on the collection.

Forms, tables, graphs, trees, range navigation components, and master-detail components. See also Providing Data Visualization.

The surrounding text describes this image.

Attribute

Represents a discrete data element in an object (for example, an attribute in a row). Attributes appear as children under the collections or method returns to which they belong.

Label, text field, date, list of values, and selection list components. See also Designing the Page Layout.

The surrounding text describes this image.

Structured Attribute

Represents a returned object that is a complex type but not a collection. For example, a structured attribute might represent a single user assigned to the current service request.

Label, text field, date, list of values, and selection list components. See also Designing the Page Layout.

The surrounding text describes this image.

Method

Represents an operation in the data control or one of its exposed structures that may accept parameters, perform some business logic and optionally return single value, a structure or a collection of those.

Command components.

For methods that accept parameters: command components and parameterized forms. See also Creating and Using UI Components.

The surrounding text describes this image.

Method Return

Represents an object that is returned by a web service method. The returned object can be a single value or a collection.

A method return appears as a child under the method that returns it. The objects that appear as children under a method return can be attributes of the collection, other methods that perform actions related to the parent collection, and operations that can be performed on the parent collection.

When a single-value method return is dropped, the method is not invoked automatically by the framework. You should either drop the corresponding method as a button to invoke the method, or if working with task flows you can create a method activity for it.

The same components as for collections and attributes and for query forms.

The surrounding text describes this image.

Operation

Represents a built-in data control operation that performs actions on the parent object. Data control operations are located in an Operations node under collections. If an operation requires one or more parameters, they are listed in a Parameters node under the operation.

The following operations for navigation and setting the current row are supported: First, Last, Next, Previous, setCurrentRowWithKey, and SetCurrentRowWithKeyValue. Execute is supported for refreshing queries. Create and Delete are available as applicable, depending on the web service operation. Because the web service data controls are not transactional, Commit and Rollback are not supported.

User interface command components, such as buttons, links, and menus. For more information, see Creating and Using UI Components.

The surrounding text describes this image.

Parameter

Represents a parameter value that is declared by the method or operation under which it appears. Parameters appear in the Parameters node under a method or operation.

Array and structured parameters are exposed as updatable structured attributes and collections under the data control, which can be dropped as an ADF form or an updatable table on the UI. You can use the UI to build a parameter that is an array or a complex object (not a standard Java type).

Label, text, and selection list components. For more information, see How to Use List View and List Item Components.


15.5 Creating a New Web Service Connection

The connection information for the web service is stored in the connections.xml file along with the other connections in your application. You do not need to explicitly create this file, as it is generated in the.adf/META-INF directory by the New Web Service Data Control wizard at the time when the web service data control is created (see Creating a Web Service Data Control Using REST and Creating a Web Service Data Control Using SOAP).

You modify the connection settings by editing the connections.xml file.

15.6 Adjusting the End Point for a Web Service Data Control

After creating a web service data control, you can modify the end point of the URI. This is useful in such cases as when you migrate an application feature from a test to production environment.

You modify the end point by editing the connections.xml file.

15.7 Accessing Secure Web Services

MAF supports both secured and unsecured web services. For more information, see Securing MAF Applications.

When a SOAP web service is secured, you must associate the SOAP connection with the predefined security policy that supports the SOAP web service. Table 15-2 lists the predefined security policies that you can associate with SOAP web services.

Table 15-2 Security Policies Supported for SOAP-Based Web Services

Authentication Type REST Policy Description

HTTP Basic

oracle/http_basic_auth_over_ssl_client_policy

This policy includes credentials in the HTTP header for outbound client requests. This policy verifies that the transport protocol is HTTPS. Requests over a non-HTTPS transport protocol are refused. This policy can be enforced on any HTTP-based client endpoint.

HTTP Basic

oracle/wss_http_token_client_policy

This policy includes credentials in the HTTP header for outbound client requests. This policy can be enforced on any HTTP-based client.

HTTP Basic

oracle/wss_http_token_over_ssl_client_policy

This policy includes credentials in the HTTP header for outbound client requests and authenticates users against the Oracle Platform Security Services identity store. This policy also verifies that the transport protocol is HTTPS. Requests over a non-HTTPS transport protocol are refused. This policy can be enforced on any HTTP-based client.

HTTP Basic

oracle/wss_username_token_client_policy

This policy includes credentials in the WS-Security UsernameToken SOAP header for all outbound SOAP request messages. Both plain text and digest mechanisms are supported. This policy can be attached to any SOAP-based client.

HTTP Basic

oracle/wss_username_token_over_ssl_client_policy

This policy includes credentials in the WS-Security UsernameToken header in outbound SOAP request messages. The policy verifies that the transport protocol provides SSL message protection. Both plain text and digest mechanisms are supported. This policy can be attached to any SOAP-based client.

When a REST web service is secured, you must associate the REST connection with the predefined security policy that supports the REST web service. Table 15-3 lists the predefined security policies that you can associate with REST web services.

Table 15-3 Security Policies Supported for REST-Based Web Services

Authentication Type REST Policy Description

HTTP Basic

oracle/wss_http_token_over_ssl_client_policy

This policy includes credentials in the HTTP header for outbound client requests and authenticates users against the Oracle Platform Security Services identity store. This policy also verifies that the transport protocol is HTTPS. Requests over a non-HTTPS transport protocol are refused. This policy can be enforced on any HTTP-based client.

HTTP Basic

oracle/wss_http_token_client_policy

This policy includes credentials in the HTTP header for outbound client requests. This policy can be enforced on any HTTP-based or HTTPS-based client.

HTTP Basic

oracle/wss_http_token_over_ssl_client_policy

This policy includes credentials in the HTTP header for outbound client requests and authenticates users against the Oracle Platform Security Services identity store. This policy also verifies that the transport protocol is HTTPS. Requests over a non-HTTPS transport protocol are refused. This policy can be enforced on any HTTP-based client.

HTTP Basic

Web SSO and Mobile-Social

oracle/http_cookie_client_policy

This policy injects cookies obtained after authentication in the HTTP request header, e.g: accessing OAM Webgate resources. This policy also sets response cookies. This policy can be enforced on any REST-based client.

OAuth

oracle/http_oauth2_token_mobile_client_policy

This policy injects bearer token (OAuth access token) in the HTTP request header while communicating with the endpoint. This token can be obtained from any OAuth2 server. This policy can be enforced on any REST-based client.

For more information on these policies and their usage, see the Determining Which Predefined Policies to Use and Predefined Policies chapters in Securing Web Services and Managing Policies with Oracle Web Services Manager.

15.7.1 How to Enable Access to Web Services

When a web service is secured and expects an authentication token, you must associate the connection with the predefined security policy that supports the web service. For a list of predefined security policies are supported for the authentication type available for SOAP-based and REST-based web services, see Accessing Secure Web Services.

Before you begin:

To associate a security policy with a web service:

  1. In the Navigator, expand the Descriptors node and then ADF META-INF, and double-click maf-application.xml. Then, in the overview editor for the maf-application.xml file, expand the Security - Web Services Security Policies section and choose the web service connection that you created in the Name field.
  2. In the Login Server Connection field, choose the login server connection that you defined.
  3. In the Policy field, double-click the Edit Policy icon button and in the Edit Data Control Policies dialog, select the policy that you want to associate with the service for the current web service connection and click OK.
    Figure 15-6 shows the policy associated with RESTConnection1, RESTConnection2, and SOAPConnection1.

    For a list of the security policies that you may select in the Edit Data Control dialog and associated with either a SOAP-based web service or a REST-based web service, see Accessing Secure Web Services.

    Figure 15-6 Associating a Security Policy with a Web Service Connection

    This image is described in the surrounding text

15.7.2 What Happens When You Enable Access to Web Services

JDeveloper stores the web service policy definitions in the wsm-assembly.xml file (located in META-INF directory of the application workspace).

You can view the security policy already associated with the REST web service using the Edit Data Control Policies dialog shown in Figure 15-7. Click Override Properties to invoke a dialog where you can specify alternative values for properties that the selected policy permits you to override.

Figure 15-7 Editing Web Service Data Control Policies

This image is described in the surrounding text.

15.7.3 What You May Need to Know About Accessing Web Services and Containerized MAF Applications

When the MAF application is containerized at deployment time, access to secured web services behind the corporate firewall will rely on the Mobile Security Access Server (MSAS), a component in the Oracle Mobile Security Suite (OMSS), to provide a central access point for securing traffic from mobile devices to corporate resources. In this case, the MSAS instance is configured to enforce an authentication endpoint for use in the initial authentication of the user.

Additionally, the backend service endpoints must be associated 1.) with a MSAS proxy application that ensures the URL of the resource is protected by an access policy that MSAS enforces and 2.) a client policy that MSAS adds to the proxied request, for example Single Sign-On (SSO).

In order to allow the MAF application to communicate with MSAS, the user installs and registers a Secure Workspace app for the type of authentication that has been configured for the MSAS instance. Then when the user attempts to access a protected resource, the MAF application and the Secure Workspace rely on a MSAS-generated Proxy Auto-Configuration file to determine which requests to proxy using the MSAS AppTunnel.

For more information about the role of MSAS AppTunnel in the authentication process of containerized MAF applications, see Overview of the Authentication Process for Containerized MAF Applications.

For an overview of OMSS support for containerized MAF applications, see Containerizing a MAF Application for Enterprise Distribution.

In the OMSS documentation library, see Policy and Assertion Template Reference for Oracle Mobile Security Access Server for reference information about MSAS predefined security and management policies.

15.7.4 What You May Need to Know About Credential Injection

For secured web services, the user credentials are dynamically injected into a web service request at the time when the request is invoked. This process is similar for SOAP and REST web services.

MAF uses Oracle Web Services Manager (OWSM) Mobile Agent to propagate user identity through web service requests.

Before web services are invoked, the user must respond to an authentication prompt triggered by the user trying to invoke a secured MAF application feature. The user credentials are stored in a credential store—a device-native and local repository used for storing credentials associated with the authentication provider's server URL and the user. At runtime, MAF assumes that all credentials have already been stored in the IDM Mobile credential store before the time of their usage.

In the connections.xml file, you have to specify the login server connection's adfCredentialStoreKey attribute value in the adfCredentialStoreKey attribute of the web service connection reference in order to associate the login server to the web service security (see the following two examples).

Note:

Since JDeveloper does not provide an Overview editor for the connections.xml file, you can use the Properties window to update the <Reference> element's adfcredentialStoreKey attribute with the name configured for the adfCredentialStoreKey attribute of the login server connection. Alternatively, you can add or update the attribute using the Source editor.

The following example shows the definition of the web service connection referenced as adfCredentialStoreKey="MyAuth", where MyAuth is the name of the login connection reference.

<Reference name="URLConnection1"
           className="oracle.adf.model.connection.url.HttpURLConnection"
           adfCredentialStoreKey="MyAuth"
           xmlns="">
   <Factory className="oracle.adf.model.connection.url.URLConnectionFactory"/>
   <RefAddresses>
      <XmlRefAddr addrType="URLConnection1">
         <Contents>
            <urlconnection name="URLConnection1"
                           url="http://myhost.us.example.com:7777/
                                SecureRESTWebService1/Echo">
               <authentication style="challange">
                  <type>basic</type>
                  <realm>myrealm</realm>
               </authentication>
            </urlconnection>
         </Contents>
      </XmlRefAddr>
      <SecureRefAddr addrType="username"/>
      <SecureRefAddr addrType="password"/>
   </RefAddresses>
</Reference>

The following example shows the definition of the login connection, where MyAuth is used as the credential store key value in the login server connection.

<Reference name="MyAuthName"
           className="oracle.adf.model.connection.adfmf.LoginConnection"
           adfCredentialStoreKey="MyAuth"
           partial="false"
           manageInOracleEnterpriseManager="true"
           deployable="true"
           xmlns="">
   <Factory className="oracle.adf.model.connection.adfmf.LoginConnectionFactory"/>
   <RefAddresses>
      <XmlRefAddr addrType="adfmfLogin">
         <Contents>
            <login url="http://172.31.255.255:7777/
                        SecuredWeb1-ViewController-context-root/faces/view1.jsf"/>
            <logout url="http://172.31.255.255:7777/
                        SecuredWeb1-ViewController-context-root/faces/view1.jsf"/>
            <accessControl url="http://myhost.us.example.com:7777/
                           UserObjects/jersey/getUserObjects" />
            <idleTimeout value="10"/>
            <sessionTimeout value="36000"/>
            <userObjectFilter>
               <role name="testuser1_role1"/>
               <role name="testuser2_role1"/>
               <privilege name="testuser1_priv1"/>
               <privilege name="testuser2_priv1"/>
               <privilege name="testuser2_priv2"/>
            </userObjectFilter>
         </Contents>
      </XmlRefAddr>
   </RefAddresses>
</Reference>

If a web service request is rejected due to the authentication failure, MAF returns an appropriate exception and invokes an appropriate action (see Using and Configuring Logging). If none of the existing exceptions correctly represent the condition, a new exception is added.

The connections.xml file is deployed and managed under the Configuration Service. For more information, see Configuring End Points Used in MAF Applications .

connections.xml files in FARs are aggregated when the MAF application is deployed. The credentials represent deployment-specific data and are not expected to be stored in FARs.

15.7.5 What You May Need to Know About Cookie Injection

Each time a MAF application requests a REST web service for cookie-based authorization, MAF's security framework enables the transport layer of the REST web service to execute cookie injection for the login connection associated with the URL endpoint of the REST web service. This is handled at runtime without configuration of the MAF application by the MAF developer.

15.7.6 Limitations of Secure WSDL File Usage

Since a MAF application must make a WSDL file accessible at run time without authentication, you cannot use a secure WSDL file with a SOAP web service secured by the basic authentication.

If your intention is to secure the WSDL, consider the following: since the WSDL file is fetched by the GET method of the web service, if you secure each web service method, except the GET method, you can use a secure WSDL. If you secure the GET method, you should not secure the WSDL.

15.8 Invoking Web Services From Java

In your MAF application, you can invoke the web services layer (both REST and SOAP) from the Java code and use the results in Java methods.

MAF provides the GenericTypeBeanSerializationHelper utility class that you can use to perform conversions between POJOs (JavaBeans objects) and MAF's GenericType objects based on the following set of conversion rules:

  1. When converting from POJO to GenericType objects:

    • Standard JavaBeans reflection rules are used for determining properties.

    • Transient properties are ignored in the conversion process.

    • Readable properties are converted into a GenericType attribute.

    • Array properties are represented as repeated attributes in the GenericType.

    • Map properties are represented as individual attributes in the GenericType.

    • Non-primitive properties are represented as nested GenericType objects.

  2. When converting from GenericType objects to POJO:

    • Standard JavaBeans reflection rules are used for determining properties.

    • Transient properties are ignored in the conversion process.

    • Writable properties are converted from GenericType attributes.

    • Repeated attributes in the GenericType are converted into an array object.

    • If the POJO implements the Map interface, then any properties that cannot be set through standard accessors are set in the POJO through the set method of the Map.

    • Non-primitive attributes are represented as nested POJO objects.

The advantage of using this helper API is that it allows you to take the response received from a web service and convert it to a JavaBean in a single call.

For example, a web service passes back and forth an Employee object that needs to be reused throughout the business logic. This object has the following set of properties:

  • name of type String

  • address: a complex object with street, city, state, and zipcode attributes

  • id of type long

  • salary of type float

  • phone of type String, and there could be more than one phone

  • password of type String, and the password should never be transmitted to the back-end web service

The following example shows a potential code for the Employee object.

public class Employee {

   protected String name;
   protected Address address;
   protected long id;
   protected float salary;
   protected String[] phone;
   protected transient String password;

   public String getName() {
      return name; 
   }

   public void setName(String name) {
      this.name = name;  
   }

   public Address getAddress() {
      return address;
   }

   public void setAddress(Address address) {
      this.address = address; 
   }

   public long getId() {
      return id; 
   }

   public void setId(long id) {
      this.id = id;
   }

   public float getSalary() {
      return salary; 
   }

   public void setSalary(float salary) {
      this.salary = salary; 
   }

   public String getPassword() {
      return password;
   }

   public void setPassword(String password) {
      this.password = password;
   }

   public void setPassword(String password) {
      this.password = password; 
   }

   public String[] getPhone() {
      return phone;  
   }

   public void setPhone(String phone) {
      this.phone = phone;  
   }

The following example shows the potential code for the Address object of the Employee class.

public class Address {

   protected String street;
   protected String city;
   protected String state;
   protected String zipcode;

   public String getStreet() {
      return street; 
   }

   public void setStreet(String street) {
      this.street = street;  
   }

   public String getCity() {
      return city; 
   }

   public void setCity(String city)  {
      this.city = city;  
   }

   public String getState() {
      return state; 
   }

   public void setState(String state) {
      this.state = state;  
   }

   public String getZipcode() {
      return zipcode; 
   }

   public void setZipcode(String zipcode)  {
      this.zipcode = zipcode;  
   }

Keeping in mind the conversion rules, note the following:

  1. Since the password is defined as transient, it is ignored with respect to the conversion algorithm.

  2. Since name, address, id, and salary all have get and set methods, they will all be converted to and from the GenericType.

  3. Based on the property type, properties can be coerced between types, as defined in the coerceToType(Object, Class) method of the oracle.adfmf.misc.Converter class.

  4. Complex objects, such as address, are recursed by the conversion algorithm to either build the child GenericType or to create and populate the POJO complex object depending on the direction of the conversion.

  5. Since phone is an array of String objects each representing a unique phone number and since the cardinality of this element is greater than one, the conversion algorithm will find all matches of the phone attribute in the GenericType object, present them as an array, and invoke the setPhone method on the bean. The toGenericType method of the GenericTypeBeanSerializationHandler will take each array element and append it to the toGenericType as an individual phone attribute.

With the following defined:

final String EMPLOYEE_VIRTUAL_BEAN_NAME = "EmployeeDC.Types.Employee";
Employee emp = getEmployee();
GenericType gt = null;
  • The Employee object is converted to the GenericType as:

    gt = GenericTypeBeanSerializationHelper.toGenericType
                                     (EMPLOYEE_VIRTUAL_BEAN_NAME, emp);
    
  • The GenericType is converted to the Employee object as:

    emp = GenericTypeBeanSerializationHelper.fromGenericType
                                      (Employee.class, gt, null);
    

For successful conversion, consider the following:

  • Typically, POJOs closely follow their associated GenericType structure.

  • When deviating from the GenericType structure, one of the following strategies should be followed:

    1. Additional bean properties should be declared transient.

    2. Optional properties can be excluded from the POJO, provided that the backing service can handle the missing data if used as an operation parameter.

  • The GenericType is only exposed in SOAP data controls. The virtual types have an associated virtual bean name that is passed into the toGenericType method. You can access the virtual bean name by hovering over the virtual type in the Data Controls window of JDeveloper. The typical name format is <DCName>.Types.<methodName>.<argName>.

For more information, see Java API Reference for Oracle Mobile Application Framework.

15.8.1 How to Add and Delete Rows on Web Services Objects

MAF allows you to insert and delete rows from a web services object programmatically by accessing the iterator on that object. To do so, you use the createRow and deleteRow methods of the oracle.adfmf.bindings.iterator.BasicIterator class.

The following example shows how to add a row to a web services object.

String keyFieldNames[] = {"EMPLID","ACAD_CAREER","INSTITUTION"};
String keyFieldValues[] = {"SR12030","UGRD","PSUNV"};
AmxAccessorIteratorBinding  acIter =
   (AmxAccessorIteratorBinding)((AdfmfJavaUtilities.getValueExpression
                                ("#{bindings.KEYIterator}", Object.class))
                                .getValue(AdfmfJavaUtilities.getAdfELContext()));

BasicIterator iter = acIter.getIterator(); 
GenericType key = (GenericType)iter.getDataProvider();
key.setAttribute("FIELDNAME", keyFieldNames[0]); 
key.setAttribute("FIELDVALUE", keyFieldValues[0]);

int totalRowCount = 0;
int currIndex = 0;

for (int i = 1; i < keyFieldNames.length; i++) {
   totalRowCount = iter.getTotalRowCount();
   currIndex = iter.getCurrentIndex();

   System.out.println("Starting to add rows.. \n\t Total Row Count: " +
                      totalRowCount + "\n\t Current Row Index: " + currIndex);

   // Create rows for key iterator
   iter.createRow();

   totalRowCount = iter.getTotalRowCount();
   System.out.println("\t Total Row Count after creating row: " + totalRowCount);

   if (iter.hasNext()) {
      iter.next();    
   }

   currIndex = iter.getCurrentIndex();
   System.out.println("\t Current Row Index after setting current 
                      index to newly added row: " + currIndex);

   GenericType key1 = (GenericType)iter.getDataProvider();
   key1.setAttribute("FIELDNAME", keyFieldNames[i]);
   key1.setAttribute("FIELDVALUE", keyFieldValues[i]);
}

// Execute method

// Add call to execute the action binding to execute the action. 
// If this is a web service call, the modified GenericType object 
// will be sent to the server and the server will respond appropriately

Note:

The createRow method signatures are available with and without a boolean input parameter. When this method is used without parameters, it produces the result identical to using the createRow with its boolean parameter value set to true: both createRow() and createRow(true) create a new row and insert it in the iterator.

15.8.2 How to Use REST Web Services Adapter

You can use the oracle.adfmf.dc.ws.rest.RestServiceAdapter interface to access data (that could be presented as JavaScript Object Notation, for example) sent across a REST call. The 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.

To use the RestServiceAdapter interface in your MAF application, ensure that the connection exists in the connections.xml file (see Creating a New Web Service Connection), and then add your code to the bean class, as the following examples show.

The following example demonstrates the use of the RestServiceAdapter for the GET request.

RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();

// Clear any previously set request properties, if any
restServiceAdapter.clearRequestProperties();

// Set the connection name
restServiceAdapter.setConnectionName("RestServerEndpoint");

// Specify the type of request
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_GET);

// 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("/WebService/Departments/100");

String response = "";

// Execute SEND and RECEIVE operation
try {
   // For GET request, there is no payload
   response = restServiceAdapter.send("");
}
catch (Exception e) {
   e.printStackTrace();
}

The following example demonstrates the use of the RestServiceAdapter for the POST request.

String id = "111";
String name = "TestName111";
String location = "TestLocation111";
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();

restServiceAdapter.clearRequestProperties();
restServiceAdapter.setConnectionName("RestServerEndpoint");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_POST);
restServiceAdapter.setRetryLimit(0);
restServiceAdapter.setRequestURI("/WebService/Departments");

String response = "";

// Execute SEND and RECEIVE operation
try {
   String postData = makeDepartmentPost("DEPT", id, name, location);
   response = restServiceAdapter.send(postData);
}
catch (Exception e) {
   e.printStackTrace();
}
System.out.println("The response is:  " + response);

private String makeDepartmentPost(String rootName, String id, 
                                  String name, String location) {
   String ret = "<" + rootName + ">";
   ret += "<DEPTID>" + id + "</DEPTID>";
   ret += "<NAME>" + name + "</NAME>";
   ret += "<LOCATION>" + location + "</LOCATION>";
   ret += "</" + rootName + ">";
   return ret;
}

The following example demonstrates the use of the RestServiceAdapter for the PUT request.

String id = "111";
String name = "TestName111";
String location = "TestLocation111";
RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();

restServiceAdapter.clearRequestProperties();
restServiceAdapter.setConnectionName("RestServerEndpoint");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_PUT);
restServiceAdapter.setRetryLimit(0);
restServiceAdapter.setRequestURI("/WebService/Departments");

String response = "";

// Execute SEND and RECEIVE operation
try {
   String putData = makeDepartmentPut("DEPT", id, name, location);
   response = restServiceAdapter.send(putData);
}
catch (Exception e) {
   e.printStackTrace();
}
System.out.println("The response is:  " + response);

private String makeDepartmentPut(String rootName, String id, 
                                  String name, String location) {
   String ret = "<" + rootName + ">";
   ret += "<DEPTID>" + id + "</DEPTID>";
   ret += "<NAME>" + name + "</NAME>";
   ret += "<LOCATION>" + location + "</LOCATION>";
   ret += "</" + rootName + ">";
   return ret;
}

The following example demonstrates the use of the RestServiceAdapter for the DELETE request.

RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();

restServiceAdapter.clearRequestProperties();
restServiceAdapter.setConnectionName("RestServerEndpoint");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_DELETE);
restServiceAdapter.setRetryLimit(0);
restServiceAdapter.setRequestURI("/WebService/Departments/44");

String response = "";

// Execute SEND and RECEIVE operation
try {
   // For DELETE request, there is no payload
   response = restServiceAdapter.send("");
}
catch (Exception e) {
   e.printStackTrace();
}

System.out.println("The response is:  " + response);

When you use the RestServiceAdapter, you should set the Accept and Content-Type headers to ensure that your request and response payloads are not deemed invalid due to mismatched MIME type.

Note:

The REST web service adapter only supports UTF-8 character set on MAF applications. UTF-8 is embedded in the adapter program.

15.8.2.1 Accessing Input and Output Streams

You can use the following RestServiceAdapter methods to obtain and customize the javax.microedition.io.HttpConnection, as well as access and interact with the connection's input and output streams which allows you to read data from the HttpConnection and write to it for further upload to the server:

  • Get an HttpConnection:

    HttpConnection getHttpConnection(String requestMethod, 
                                     String request, 
                                     Object httpHeadersValue)
    
  • Get the HttpConnection's OutputStream:

    OutputStream getOutputStream(HttpConnection connection) 
    
  • Get the HttpConnection's InputStream:

    InputStream getInputStream(HttpConnection connection)
    
  • Close the HttpConnection:

    void close (HttpConnection connection)
    
  • Look up a connection name in the connections.xml file and return the connection's end point:

    String getConnectionEndPoint(String connecionName)
    

These methods, while accomplishing the same functionality as the RestServiceAdaper's send and sendReceive methods, provide opportunity for customization of the connection and the process of sending requests and receiving responses.

The following example initializes and returns an HttpConnection using the provided request method, request, and HTTP headers value. In addition, it injects basic authentication into the request headers from the credential store, obtains the input stream and closes the connection.

RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();

restServiceAdapter.clearRequestProperties();

// Specify the type of request
String requestMethod = RestServiceAdapter.REQUEST_TYPE_GET;

// Get the connection end point from connections.xml
String requestEndPoint = restServiceAdapter.getConnectionEndPoint("GeoIP");

// Get the URI which is defined after the end point
String requestURI = "/xml/" + someIpAddress;

// The request is the end point + the URI being set
String request = requestEndPoint + requestURI;

// Specify some custom request headers
HashMap httpHeadersValue = new HashMap();
httpHeadersValue.put("Accept-Language", "en-US");
httpHeadersValue.put("My-Custom-Header-Item", "CustomItem1");

// Get the connection
HttpConnection connection = 
                  restServiceAdapter.getHttpConnection(requestMethod,
                                                       request,
                                                       httpHeadersValue);

// Get the input stream
InputStream inputStream = restServiceAdapter.getInputStream(connection);

// Define data
ByteArrayOutputStream byStream = new ByteArrayOutputStream();

int res = 0;
int bufsize = 0, bufread = 0;

byte[] data = (bufsize > 0) ? new byte[bufsize] : new byte[1024];

// Use the input stream to read data
while ((res = inputStream.read(data)) > 0) {
   byStream.write(data, 0, res);
   bufread = bufread + res;
}
data = byStream.toByteArray();

// Use data 
...

restServiceAdapter.close(connection);
...

15.8.2.2 Support for Non-Text Responses

You can use the RestServiceAdapter to handle binary (non-text) responses received from web service calls. These responses can include any type of binary data, such as PDF or video files. The RestServiceAdapter method to use is sendReceive.

The following example shows how to send a request for a file to a REST server, and then save the file to a disk.

RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();

restServiceAdapter.clearRequestProperties();
restServiceAdapter.setConnectionName("JagRestServerEndpoint");
restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_GET);
restServiceAdapter.setRetryLimit(0);
restServiceAdapter.setRequestURI("/ftaServer/v1/kpis/123/related/1");

// Set credentials needed to access the REST server 
String theUsername = "hr_spec_all";
String thePassword = "Welcome1"; 
String userPassword = theUsername + ":" + thePassword;
String encoding = new sun.misc.BASE64Encoder().encode(userPassword.getBytes());

restServiceAdapter.addRequestProperty("Authorization", "Basic " + encoding);

// Execute the SEND and RECEIVE operation.
// Since it is a GET request, there is no payload.
try {
   this.responseRaw = restServiceAdapter.sendReceive("");
}
catch (Exception e) {
   e.printStackTrace();
}
System.out.println("The response is:  " + this.responseRaw);

// Write the response to a file
writeByteArrayToFile(this.responseRaw);

The following example demonstrates a method that is called by the code from the preceding example. This method saves a byte[] response to a file on disk:

public void writeByteArrayToFile(byte[] fileContent) {
   BufferedOutputStream bos = null;
   try {
      FileOutputStream fos = new FileOutputStream(new File(fileToSavePath));
      bos = new BufferedOutputStream(fos);
      // Write the byte [] to a file 
      System.out.println("Writing byte array to file");
      bos.write(fileContent);
      System.out.println("File written");
   }
   catch(FileNotFoundException fnfe) {
      System.out.println("Specified file not found" + fnfe);
   }
   catch (IOException ioe) {
      System.out.println("Error while writing file" + ioe);
   }
   finally {
      if(bos != null) {
         try {
            // Flush the BufferedOutputStream
            bos.flush();
            // Close the BufferedOutputStream
            bos.close();
         }
         catch (Exception e) {
         }
      }
   }
}

15.8.3 How to Enable Strict Validation of REST Responses

Using the maf-config.xml file, you can specify how MAF is to behave when a REST response contains a child or attribute that is not expected or defined in the XSD:

  • If the strict validation is enabled, MAF throws an exception.

  • If the strict validation is disabled, the condition is logged and the execution continues without exceptions thrown.

The following example shows how to set the validated parameter. If you define the value of this parameter as true, the validation proceeds as strict. The value of false (default) means that the validation is not strict.

<generic-type>
   <conversion>
      <validated>true</validated>
   </conversion> 
</generic-type>

15.8.4 How to Process JSON Responses

In addition to XML, a REST web service that you use in your MAF application can accommodate a message specified in a JavaScript Object Notation (JSON) format.

A MAF sample application called RESTDemo (located in the PublicSamples.zip file within the jdev_install/jdeveloper/jdev/extensions/oracle.maf/Samples directory on your development computer) includes the RESTJSONBean.java file that demonstrates how the RestServiceAdapter described in detail in How to Use REST Web Services Adapter enables the use of JSON as a message format for REST web services

The RESTJSONResponse.java file that is also included in the RESTDemo represents the JSON message and is converted to an appropriate format using the fromJSON method of the JSONBeanSerializationHelper class.

The RESTJSONBean's loadData method shown in the following example demonstrates how to use the relevant APIs.

public class RESTJSONBean {
...
   public void setResponse(RESTJSONResponse response) {
      RESTJSONResponse oldResponse = this.response;
      this.response = response;
      propertyChangeSupport.firePropertyChange("response", oldResponse, response);
   }
   
   public void loadData() {
      RestServiceAdapter restServiceAdapter = Model.createRestServiceAdapter();
   
      // Clear previously set request properties, if any
      restServiceAdapter.clearRequestProperties();
   
      // Set the connection name
      restServiceAdapter.setConnectionName("GeoIP");
   
      // Specify the type of request
      restServiceAdapter.setRequestType(RestServiceAdapter.REQUEST_TYPE_GET);
   
      // 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("/json/" + getSearchIp());
   
      setJsonResponse("");
   
      // Execute SEND and RECEIVE operation
      try {
         // For GET request, there is no payload
         setJsonResponse(restServiceAdapter.send(""));
   
         // Create a new RESTJSONResponse object and 
         // parse the returned JSON string into this class
         RESTJSONResponse res = new RESTJSONResponse();
         res = (RESTJSONResponse)JSONBeanSerializationHelper.
                fromJSON(RESTJSONResponse.class, getJsonResponse());
         setResponse(res);
      }
      catch (Exception e) {
         e.printStackTrace();
      }
   }
...
}

For additional information and examples, see the tutorial called Consuming REST-JSON Web Services in Mobile Applications with Oracle Mobile Application Framework.

15.8.5 What You May Need to Know About Invoking Data Control Operations

You can use the invokeDataControlMethod method of the AdfmfJavaUtilities to invoke a data control operation which does not have to be explicitly added as a methodAction in a PageDef file.

For more information and examples, see Java API Reference for Oracle Mobile Application Framework.

15.9 Understanding Limitations Related to MAF Support for JavaScript

Since MAF REST web service client does not support JavaScript, REST exchanges that require execution of JavaScript cannot be successfully processed by MAF applications. That is, a server response that expects the client to execute JavaScript cannot be completed. Your MAF application cannot include code to indirectly retrieve a web page that requires JavaScript support in order to complete the original request through redirection.

The following is an acceptable scenario on web browsers because most of them support JavaScript. However, it would not produce the desired outcome if used within a MAF application:

An application requests for data using REST web service and the application server redirects the request to the authentication server. The authentication server serves a web page that, in turn, redirects to another page, and then redirects back to the original REST end point. In the redirect sequence, one of the web pages that is served by the authentication server expects the client to execute a JavaScript and authenticates the end user against the application server.

15.10 Configuring the Browser Proxy Information

If the web service you are to call resides outside your corporate firewall, you need to ensure that you have set the appropriate Java system properties to configure the use of an HTTP proxy server.

By default, MAF determines the proxy information using the system settings on iOS and Android platforms. For example, if the proxy information is set using the Settings utility on an iOS-powered device, then JVM automatically absorbs it.

Note:

It is possible to define a different proxy for each MAF application.

If you do not want to obtain the proxy information from the device settings, first you need to add the -Dcom.oracle.net.httpProxySource system property. The default value of this property is native, which means that the proxy information is to be obtained from the device settings. You need to disable it by specifying a different value, such as user, for example: -Dcom.oracle.net.httpProxySource=user

JVM uses two different mechanisms for enabling the network connection:

  1. The generic connection framework (GCF). If this mechanism is used, the proxy is defined through the system property -Dcom.sun.cdc.io.http.proxy=<host>:<port>

  2. java.net API. If this mechanism is used, the proxy is defined through the standard http.proxyHost and http.proxyPort.

In either case, it is recommended to define all three properties in the maf.properties file, which would look similar to the following:

java.commandline.argument=-Dcom.oracle.net.httpProxySource=user
java.commandline.argument=-Dcom.sun.cdc.io.http.proxy=www-proxy.us.mycompany.com:80
java.commandline.argument=-Dhttp.proxyHost=www-proxy.us.mycompany.com
java.commandline.argument=-Dhttp.proxyPort=80

Note:

These properties affect only the JVM side of network calls.