Diego Urenia
Diego Urenia

Reputation: 1640

Problems displaying PDF inside a new browser tab using a flex + servlet + jasper

I'm using my reportService class to generate the JasperPrint object that contains my report, then I send it to a Servlet and it generates the PDF. The problem is that this servlet is not opening the PDF in a new tab(this is what I want), actually it doesn't even prompting me to download it or anything.

Servlet Caller:

   try {
        URL url = new URL("http://" + serverName + ":" + serverPort + path
                + "/reportgenerator");

        HttpURLConnection connection = (HttpURLConnection) url
                .openConnection();

        connection.setRequestMethod("POST");
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setDefaultUseCaches(false);
        connection.setRequestProperty("Content-Type",
                "application/octet-stream");

        ObjectOutputStream out = new ObjectOutputStream(
                connection.getOutputStream());

        //This "jasperPrint" is my generated report from my service
        out.writeObject(jasperPrint);
        out.close();

        connection.getInputStream();

    } catch (MalformedURLException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

My doPost method from my Servlet:

@Override
protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {

    JasperPrint jasperPrint = null;
    ObjectInputStream resultStream = null;
    ServletOutputStream out = response.getOutputStream();       

    try {

        resultStream = new ObjectInputStream(request.getInputStream());
        jasperPrint = (JasperPrint) resultStream.readObject();
        resultStream.close();

        byte[] rel = JasperExportManager.exportReportToPdf(jasperPrint);            
        out.write(rel,0, rel.length);

       //JasperExportManager.exportReportToPdfStream(jasperPrint, out);

        response.setContentLength(rel.length);          
        response.setContentType("application/pdf");
        response.setHeader("Content-Disposition",
                "attachment; filename=\"report.pdf\"");
        response.setHeader("Cache-Control", "no-cache");                        

        System.err.println(rel.length);

    } catch (JRException e) {
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } finally {                 
        out.flush();
        out.close();    
    }
}

What am I doing wrong?

Upvotes: 1

Views: 2895

Answers (2)

Jacob Schoen
Jacob Schoen

Reputation: 14212

Assuming you have the byte[] of the file you want to open on the flex side of your application you should be able to write the file to a temp location and then open it. It would look similar to this:

//create a temp dir in the system temp directory to place all the temp files for you app.
private static var tempDir:File=File.createTempDirectory();    

/**
 * bytes - the byte array of the pdf you want to open
 * filename - the name to use for the temp file, you may need to create some type of
 *            counter to add to the beginning of the filename so that you always get
 *            a unique name 
 */
public static openFile(bytes:ByteArray,filename:String):void{
   //create a file in the system temp directory to write the file to
   var tempFile:File = tempDir.resolvePath(filename);

   //create a filestream to write the byte array to the file
   var fileStream:FileStream = new FileStream(); 
   fileStream.open(tempFile, FileMode.WRITE); 
   fileStream.writeBytes(bytes,0,bytes.length);
   fileStream.close();

   //open the temp file with default application
   tempFile.openWithDefaultApplication();
}

Upvotes: 1

Diego Urenia
Diego Urenia

Reputation: 1640

I've solved my problem returning the JasperPrint as a byte[] to my flex application, in flex it will be treated as a ByteArray(because it's converted by, in my case, graniteds) and then I just call my servlet sending this ByteArray.

I'm looking for another solution, but it can help someone else.

Upvotes: 1

Related Questions