itext"文档未打开"在tomcat 7中部署的Web服务出错

时间:2015-03-04 23:15:04

标签: multithreading web-services tomcat itext

我在tomcat中部署了一个jaxws webservice,当它只为一个请求提供服务时它恰好运行良好但是当有两个同时发生的请求时,创建PDF的过程失败并出现错误 “该文件未公开” itext jar包含在webservice war中,所以我们认为它不是类加载问题。 什么可能失败?

编辑最初提供的代码作为答案:

public Boolean PDF(BeanGeneral general2, String carpeta) {
    general = general2;
    document = new Document();
    document.setPageSize(PageSize.LETTER);

    try {
        fileName = carpeta + "/" + general.getNoSAP() + ".pdf";

        writer = PdfWriter.getInstance(document, new FileOutputStream(fileName));
        document.open();
        cb = writer.getDirectContent();
        PdfReader reader = null;
        reader = new PdfReader(general.getParametros().getProperty("images") + "/template.pdf");

        page = writer.getImportedPage(reader, 1);
        document.newPage();
        cb.addTemplate(page, 0, 0);
        getHeader();

        getDetalle();

        getFooter();
        document.close();           
        file = new File(fileName);
    } catch (IllegalPdfSyntaxException e) {        
        error = false;
        return error;
    } catch (Exception e) {
        e.printStackTrace();
        error=false;
        return error;
    }

    return error;
}

1 个答案:

答案 0 :(得分:1)

您的其他信息(不幸的是,您作为答案而不是问题的修改)显示变量documentwritercb(甚至可能更多)实际上不是方法变量,而是类实例的成员。

同时请求期间,这两个请求都使用此类实例。因此,这两个请求都将DocumentPdfWriterPdfContentByte放入相同的变量中。

这意味着请求的值稍微落后于win,并且两个请求都使用后来的请求值。这反过来意味着:

  • 赢得的文件检索从覆盖变量内容开始的两个请求过程中产生的所有内容;那
  • 获胜的文件即使在被第一个请求关闭后也被后一个请求使用:这导致您观察到的“文档未打开”错误。

(实际上这是一种简化;因为你没有引入内存同步障碍,所以变量可能在不同的缓冲区中缓冲,并且这些缓冲区的同步可能在任何随机时间发生......)

您可以通过多种不同方式解决此问题:

  • 将您的方法PDF声明为synchronized;因为成员变量的值只需要在运行此方法时保持不变,这应该足够了:

    public synchronized Boolean PDF(BeanGeneral general2, String carpeta)
    

  • 将这些成员变量转换为方法变量,并将其作为参数添加到方法getHeadergetDetallegetFooter(如果需要);或

  • 将这些成员变量转换为ThreadLocal变量。