Search code examples
javapostgresqljdbcjsonbstruts2-json-plugin

Trouble in getting JSON data from PostgreSQL


I have a database table with JSONB datatype as one of the column. My application is in Struts2 which uses struts2-json.jar to map deal the request and response as JSON.

The problem I am facing is that i wish to send the JSON data from a table column as JSON array in the response. However i end up sending the data as Hash-literal.

When the method returns SUCCESS,there's a HashMap associated which is used to return the data as JSON.

I am putting the name of column as key and the value of that column as value for that key in the HashMap.

However, when struts2-json library is converting the value of the JSON key as follows.

{
"status":"success",
"data":[
{
"sem_votes_allowed":{
"type":"jsonb",
"value":"{\"sem_votes_allowed\": [{\"E1\": \"100\", \"E2\": \"200\"}]}"
},
"uvp_even_id":{
"type":"jsonb",
"value":"[\"E1\", \"E2\"]"
},
"usm_x_mobile_no":null,
"usm_pin_no":null,
"sem_first_even_flag":null,
"sem_holdings":{
"type":"jsonb",
"value":"{\"sem_holdings\": [{\"E1\": \"100\", \"E2\": \"200\"}]}"
}
}
],
"action":"sc/get_shareholder_list",
"statusmsg":"Share holder list",
"statuscode":"E_OK"
}

And the response i wish to send is

{
"status":"success",
"data":[
{
"sem_votes_allowed":{
"sem_votes_allowed":[
{
"E1":"100",
"E2":"200"
}
]
},
"uvp_even_id":[
"E1",
"E2"
],
"usm_x_mobile_no":null,
"usm_pin_no":null,
"sem_first_even_flag":null,
"sem_holdings":{
"sem_holdings":[
{
"E1":"10",
"E2":"200"
}
]
}
}
],
"action":"sc/get_shareholder_list",
"statusmsg":"Share holder list",
"statuscode":"E_OK"
}

"sem_votes_allowed" , "uvp_even_id", and "sem_holdings" are the columns in the table with datatype as JSONB.

Below is the code snippet where in the HashMap is getting populated.

ResultSetMetaData rsmd = rs.getMetaData();
        int numColumns = rsmd.getColumnCount();

        while (rs.next()) {
        HashMap<String, Object> record = new HashMap<String, Object>();
        for (int i = 1; i < numColumns + 1; i++) {
            String columnName = rsmd.getColumnName(i);
            record.put(columnName, rs.getObject(columnName));

        }
        out.add(record); // ArrayList out
        }

shareDataMap is an instance member and has its getter and setter

HashMap <String,Object> shareDataMap = new HashMap<>();
 shareDataLs = conn.executeQuery(query, params);
        System.out.println("shareDataLs: " + shareDataLs);
        shareDataMap.put(Constants.SUCCESS, Constants.SUCCESS);
        shareDataMap.put(Constants.DATA, shareDataLs);

This is the code snippet in struts.xml

<action name="get_shareholder_list" method="shareHldrLs"
            class="co.merce.instapoll.ui.ShareHldrAction">
            <result type="json" name="success">
                <param name="root">shareDataMap</param>
            </result>
        </action>

It would be really helpful if anybody can show me the workaround to achieve this.

Thanks in advance.


Solution

  • I achieved this by de-serializing it with GSON api.

     ResultSetMetaData rsmd = rs.getMetaData();
            int numColumns = rsmd.getColumnCount();
    
            while (rs.next()) {
            HashMap<String, Object> record = new HashMap<String, Object>();
            for (int i = 1; i < numColumns + 1; i++) {
                String columnName = rsmd.getColumnName(i);
    
                //MODIFIED BY LALIT RAO @ 29-07-2015
                //THE BELOW CODE DESERIALIZES THE JSON ARRAY AND HASH-VALUE INTO JAVA STRING FOR struts2-json jar to convert it back to json in  response.
    
                if (columnName.equalsIgnoreCase("sem_holdings") || columnName.equalsIgnoreCase("sem_votes_allowed") || columnName.equalsIgnoreCase("gc_even_desc")){
    
                System.out.println("Inside Map<String, ArrayList<HashMap<String,String>>> if block");
                Map<String, ArrayList<HashMap<String,String>>> retMap = new Gson().fromJson(rs.getString(columnName), new TypeToken<HashMap<String, ArrayList<HashMap<String,String>>>>() {}.getType());
                    record.put(columnName, retMap);
                }
                else if (columnName.equalsIgnoreCase("sem_ev_id") || columnName.equalsIgnoreCase("uvp_even_id") || columnName.equalsIgnoreCase("gc_ev_id")){
    
                System.out.println("Inside List <String> else-if block");
                List <String> retList = new Gson().fromJson(rs.getString(columnName), new TypeToken<List<String>>() {}.getType());
                    record.put(columnName, retList);
                }
                else
                record.put(columnName, rs.getObject(columnName));
    
            }
            out.add(record); // ArrayList out
            }
    

    and the response which was sent back to AngularJS is

    {
    "status":"success",
    "data":[
            "sem_votes_allowed":{
                                "sem_votes_allowed":[{
                                                       "E2":"200", "E1":"100"
                                                    }]
                                },
            "usm_typ_flg":null,
            "uvp_user_id":"1",
            "sem_x_visitedat":"2015-07-23T06:15:21",
            "uvp_even_id":[
                           "11196","11197"
                          ],
            "usm_x_mobile_no":null,
            "usm_pin_no":null,
            "sem_holdings":{
                           "sem_holdings":[{
                                            "E2":"100","E1":"100"
                                          }]
                           },
     ],
    "action":"sc/get_shareholder_list",
    "statusmsg":"Share holder list",
    "statuscode":"E_OK"
    }