Get completed report via web service?

0

 From what I have read and been told, there is a common request/feature for JasperServer which I need to solve; the ability to place completed report export files (PDF, XLS, etc.) from JS into a directory/folder on a network. From what I understand this is not supported yet in JS as of 3.1

 

I have examined the CIFS patch submitted and I decided instead that it would be better for my purposes if I used the web services to retrieve Report Jobs periodically and place the report export files where I need them. I downloaded JS 3.1 and the source code. Using the iReport plugin examples I wrote a unit test to interface with the web services in order to retrieve the jobs and their information.

 

Now that I have that info (basefilename, date format, when the report job runs) I can construct a URL to retrieve a completed report - I thought.

 

I searched this forum for examples. All of the examples I have seen seem to be URLs for running a report again, vs. the URL for retrieving a completed export. For example (correct me if I am wrong) - to run a report I would use the URL starting with this:

 

"http://localhost:8081/jasperserver/flow.html?_flowId" and then the rest of the params

 

But if I want to access the completed report job I would use the following:

 

"http://localhost:8081/jasperserver/fileview/fileview/" and then the filename (constructed from info I retrieve via the web service).

 

So, to keep this simple, I decided to use the Java URL and URL connection class (see code below) rather than something like HTTP client. From what I understand this should work for simple retrieval of a file at a URL. If I use the following URL in a web browser, it works to a point (I get a save dialog):

 

http://localhost:8081/jasperserver/fileview/fileview/AllAccounts-2009021...

 

But if I use that URL in a Java Program using URL/URLConnection, I get back minus one for the content length.

 

So, the questions:

 

1) Am I correct about the URLs? I.E., the first runs the report, the second is the URL for the report already run?

 

2) Am I doing something wrong with URL/URLConnection? Or should I go the more complex route of using Apache HTTPClient?

 

3) Or is there a better way to do this?

 

Thanks

 

 

 

Code:
@Test
public void testURL()
{
	try
	{
//		URL url = new URL("http://localhost:8081/jasperserver/fileview/fileview/AllAccounts-200902171410.csv&j_acegi_security_check?&j_username=jasperadmin&j_password=jasperadmin");
		URL url = new URL("http://localhost:8081/jasperserver/fileview/fileview/AllAccounts-200902171410.csv");
		URLConnection urlConn = url.openConnection();
		int length = urlConn.getContentLength();
 
		FileWriter outStream;
 
		if (length > 0)
		{
			outStream = new FileWriter("c:\\AllAccounts-200902171410.csv");
			InputStream inStream = urlConn.getInputStream();
 
			int ch;
 
			while ((ch = inStream.read()) >= 0)
				outStream.write(ch);
		}
		else
			System.out.println("URL conn content length was " + length);
 
 
	}
	catch(Exception ex)
	{
 
	}
 
}


Post Edited by Lauren Bish at 02/18/09 17:28
developerdude's picture
Joined: Feb 18 2009 - 8:55am
Last seen: 10 years 8 months ago

6 Answers:

0

 I have made progress: I had a mistake in some of the logic and in the URL params (I needed a question mark in the right spot).

 

I can now download text based files (CSV, RTF, HTML - except for linked resources such as images), but I am having problems with binary files (PDF, XLS). I think I can figure it out from here - I am probably using the wrong read/writer or mode for binary files.

 

Rough example of code below:

 

 

Code:
@Test
	public void testURL()
	{
		try
		{
			URL url = new URL("http://localhost:8081/jasperserver/fileview/fileview/AllAccounts-200902171410.csv?&j_acegi_security_check&j_username=jasperadmin&j_password=jasperadmin");
			HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
 
			BufferedReader in = new BufferedReader( new InputStreamReader( urlConn.getInputStream()));
 
			int length = urlConn.getContentLength();
 
			FileWriter outStream;
 
			if (length > 0)
			{
				outStream = new FileWriter("c:\\AllAccounts-200902171410.csv");
 
				int ch;
				int charsWritten = 0;
 
				while ((ch = in.read()) >= 0)
				{
					outStream.write(ch);
					charsWritten++;
				}
 
				outStream.flush();
				outStream.close();
				System.out.println("Chars retrieved: " + length + " Chars written: " + charsWritten);
			}
			else
				System.out.println("URL conn content length was " + length);
 
 
		}
		catch(Exception ex)
		{
 
		}
 
	}</td></tr></tbody></table>
developerdude's picture
Joined: Feb 18 2009 - 8:55am
Last seen: 10 years 8 months ago
0

Hi,

 

Did u got the solution here... to write into the PDF ???

 

Thanks in advance...

nanju's picture
3
Joined: Mar 5 2009 - 12:16pm
Last seen: 10 years 7 months ago
0
Yes. I've had that working for some time now. But it is better to use the web services: i.e., there *is* a better way to do this and that is to use the repository web services to download directly instead of using HTTP. The problem with HTTP is that it is another level of indirection/abstraction/protocol, and if there is a problem in communication and/or with the request/response, then you (or your code) can be left guessing what went wrong. For example, if the report didn't run, or the report was empty and the file wasn't created (I patched JS to not write a file if the report results are empty), then what you get back is an HTTP response code of 500 (which is a general error that something went wrong) instead of a 404 error (file not found). Not to mention you are exposing your username and password in the URL to retrieve the report (I think 3.5 addresses this, but you still have to know the password). So use the repository web services.
developerdude's picture
Joined: Feb 18 2009 - 8:55am
Last seen: 10 years 8 months ago
0

Hi,

Can u give me some idea which web service to use in order to get the repository?

Actually, i am using the method listed in the JasperServer sample file "ContentResourceDataServlet.java" to get the file saved in the JasperServer repository. But also using the HTTP to get the report export file (PDF, XLS, ..) on the network.

Many Thanks.

henryho's picture
16
Joined: Sep 3 2008 - 1:17am
Last seen: 4 years 6 months ago
0

 See below

 

First I get the scheduled job from the scheduler, then I construct the name of the file to include the date suffix (probably should add the extension too). Then I call the repository and it creates the temp file that is the report.

 

There are probably some bugs, but that should get you started down the right road.

Code:
ReportScheduler scheduler = (ReportScheduler) applicationContext.getBean("jsReportSchedulerWebService");
JServer jasperServer = (JServer) applicationContext.getBean("jsRepositoryWebService");
Assert.assertNotNull(scheduler);
Assert.assertNotNull(jasperServer);
 
try
{
	WSClient wsClient = jasperServer.getWSClient();
	JobSummary[] summaries = scheduler.getAllJobs();
	Assert.assertNotNull(summaries);
 
	for (JobSummary summary : summaries)
	{
		System.out.println( "Job ID: " + summary.getId() + 
				" Label: " + summary.getLabel() + 
				" URI: " + summary.getReportUnitURI());
 
		try
		{
			SimpleDateFormat _dateFormat = new SimpleDateFormat("yyyyMMdd" );
			String dateString = "-" + _dateFormat.format(summary.getPreviousFireTime().getTime()) + ".xls";
			ResourceDescriptor rd = new ResourceDescriptor();
			rd.setWsType( ResourceDescriptor.TYPE_CONTENT_RESOURCE);
			rd.setUriString(summary.getReportUnitURI()+dateString);
			File tmpFile = File.createTempFile("jasperserver", "");
 
			tmpFile.deleteOnExit();
			StopWatch timer = new StopWatch();
			timer.start();
			ResourceDescriptor result = wsClient.get(rd, tmpFile);
			Assert.assertTrue(tmpFile.exists());
			timer.stop();
 
			if (result != null)
				result.getCreationDate();
		}
		catch(Exception ex)
		{
			System.out.println("job id == " + summary.getId() +  
					" label == " + summary.getLabel() + " " +
					ex.getMessage());
		}
	}
}
catch(Exception ex){}
</td></tr></tbody></table>
developerdude's picture
Joined: Feb 18 2009 - 8:55am
Last seen: 10 years 8 months ago
0

Hi

I'm having trouble displaying a graph using WEBSERVICEs. Using webservices I obtain the JPRINT object, convert to HTML using the HTMLExporter and then display to webpage.

Unfortunately, though the page doesn't render the graph image. I've tried suncessfully setting the IMAGES_URI parameter using the values of :

IMAGES_URI="images/"

IMAGES_URI="http://someserver/jasperreports/images/"

IMAGES_URI="http://someserver/jasperreports/reportimage?image="

None of these produced an error nor an image.

 

When running the report directly thorugh the JaperAdmin console I noticed the URLs issued to the jasper server contained an image (named  - img_0_0_3) as I expected. However, a parameter called 'jrprint'  was also dynamically generated and appended by jasperserver which isn't documented in the WS docs. 

Here is the URL:

http://someserver/jasperreports/reportimage?jrprint=2323445665_243465382&image=img_0_0_3

 

If I assign this value to IMAGES_URI parameters and re-retrieve the report via the application(i,e. embedded ), the graph image appears(as I require), but since the JRPRINT value is dynamic, hardcoding is probably an incorrect approach( I assume)?


The WS documentation mentions to use the IMAGES_URI parameter and to set it (e.g. "image/")  in order to display display graphs and other report images but no mention of the JRPRINT parameter in the context of displaying graphs.

 

Can some one please provide any guidance?

 

Thanks

Glenn

 

 

glennodickson's picture
Joined: Feb 11 2010 - 6:32pm
Last seen: 11 months 1 week ago
Feedback
randomness