我在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;
}
答案 0 :(得分:1)
您的其他信息(不幸的是,您作为答案而不是问题的修改)显示变量document
,writer
和cb
(甚至可能更多)实际上不是方法变量,而是类实例的成员。
在同时请求期间,这两个请求都使用此类实例。因此,这两个请求都将Document
,PdfWriter
和PdfContentByte
放入相同的变量中。
这意味着请求的值稍微落后于win,并且两个请求都使用后来的请求值。这反过来意味着:
(实际上这是一种简化;因为你没有引入内存同步障碍,所以变量可能在不同的缓冲区中缓冲,并且这些缓冲区的同步可能在任何随机时间发生......)
您可以通过多种不同方式解决此问题:
将您的方法PDF
声明为synchronized
;因为成员变量的值只需要在运行此方法时保持不变,这应该足够了:
public synchronized Boolean PDF(BeanGeneral general2, String carpeta)
或
将这些成员变量转换为方法变量,并将其作为参数添加到方法getHeader
,getDetalle
和getFooter
(如果需要);或
将这些成员变量转换为ThreadLocal
变量。