Search code examples
javarestjasper-reportsjasperserver

Jasper Reports: getting JSON data from a post rest service


I am trying to get JSON data from a rest service. I know this is pretty simple for a GET service where you only have to provide the URI and Jasper studio can pull the data but I want to do this for a post rest service that also consumes some JSON input.

Workflow will be something like:

  1. Send userID in request header and some JSON parameters in request body.
  2. Get JSON data as output.
  3. Use JSON data to build report.

I am new to Jasper and am using Jasper server 6 with Japser Studio 6 but I can't find any documentation to do something like this.

I would appreciate if anyone can point me in the right direction regarding this.

The closes thing I can find is this link. From there I get that I can create a constructor which will get the data from rest service but how do I serve it to the report? Also please note that the JSON object being retrieved here is a bit complex and will have at least 2 lists with any number of items.

EDIT:

Alright so my custom adapter is like this:

package CustomDataAdapter;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.json.JSONObject;

public class SearchAdapter implements JRDataSource {
/**
 * This will hold the JSON returned by generic search service
 */
private JSONObject json = null;

/**
 * Will create the object with data retrieved from service.
 */
public SearchAdapter() {
    String url = "[URL is here]";
    String request = "{searchType: \"TEST\", searchTxt: \"TEST\"}";

    // Setting up post client and request.
    HttpClient client = HttpClientBuilder.create().build();
    HttpPost post = new HttpPost(url);
    HttpResponse response = null;

    post.setHeader("userId", "1000");
    post.setHeader("Content-Type", "application/json");

    // Setting up Request payload
    HttpEntity entity = null;
    try {
        entity = new StringEntity(request);
        post.setEntity(entity);

        // do post
        response = client.execute(post);
    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    // Reading Server Response
    try {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != 200) {
            throw new Exception("Search Failed");
        }

        BufferedReader in = new BufferedReader(new InputStreamReader(
                response.getEntity().getContent()));
        String inputLine;
        StringBuffer resp = new StringBuffer();
        while ((inputLine = in.readLine()) != null) {
            resp.append(inputLine);
        }

        in.close();

        this.json = new JSONObject(resp.toString());
    } catch (NullPointerException e) {
        e.printStackTrace();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

/*
 * (non-Javadoc)
 * 
 * @see
 * net.sf.jasperreports.engine.JRDataSource#getFieldValue(net.sf.jasperreports
 * .engine.JRField)
 */
public Object getFieldValue(JRField field) throws JRException {
    // TODO Auto-generated method
    // stubhttp://community-static.jaspersoft.com/sites/default/files/images/0.png
    return this.json;
}

/*
 * (non-Javadoc)
 * 
 * @see net.sf.jasperreports.engine.JRDataSource#next()
 */
public boolean next() throws JRException {
    return (this.json != null);
}

/**
 * Return an instance of the class that implements the custom data adapter.
 */
public static JRDataSource getDataSource() {
    return new SearchAdapter();
}

}

I am able to create an adapter and the Test Connection feature in Jasper Studio also returns true but I cant get it to read any of the fields in the JSON and auto-generate the report. I only get a blank document. FYI the JSON is something like:

{
"key": "value",
"key": "value",
"key": [list],
"key": [list]
}

Solution

  • Well, I feel stupid now but the solution was pretty easy. Turns out you cant just return a JSON object. You need to return the fields and manually add the fields in the report.

    For record purposes my final code look like this:

    package CustomDataAdapter;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    import net.sf.jasperreports.engine.JRDataSource;
    import net.sf.jasperreports.engine.JRException;
    import net.sf.jasperreports.engine.JRField;
    
    import org.apache.http.HttpResponse;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.HttpClientBuilder;
    import org.json.JSONException;
    import org.json.JSONObject;
    
    public class SearchAdapter implements JRDataSource {
    
        /**
         * This will hold the JSON returned by generic search service
         */
        private JSONObject json = null;
    
        /**
         * Ensures that we infinitely calling the service.
         */
        private boolean flag = false;
        /**
         * Will create the object with data retrieved from service.
         */
        private void setJson() {
            String url = "[URL is here]";
            String request = "{\"searchType\": \"Test\", \"searchTxt\": \"Test\"}";
    
            // Setting up post client and request.
            HttpClient client = HttpClientBuilder.create().build();
            HttpPost post = new HttpPost(url);
            HttpResponse response = null;
    
            post.setHeader("userId", "1000");
            post.setHeader("Content-Type", "application/json");
    
            // Setting up Request payload
            StringEntity entity = null;
            try {
                entity = new StringEntity(request);
                post.setEntity(entity);
    
                // do post
                response = client.execute(post);
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            // Reading Server Response
            try {
                int statusCode = response.getStatusLine().getStatusCode();
                if (statusCode != 200) {
                    // Thrown Exception in case things go wrong
                    BufferedReader in = new BufferedReader(new InputStreamReader(
                            response.getEntity().getContent()));
                    String inputLine;
                    StringBuffer resp = new StringBuffer();
                    while ((inputLine = in.readLine()) != null) {
                        resp.append(inputLine);
                    }
    
                    in.close();
    
                    String ex = "Search Failed. Status Code: " + statusCode;
                    ex += "\n Error: " + resp.toString();
                    throw new Exception(ex);
                }
    
                BufferedReader in = new BufferedReader(new InputStreamReader(
                        response.getEntity().getContent()));
                String inputLine;
                StringBuffer resp = new StringBuffer();
                while ((inputLine = in.readLine()) != null) {
                    resp.append(inputLine);
                }
    
                in.close();
    
                this.json = new JSONObject(resp.toString());
            } catch (NullPointerException e) {
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see
         * net.sf.jasperreports.engine.JRDataSource#getFieldValue(net.sf.jasperreports
         * .engine.JRField)
         */
        @Override
        public Object getFieldValue(JRField field) throws JRException {
            // TODO Auto-generated method
            // stubhttp://community-static.jaspersoft.com/sites/default/files/images/0.png
            try {
                return this.json.get(field.getName());
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
        /*
         * (non-Javadoc)
         * 
         * @see net.sf.jasperreports.engine.JRDataSource#next()
         */
        @Override
        public boolean next() throws JRException {
            if (this.json != null && !flag) {
                flag = true;
                return true;
            } else {
                return false;
            }
        }
    
        /**
         * Return an instance of the class that implements the custom data adapter.
         */
        public static JRDataSource getDataSource() {
            SearchAdapter adapter = new SearchAdapter();
            adapter.setJson();
            return adapter;
        }
    
    }