XML Basics

XML stands for Extensible Markup Language, which is widely used Message Exchange pattern along with JSON. XML format is similar to HTML, but no predefined tags.

In this post I’ll focus on explaining the concepts for real time usage, instead giving text book definitions.

First let’s see below sample XML code:

2.png

Now let’s see another example where we write employee details for two different organizations.

3.png

In the above example, we have two employee records belong to two different organizations. So we can not use same element name like <employee> for both the organizations. So to overcome this we use the Namespace concept. Here in the example we’ve used two different namespaces for two organizations with the namespace prefixes as ‘orgA’, ‘orgB’ and declared these name spaces at the root element. XML Namespaces provide a method to avoid element name conflicts in an XML document.

If you observe the namespace declaration it seems like an URL, But actually it is  NOT an URL and you can’t open it in browser. You may doubt then why a URL notation is followed for namespace declaration when it is actually not an URL, fact is that it is just a standard that we follow. (If you don’t follow standards you can even declare like xmlns:orgA=“orgA/schemas/Employee”) but is not recommended. 

Now let’s jump into XSD (XML schema document) : 

An XSD document describes the structure of XML document. For the above example we’ll write an XSD document will be as given below.

<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.emp.org" 
 targetNamespace="http://www.emp.org" elementFormDefault="qualified">
 <xsd:element name="Employee">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element name="employee" maxOccurs="unbounded">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element name="name" minOccurs="0" type="xsd:string"/>
 <xsd:element name="id" type="xsd:integer"/>
 <xsd:element name="email" type="xsd:string"/>
 <xsd:element name="phNum" type="xsd:string"/>
 </xsd:sequence>
 </xsd:complexType>
 </xsd:element>
 </xsd:sequence>
 </xsd:complexType>
 </xsd:element>
</xsd:schema>

In the above example if you observe, elements defined as ‘complexType’ are meant that they have child elements. Element <employee> in xml has child elements under it, so its child elements are wrapped in a compleType tag followed by a sequence tag.

4.png

Note: Here in the above image we have element ‘Employee’ and another element ’employee’ under it and then child elements under it. You can directly give all the child elements under element ‘Employee’ instead under element ’employee’.

If you have observed in XSD file there is ‘targetNamespace’ given. Don’t confuse with the Namespace.

  • TargetNamespace is nothing but defining the namespace for all the elements that you define in XML schema.
  • Any element that you define within the schema would be associated with the target namespace. You you’ve defined prefix for the TargetNamesapce then all the elements in the XSD file are associated with the TargetNamesapce using the prefix defined (all element names start with prefixName: followed by element name).
  • If you don’t define target namespace to the Schema, it results in conflicts. So it is advised to give TargetNamesapce always.
  • Each element can have a different namesapce associated with it, but all those elements defined with in the schema should be aligned to a single target namespace. This is just a declaration and make sure you do not use predefined namespace (soap, soap12 etc) for the targetNamespace.

Now let’s see more examples to understand more about XSD:

For the below XML, there are two elements with same name but with different namespace. If you generate XSD out of this XML document using JDeveloper you’ll get an XSD in which you can see only one element is created for both the elements. But this is not correct to use in real time. Better to have a separate declaration for two different <employee> elements in XSD file also.

5.png

You can create an XSD for the above XML as given below also, where two separate elements created though having same name for the elements in XML. This is recommended over above.

6.PNG

In the above example, there are two element with same name (employee), so it is difficult for you to work with this kind of XSD file in SOA. So it is always advisable to have different names. such as employee_orgA, employee_orgB.

7.PNG

 

Now assume if the two element with same name ’employee’ have sub elements with same name and one element has one more extra field, then you can prepare your XSD as given below.

8.png

The source code for the above will be as given below.

<?xml version="1.0" encoding="windows-1252" ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.emp.org" targetNamespace="http://www.emp.org"
 elementFormDefault="qualified">
 <xsd:element name="Employee">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element name="employee_orgA" maxOccurs="unbounded" type="emp_commonType"/>
 <xsd:element name="employee_orgB">
 <xsd:complexType>
 <xsd:sequence>
 <xsd:element name="empCommon" type="emp_commonType"/>
 <xsd:element name="address"/>
 </xsd:sequence>
 </xsd:complexType>
 </xsd:element>
 </xsd:sequence>
 </xsd:complexType>
 </xsd:element>
 <xsd:complexType name="emp_commonType">
 <xsd:sequence>
 <xsd:element name="name" type="xsd:string"/>
 <xsd:element name="id" type="xsd:integer"/>
 <xsd:element name="email" type="xsd:string"/>
 <xsd:element name="phNum" type="xsd:string"/>
 </xsd:sequence>
 </xsd:complexType>
</xsd:schema>

 

Another XSD document for a sample XML document can be created as given below.

9

The above XSD can also be written as given below.

10

 

Advertisements

Proxy Configuration In JDeveloepr

When you are working with webservices in JDeveloper, it won’t recognize the webservices if there is any proxy configured in your system though the Webservice (WSDL) is be accessible from web browser.

So to work with webservices in JDeveloper you need to manually configure the proxy settings in JDeveloper and in web browser as given below.

JDeveloper -> Tools -> Preferences -> Web Browser and Proxy

proxy_jdev1

Browser -> Internet Options -> Connections -> LAN Settings

proxy_browser1

 

 

EXCEPTION_ACCESS_VIOLATION error in JDeveloper 12c

When you run an application (ADF/SOA) in JDeveloper 12c, if you come across below error ‘EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000061c0fc2a, pid=6556, tid=6848’, then to fix the issue you just need to perform few simple steps. This is actually a JVM bug in few version of java (I got this issue with Java version jdk1.8.0 when deploying applications to Integrated weblogic server)

Error Log:


#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x0000000061c0fc2a, pid=6556, tid=6848
#
# JRE version: Java(TM) SE Runtime Environment (8.0-b132) (build 1.8.0-b132)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.0-b70 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# V [jvm.dll+0x23fc2a]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
#

jre_error.PNG

Fix: 

  1. Install latest version of Java (jdk1.8.0_162 worked for me).
  2. Check the JDK version in JDeveloper ‘Help -> About -> Version’. If the version is not latest then close JDeveloper.

jdk_version.PNG

3. Update the file ‘JDEV_HOME/jdeveloepr/jdev/bin/jdev.conf’ file, where update SetJavaHome path with latest jdk version.

SetJavaHome C:\Program Files\Java\jdk1.8.0_162

4. Open JDeveloper and again check the Java version (It should be updated with the version that you mentioned in jdev.conf file) . Now run the application, it should be deployed and able run successfully.

If you find this post useful Hit Like & post your comments. Happy Coding 🙂 

References (IF you want to explore more about issue and the above post doesn’t resolve your issue):

https://confluence.atlassian.com/confkb/java-crash-exception_access_violation-vmthread-235669512.html

https://docs.oracle.com/javase/7/docs/webnotes/tsg/TSG-VM/html/crashes.html/crashes

https://bugs.openjdk.java.net/browse/JDK-8154831

https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8181200

https://windowsreport.com/exception-access-violation-windows-10/

 

 

Invoking REST webservice from JQuery using an AJAX call

Below code helps you to understand how we can Invoke a REST web service on click of a button using JQuery and AJAX.

Note: In Java you can Invoke REST web service using ApacheHTTPClient library.

HTML File:

<!DOCTYPE html>
<html>
<head>
<sscript type=”text/javascript”
src=”http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js”></script&gt;
<sscript type=”text/javascript”>
$(document).ready(function () {
$(“#mybutton”).click(function () {
alert(‘welcome’);

$.ajax( {
type : “GET”, url : “http://services.groupkt.com/country/get/iso2code/IN&#8221;, dataType : “json”, success : function (data) {
alert(“Reading Msg: ” + data.RestResponse.messages);
alert(“Reading Name: ” + data.RestResponse.result.name);
}
});

});

});
</script>
</head>
<body>
<button type=”button” id=”mybutton”>Invoke REST WS</button>
</body>
</html>

Sample REST Services (thanks for making them available to developers for testing purpose):

http://www.groupkt.com/post/c9b0ccb9/country-and-other-related-rest-webservices.htm
http://services.groupkt.com/country/get/iso2code/IN
http://services.groupkt.com/country/get/all
http://rest-service.guides.spring.io/greeting

REST_invoke

Showing Parameters passed in the URL in a page – Oracle ADF

In ADF Application we can read the parameters passed in the URL and display them as an output text using a simple EL (Expression language).

#{param.paramName}

Sample Jspx page:

1

Page in browser:

2If your requirement is to show the URL passed in parameter data in the input text field and if there is no parameter data passed then show it as an input text field, then you can use below given EL which is having the ternary condition.

<af:inputText value=”#{param.dept eq null? bindings.DepartmentId.inputValue: param.dept}” />

Browser output when URL: 

http://127.0.0.1:7101/Application2-ViewController-context-root/faces/home.jspx

3.PNG

Browser output when URL: 

http://127.0.0.1:7101/Application2-ViewController-context-root/faces/home.jspx?dept=Marketing

4.PNG

 

This post is intended to show how the requirement can be fulfilled with the help of EL.

Invoke a WebService with the Inserted Rows data of Excel sheet in ADF-DI:

In ADF-DI you don’t have any direct option available to get the control over all the inserted rows to invoke WS (Web Service). So you must implement it with the help of programmatic approach.

First what you need to understand is, If you want to upload 100 records of data from Excel sheet to DB, first you must set a property [InsertBeforeRowActionID : ‘CreateInsert‘] which means before reading each row of data, a new empty row object is created and the data of that row is stored into that row object cache. The same thing happens for all the rows. Once all the rows of Excel sheet are read, the cached data has to be committed to DB. So set the property [CommitBatchActionID: Commit] which inserts the cached data to DB.

The above properties must be set to upload data to DB from Excel sheet. To achieve this your page definition file must contain the bindings [tree binding, Commit, CreateInsert bindings]

To get the Handle over the Excel sheet data, you must set below proprieties.
Property [InsertBeforeRowActionID : ‘eachRowInvokeAM‘] which is being used to Invoke a custom method where current row data can be read and stored to a List. This will repeat for all the rows.
Then set the property [SuccessActionID : afterAllRowsInvokeAM] for a ribbon command ‘Update‘. This triggers the custom method ‘afterAllRowsInvokeAM’ after successful Insert/Update to DB. In this custom method, you can work with the list which has the data of all rows inserted in the Update operation. Using this data you can Invoke a Web Service.

You must write your custom methods in AMImpl class. ADF12c supports only AMImpl class methods, where as ADF11g supports AMImpl & VOImpl class methods to invoke.

Eg: Let’s take an example, where we insert a record to Departments table. And after all the rows got inserted to DB from ADF-DI Excel sheet a webservice should be invoked with the inserted data as input. For this set the below properties.

InsertBeforeRowActionID : ‘CreateInsert’
InsertBeforeRowActionID : ‘eachRowInvokeAM’
InsertRowEnabled: True
CommitBatchActionID: Commit
RibbonCommand- Update -> SelectActionSet -> ActionOptions -> SuccessActionID : afterAllRowsInvokeAM

Custom methods given above are [‘eachRowInvokeAM’, ‘afterAllRowsInvokeAM’] are mehtods created in AMImpl class .
Another class also created ‘Dept’ which is a Pojo class with the column names as variables and having parameterized constructor.
In the AMImpl class, a list is created of type ‘Dept’ pojo class. And the parameterized constructor is being invoked to insert the department type object to the list. Two custom methods are created in it [‘eachRowInvokeAM’, ‘afterAllRowsInvokeAM’] and are exposed and then added to the page definition file as method bindings. During each row insert ‘eachRowInvokeAM’ will be invoked and that row data in inserted to the List. Once the commit operation is susccessful another method ‘afterAllRowsInvokeAM’ will be invoked where the list data is read and used as input to Invoke the webservice.

The page definition file should be:

ADF-DI_1.PNG

Excel properties should be:

ADF-DI_3

ADF-DI_2

 

AmImpl.java:


package model;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;

import java.net.HttpURLConnection;
import java.net.URL;

import java.util.ArrayList;
import java.util.List;

import model.common.AppModule;

import oracle.jbo.Row;
import oracle.jbo.server.ApplicationModuleImpl;
import oracle.jbo.server.ViewLinkImpl;
import oracle.jbo.server.ViewObjectImpl;

public class AppModuleImpl extends ApplicationModuleImpl implements AppModule {

/* Custom Code */
List dept = new ArrayList();
public void eachRowInvokeAM(){
System.out.println("Entered before Upload..");
System.out.println("row count:"+getDepartmentsView1().getRowCount());
Row r = getDepartmentsView1().getCurrentRow();
System.out.println(r.getAttribute("DepartmentId"));
System.out.println(r.getAttribute("DepartmentName"));
System.out.println(r.getAttribute("LocationId"));
System.out.println(r.getAttribute("ManagerId"));

int deptId = Integer.valueOf(r.getAttribute("DepartmentId").toString());
String deptName = r.getAttribute("DepartmentName").toString();
int locId = Integer.valueOf(r.getAttribute("LocationId").toString());
int mgrId = Integer.valueOf(r.getAttribute("ManagerId").toString());

//adding current row to list
dept.add(new Dept(deptId, deptName, locId, mgrId));
}

public void afterAllRowsInvokeAM() {
System.out.println("after Insert success..");
System.out.println("rows inserted:"+dept.size());
for(int i=0; i< dept.size(); i++){
System.out.println(dept.get(i).getDepartmentId());
System.out.println(dept.get(i).getDepartmentName());
System.out.println(dept.get(i).getLocationId());
System.out.println(dept.get(i).getManagerId());
}
System.out.println("Now Invoking WebService");
try {
http_client();  // Invoke Webserive method
} catch (Exception e) {
}
}

public static void http_client() throws Exception {
System.out.println("Invoke service using direct HTTP call with Basic Auth");
String payload =
"\n" +
" \n" +
" \n" +
" \n" +
" INR\n" +
" USD\n" +
" \n" +
" \n" +
"";

httpPost("http://www.webservicex.net/CurrencyConvertor.asmx" + "?invoke=", payload);
}
private static String httpPost(String destUrl, String postData) throws Exception {
URL url = new URL(destUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
if (conn == null) {
return null;
}
conn.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setFollowRedirects(true);
conn.setAllowUserInteraction(false);
conn.setRequestMethod("POST");

//byte[] authBytes = authStr.getBytes("UTF-8");
//String auth = com.sun.org.apache.xml.internal.security.utils.Base64.encode(authBytes);
// conn.setRequestProperty("Authorization", "Basic " + auth);

System.out.println("post data size:" + postData.length());

OutputStream out = conn.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8");
writer.write(postData);
writer.close();
out.close();

System.out.println("connection status: " + conn.getResponseCode() +
"; connection response: " +
conn.getResponseMessage());

InputStream in = conn.getInputStream();
InputStreamReader iReader = new InputStreamReader(in);
BufferedReader bReader = new BufferedReader(iReader);

String line;
String response = "";
System.out.println("==================Service response: ================ ");
while ((line = bReader.readLine()) != null) {
System.out.println(line);
response += line;
}
iReader.close();
bReader.close();
in.close();
conn.disconnect();

return response;
}

Dept.java:

</pre>
package model; public class Dept { int DepartmentId; String DepartmentName; int LocationId; int ManagerId; public Dept(int DeptId, String DeptName, int LocId, int MgrId) { //super(); this.DepartmentId = DeptId; this.DepartmentName = DeptName; this.LocationId = LocId; this.ManagerId = MgrId; } public void setDepartmentId(int DepartmentId) { this.DepartmentId = DepartmentId; } public int getDepartmentId() { return DepartmentId; } public void setDepartmentName(String DepartmentName) { this.DepartmentName = DepartmentName; } public String getDepartmentName() { return DepartmentName; } public void setLocationId(int LocationId) { this.LocationId = LocationId; } public int getLocationId() { return LocationId; } public void setManagerId(int ManagerId) { this.ManagerId = ManagerId; } public int getManagerId() { return ManagerId; } } 

Your Excel in Design Time:

ADF-DI_4.PNG

Your Excel at run time:

ADF-DI_5


After Click on Ribbon button ‘Upload’, all the rows inserted to DB and also a web service is invoked at back end.

ADF-DI_6

Hope the post is Informative!