2015-04-02 212 views
2

我在一个打开PDF文件的按钮中有SSJS,写入它的一些字段(Acroform),然后将文件下载到用户。所有的作品都很棒(使用pdfbox),但我想成为一名优秀的程序员,如果原始pdf文件不可用,请取消操作。否则,用户仍会被提示打开文件,但Adobe Reader报告该文件已损坏(显然会是)。我在我调用的Java类中执行我的pdf操作,并传递响应对象的outputStream。以下是我的SSJS。如果我测试来自newVal.outputPdf的ret值并将所有其他代码放在if语句中,那么我的XPage只是空白。我假设,因为响应和outputStream已经打开?取消创建用于创建新PDF文件的outputteam的最佳方法?

霍华德

importPackage(com.tlcc); 
var newVal = new PdfBoxTest(); 
importPackage(java.net); 
importPackage(java.lang); 
var con = facesContext.getExternalContext(); 
var response:com.ibm.xsp.webapp.XspHttpServletResponse = con.getResponse(); 

try {   
var writer:javax.servlet.ServletOutputStream = response.getOutputStream(); 


//get the stream 
var ret = newVal.outputPdf(writer, "http://localhost/pdfexportcc.nsf/certificate.pdf"); 

// setting response headers for browser 
print("Good output"); 
response.setContentType("application/pdf"); 
response.setHeader("Cache-Control", "no-cache"); 
response.setDateHeader("Expires", -1); 
response.setHeader("Content-Disposition", "attachment; filename=\"mypdf.pdf\""); 
writer.flush(); 
writer.close(); 
print("in close"); 
facesContext.responseComplete(); 
} catch (e) { 
    var errorMessage = "An error has occured: " + e.toString(); 
    _dump(errorMessage); 
    writer.close(); 
    response.sendError(500, errorMessage); 
} 

与所有的工作再次尝试是用Java语言实现。我从一个按钮调用了这个方法。与有效的网址工作正常,但当网址不好时,会引发错误。异常在OutputStream已被使用时无法获得Writer。

public boolean outputAllInJavaPdf() { 
    try { 
     FacesContext context = FacesContext.getCurrentInstance(); 

     XspHttpServletResponse response = (XspHttpServletResponse) context.getExternalContext().getResponse(); 

     ServletOutputStream writer = response.getOutputStream(); 
     InputStream docUrl = new URL("http://localhost/pdfexportcc.nsf/certifxxicate.pdf").openStream(); 
     pdfDoc = PDDocument.load(docUrl); 

     System.out.println("Number of pages is " + pdfDoc.getNumberOfPages()); 
     setField("Student", "James Namce"); 
     setField("CourseName", "XPages Development 2 for Notes and Domino 9"); 
     setField("Instructor", "John Smith"); 
     System.out.println("After set field"); 
     pdfDoc.save(writer); 
     pdfDoc.close(); 

     response.setContentType("application/pdf"); 
     response.setHeader("Cache-Control", "no-cache"); 
     response.setDateHeader("Expires", -1); 
     response.setHeader("Content-Disposition", "attachment; filename=\"mypdf.pdf\""); 
     writer.flush(); 
     writer.close(); 

     context.responseComplete(); 
     return true; 

    } catch (Exception e) { 
     System.out.println(e.getMessage()); 
     e.printStackTrace(); 
     return false; 
    } 
} 

回答

0

它可能试图呈现您的Xpage,但您想自己控制响应。要防止Xpage的渲染并控制作者,请将rendered="false"添加到Xpage。

+0

我确实需要XPage。我想在页面上有按钮来创建pdf并下载/打开它。但XPage应该保持开放。 – Howard 2015-04-03 13:26:22

1

一切都取决于你告诉浏览器。

您使用PDF文件的内容类型。浏览器打开(下载)PDF文件。您放入的任何内容(例如错误页面)都被视为PDF文件的内容。 因此,如果PDF生成失败,请不要设置该内容类型并将浏览器重定向到错误页面,或者返回到原始XPage并附带说明。

public boolean outputAllInJavaPdf() { 
    try { 
     FacesContext context = FacesContext.getCurrentInstance(); 

     XspHttpServletResponse response = (XspHttpServletResponse) context.getExternalContext().getResponse(); 

     ServletOutputStream writer = response.getOutputStream(); 
     boolean servePdf = true; 
     try { 
      InputStream docUrl = new URL("http://localhost/pdfexportcc.nsf/certifxxicate.pdf").openStream(); 
      pdfDoc = PDDocument.load(docUrl); 
      // do something to validate PDF 
     } catch (Exception e) { 
      //no PDF 
      servePdf = false; 
     } 

     if (servePdf) { 
      System.out.println("Number of pages is " + pdfDoc.getNumberOfPages()); 
      setField("Student", "James Namce"); 
      setField("CourseName", "XPages Development 2 for Notes and Domino 9"); 
      setField("Instructor", "John Smith"); 
      System.out.println("After set field"); 
      pdfDoc.save(writer); 
      pdfDoc.close(); 

      response.setContentType("application/pdf"); 
      response.setHeader("Cache-Control", "no-cache"); 
      response.setDateHeader("Expires", -1); 
      response.setHeader("Content-Disposition", "attachment; filename=\"mypdf.pdf\""); 

     } else { 
      // take care of no PDF response - redirect? 
     } 
      writer.flush(); 
      writer.close(); 
      context.responseComplete(); 
      return true; 
    } catch (Exception e) { 
     System.out.println(e.getMessage()); 
     e.printStackTrace(); 
     return false; 
    } 
} 
+0

不太清楚如何安排代码来做到这一点。如果打开现有的pdf失败,它会进入catch块。该控件返回到调用Java代码的按钮并返回false。 – Howard 2015-04-03 13:27:20

+0

这个修改过的代码很有用,但是,我仍然因为如何重新加载原始XPage而陷入困境(甚至更好,对原始XPage没有任何影响)。现在我只是得到一个空白的XPage。在我的SSJS按钮上,如果Java调用的返回值是false,我做了一个context.reloadPage(),但它仍然只显示一个空白的网页。感谢您的帮助... – Howard 2015-04-03 20:32:30

+0

再次尝试使用context.redirectToPage(“myPage.xsp”)...像var ret = new newVal.outputAllInJavaPdf(); \t if(ret == false){ \t \t context.redirectToPage(“testPDF.xsp”);这工作。似乎是一种暴力方式来处理Java类中的异常?这是最好的方法吗?谢谢,霍华德 \t} – Howard 2015-04-03 20:36:45