August 31, 2014

A Handy Method of Accessing Data in Remote http Server in Java

In Java projects, sometimes accessing data in remote http server is required. The data can be of xml format or json format. The following will compare two accessing methods through an example.

Here is a servlet which provides employee information query in json format. servlet accesses the employee table in the database and stores the data of employees as follows:
EID   NAME       SURNAME        GENDER  STATE        BIRTHDAY        HIREDATE         DEPT         SALARY
1       Rebecca   Moore      F       California 1974-11-20       2005-03-11       R&D          7000
2       Ashley      Wilson      F       New York 1980-07-19       2008-03-16       Finance    11000
3       Rachel      Johnson   F       New Mexico     1970-12-17       2010-12-01       Sales         9000
4       Emily         Smith        F       Texas        1985-03-07       2006-08-15       HR    7000
5       Ashley      Smith        F       Texas        1975-05-13       2004-07-30       R&D          16000
6       Matthew Johnson   M     California 1984-07-07       2005-07-07       Sales         11000
7       Alexis        Smith        F       Illinois       1972-08-16       2002-08-16       Sales         9000
8       Megan     Wilson      F       California 1979-04-19       1984-04-19       Marketing        11000
9       Victoria    Davis        F       Texas        1983-12-07       2009-12-07       HR    3000
servelet'sdoGet function receives the employee id string of json format, queries corresponding employee information in the database, generates an employee information list of json format and return it. The following code omits the process of accessing the database and generating the employee information list:

protected void doGet(HttpServletRequestreq, HttpServletResponseresp) throws ServletException, IOException {
         String inputString=(String) req.getParameter("input");
         //the input value of inputString is"[{EID:8},{EID:32},{EID:44}]";
         if (inputString==null) inputString="";
         String outputString ="";
        
         {...}//here the code of generating outputString through inputString’s queryof the database is omitted
         //the code of generated outputString is
//"[{EID:8,NAME:"Megan",SURNAME:"Wilson",GENDER:"F",STATE:\...";
         resp.getOutputStream().println(outputString);
         resp.setContentType("text/json"); 
}

Java will access this http servlet, get the employee information in which EID is 1 and 2, and then sort the records of information by EID in descending order. Detailed steps are as follows:
1. Import an open source project httpclient to access servlet and get the result.
2. Import an open source project json-lib to parse the returned strings.
3. Use comparison method to sort by EID in descending order.

The sample code is a follows:
public static voidmyHTTP() throws Exception {
                   // the following defines http’s url
                   URL url =
new URL("http://localhost:6080/myweb/servlet/testServlet?input=[{EID:1},{EID:2}]");
                   URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), null);
                   //then send a request from http and receive the returned result
                   CloseableHttpClient client = HttpClients.createDefault();
                   HttpGet get = new HttpGet(uri);
                   CloseableHttpResponse response = client.execute(get);
                   String myJson=EntityUtils.toString(response.getEntity());
                   //then parse the imported data into json object
         JSONArrayjsonArr = JSONArray.fromObject(myJson );
             //then sort the json data (in descending order)
         JSONObjectjObject = null;
                   for(inti = 0;i<jsonArr.size();i++){
                            long l = Long.parseLong(jsonArr.getJSONObject(i).get("EID").toString());
                            for(int j = i+1; j<jsonArr.size();j++){
                                               longnl = Long.parseLong(jsonArr.getJSONObject(j).get("EID").toString());
                                               if(l<nl){
                                                        jObject = jsonArr.getJSONObject(j);
                                                        jsonArr.set(j, jsonArr.getJSONObject(i));
                                                        jsonArr.set(i, jObject);
                                               }
                            }
                   }
                   System.out.println(jsonArr.toString());
         }

The open source project json-lib needs to be imported. The jars necessary for its function are:
         json-lib-2.4-jdk15.jar
         ezmorph-1.0.6.jar
         commons-lang.jar
         commons-beanutils.jar
         commons-logging.jar
         commons-collections.jar


Import the open source project httpclient. The jars necessary for its function are:
            commons-codec-1.6.jar
            commons-logging-1.1.3.jar
            fluent-hc-4.3.5.jar
            httpclient-4.3.5.jar
            httpclient-cache-4.3.5.jar
            httpcore-4.3.2.jar
            httpmime-4.3.5.jar

As can be seen from this example, Java needs to import two open source projects to complete its job. By the way, the jars may have overlapping parts. In addition, myHTTP function's operation for accessing and sorting http data is not universal enough. When it is required to sort in ascending order or according to more than one field, the program has to be modified. To make myHTTP function more universal and as flexible as SQL in accessing and processing data, dynamic analysis of expressions should be achieved, which will produce rather complicated code.

The method in accessing and processing http data in Java can be replaced by the cooperative work of Java and esProc. The advantage of this cooperation is that only one project will be imported in order to realize dynamic accessing and sorting with simple code. esProc can getand compute data from a remote http server conveniently. To achieve the dynamic processing, the expression for sorting could be sent to esProc as a parameter. Please see the figure below:

The value of the parameter sortBy is EID:-1. The program for esProc to access http data contains only six lines of code as follows:


A1Define the input parameters to be sent to servlet, that is, the employee id list of json format.

A2: Define anhttpfile object, the URL is http://localhost:6080/myweb/servlet/testServlet?input=[{EID:1},{EID:2}].

A3Import the result returned by httpfile object in A2.

A4Parse one by one each employee’s information of json format, and generates a sequence.

A5Sort the data. esProc will first compute the parameter sortBy in macro ${sortBy}, and then execute the resulting statement A4.sort(EID:-1) which means sorting by EID in descending order.

A6Return the result in A5 to the Java code that called this piece of esProc program.

If the fields and method for sorting are changed, the program needn’t to be modified. We just need to change the parameter sortBy. For example, sort by EID in ascending order and by name in descending order. In this case, what we need is to change the value of sortBy to EID:1,NAME:-1. The sorting statement we finally execute is A4.sort(EID:1,NAME:-1).

This piece of esProc program can be called conveniently in Java using jdbc provided by esProc. To save the above esProc program as file test.dfx, Jave need to call the following code:

          // create a connection between esProc and jdbc
Class.forName("com.esproc.jdbc.InternalDriver");
con= DriverManager.getConnection("jdbc:esproc:local://");
//call esProc program (the stored procedure) in which test is the name of filedfx
com.esproc.jdbc.InternalCStatementst;
st =(com.esproc.jdbc.InternalCStatement)con.prepareCall("call test(?)");
// set parameters
st.setObject(1,"EID:1,NAME:-1");//esProc’s input parameters, that is, the dynamic expression for sorting
// execute esProc stored procedure
ResultSet set=st.executeQuery();
while(set.next()) System.out.println("EID="+set.getInt("EID"));

As the esProc code in this example is relatively simple and can be called directly in Java, it is unnecessary to write the esProc script file (like the above-mentioned test.dfx). Thus the code will be written in this way:
st=(com. esproc.jdbc.InternalCStatement)con.createStatement();
ResultSet set=st.executeQuery("=httpfile(\"http://localhost:6080/myweb/servlet/testServlet?input=[{EID:1},{EID:2}]\").read().import@j().sort(EID:1,NAME:-1)");

The above Java code directly called a line of esProc statement, that is, read data from http serverand sort them by specified fields and return the result ResultSet to Java.