servlet在首先生成的iframe中生成預覽頁面後生成PDF文檔。這通常工作,看起來像這樣:Servlet生成PDF,但有時調用行爲陷入困境
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if ("directPrintDocumentDoIt".equals(request.getParameter("method"))) {
generatePDF(request, response);
}
if ("directPrintDocumentWaiting".equals(request.getParameter("method"))) {
String queryString = request.getQueryString().replace("directPrintDocumentWaiting", "directPrintDocumentDoIt");
renderWaiting(request, response, queryString);
}
if ("directPrintDocument".equals(request.getParameter("method"))) {
String queryString = request.getQueryString().replace("directPrintDocument", "directPrintDocumentWaiting");
renderIFrameWaiting(request, response, queryString);
}
}
首先「directPrintDocument」和方法「renderIFrameWaiting」被調用產生的iframe頁面,將內容寫入到servlet響應(該IFRAME SRC調用下一個部分doPost。我確信這不會產生錯誤,所以我省略了這段代碼片段)。然後「directPrintDocumentWaiting」和方法「renderWaiting」被調用而生成的JavaScript調用「directPrintDocumentDoIt」,它最終生成PDF生成以前生成的iframe頁面內預覽頁面:
private void renderWaiting(HttpServletRequest request, HttpServletResponse response, String queryString) throws IOException {
StringBuffer output = new StringBuffer();
response.setContentType("text/html; charset=ISO-8859-1");
response.setHeader("Cache-Control", "no-cache");
output.append("<html>\n");
output.append("<head>\n");
output.append("<meta http-equiv='Content-Type' content='text/html;charset=iso-8859-1'>\n");
output.append("<meta http-equiv='expires' content='0'>\n");
output.append("<meta http-equiv='cache-control' content='no-cache'>\n");
output.append("<meta http-equiv='pragma' content='no-cache'>\n");
output.append("</head>\n");
output.append("<script type=\"text/javascript\">\n");
output.append("function formSubmit() {\n");
output.append("document.forms[0].target=\'_self\';\n");
output.append("document.body.style.cursor = \"wait\";\n");
output.append("var formAction = document.forms[0].action;\n");
output.append("document.forms[0].submit();\n");
output.append("}\n");
output.append("</script>\n");
output.append("<body onload=\"self.focus(); formSubmit();\">\n");
output.append("<form name=\"druckenForm\" method=\"post\" action=\"" + request.getRequestURI() + "?" + queryString + "\" onsubmit=\"return false;\">\n");
output.append("<p align=\"center\" valign=\"center\">Druck wird erzeugt...\n</p>\n");
output.append("<p align=\"center\" valign=\"center\">Der erstmalige Start kann etwas länger dauern.</p>\n");
output.append("</form>\n");
output.append("</body>\n");
output.append("</html>");
response.setContentLength(output.length());
response.getOutputStream().write(output.toString().getBytes());
response.getOutputStream().flush();
response.getOutputStream().close();
}
這通常工作,但有時事情發生奇怪的事不知怎的,它看起來像最後一次調用「directPrintDocumentDoIt」將被調用兩次,因此generatePDF也會被調用兩次,整個打印輸出陷入困境(在大多數情況下,PDF將被白頁覆蓋)。發生這種情況的機率是50倍,所以它幾乎無法再現。首先我想到了一些線索問題,所以我記錄的線程ID在每次調用:
log.info("> current thread:" + Thread.currentThread().getId());
線程ID始終是相同的,所以我懷疑這真是一個線程問題。讓我感到困惑的是,當這個錯誤發生時,fiddler在執行javascript POST調用之後記錄第4次調用。通常有3個調用(「directPrintDocument」,「directPrintDocumentWaiting」和「directPrintDocumentDoIt」)。當有4個調用時,它總是以相同的方式發生:「directPrintDocumentDoIt」將被調用兩次(與POST請求相同的URL),但作爲一個GET請求突然被調用。我不知道這個GET請求來自哪裏(在「generatePDF」中沒有其他請求調用)。所以無論是JavaScript產生一些奇怪的行爲(但爲什麼然後很少)或Web容器(Websphere)使我不明白的一些奇怪的事情。有趣的是,提琴手在第3次和第4次調用時顯示不同的實體大小。正確的POST調用的實體大小爲84.138字節。第四次調用(錯誤的)有83.883字節。我不知道這是什麼意思,但也許這個信息是有幫助的。我有這樣的感覺,即在我重新啓動或發佈到Websphere後,這種錯誤經常發生。在這種情況下,它發生在第一次嘗試(但並非總是)。這不可能是巧合。任何想法發生了什麼?
'renderWaiting'看起來不像它爲我生成預覽。它會生成一個自動提交表單。爲什麼需要這一步驟?爲什麼初始操作不能渲染指向PDF渲染操作的iframe? –
「p align」的2行生成「預覽」。在自動提交被調用之後,直到生成pdf需要幾秒鐘的時間。在這個時候,只要PDF尚未生成,客戶端就會看到該頁面。這就是爲什麼這一步很重要。否則這不會以這種方式工作。 – Bevor
如果您直接點擊PDF URL,會發生什麼情況。你有雙重要求嗎?另外,您在HTTP標頭和''標籤中使用ISO8859-1,但使用'getBytes()',不保證使用該編碼。使用'getBytes(「ISO-8859-1」)'。 –