2011-09-19 5 views
0

서블릿은 처음 생성 된 iframe 내에 미리보기 페이지가 생성 된 후에 PDF 문서를 생성합니다. 이것은 일반적으로 작동하고 다음과 같습니다 : 모든 "directPrintDocument"및 iframe이 페이지를 생성하고 서블릿 응답 콘텐츠를 쓰는 방법 "renderIFrameWaiting"호출의서블릿은 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); 
     } 
    } 

우선합니다 (iframe이 SRC는 다음 부분을 호출 doPost.이 코드 조각을 생략하므로 오류가 발생하지 않습니다.) 이것은 일반적으로 작동

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&auml;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(); 
} 

하지만 때로는 뭔가 : 그런 다음 "directPrintDocumentWaiting"및 방법 "renderWaiting는"생성 된 자바 스크립트가 마지막으로 PDF를 생성 "directPrintDocumentDoIt"를 호출하는 동안 이전에 생성 된 iframe이 페이지에서 미리보기 페이지를 생성하는 호출 이상한 일이 일어난다. 어떻게 든 마지막 호출 인 "directPrintDocumentDoIt"이 두 번 호출되어 generatePDF가 두 번 호출되고 전체 인쇄물이 멈추는 것처럼 보입니다 (대부분의 경우 PDF는 흰색 페이지에 의해 무시됩니다). 50 번 중 1 번 기회가 발생하므로 재생산이 거의 불가능합니다.

log.info("> current thread:" + Thread.currentThread().getId()); 

스레드 ID는 항상 동일합니다, 그래서 정말 스레드 문제가 의심 : 우선 내가 어떤 스레드 문제로 생각했던 모든 그래서 나는 모든 호출에 스레드 ID를 기록. 필자가 당황한 것은이 오류가 발생하면 바이올린 POST 호출이 실행 된 후 4 번째 호출을 기록하는 것입니다. 일반적으로 3 개의 호출 ("directPrintDocument", "directPrintDocumentWaiting"및 "directPrintDocumentDoIt")이 있습니다. 4 번의 호출이있을 때는 항상 같은 방식으로 발생합니다. "directPrintDocumentDoIt"은 두 번 (POST 요청과 동일한 URL) 호출되지만 suddendly GET 요청으로 호출됩니다. 나는이 GET 요청이 어디에서 오는 것인지 전혀 모른다. ("generatePDF"에서는 다른 요청 호출이 없다.) 따라서 자바 스크립트는 이상한 행동을하지만 (웹 컨셉) 왜 이해가 가지 않는 이상한 행동을합니다. 흥미로운 점은 피들러가 3 번째 및 4 번째 호출에서 서로 다른 엔티티 크기를 보여줍니다. 올바른 POST 호출은 엔티티 크기가 84.138 바이트입니다. 네 번째 호출 (잘못된 것)은 83.883 바이트입니다. 이것이 의미하는 바를 모르지만이 정보가 도움이 될지도 모릅니다. 필자는 Websphere를 다시 시작하거나 게시 한 후에이 오류가 더 자주 발생한다고 생각합니다. 이 경우 첫 번째 시도에서 발생하지만 항상 그렇지는 않습니다. 이것은 우연 일 수 없습니다. 여기에 무슨 일이 일어나고 있는거야?

+0

'renderWaiting'이 내게 미리보기를 생성하는 것처럼 보이지 않습니다. 자동 제출 양식을 생성합니다. 이 단계가 필요한 이유는 무엇입니까? 초기 액션이 PDF 렌더링 액션을 가리키는 iframe을 렌더링하지 못하는 이유는 무엇입니까? –

+0

"p align"이있는 두 줄은 "preview"를 생성합니다. 자동 제출이 호출 된 후 pdf가 생성 될 때까지 몇 초가 걸립니다. 이 시간에 클라이언트는 PDF가 생성되지 않은 한이 페이지를 봅니다. 이것이이 단계가 중요한 이유입니다. 그렇지 않으면이 방법으로는 작동하지 않습니다. – Bevor

+0

방금 ​​PDF URL을 직접 방문하면 어떻게됩니까? 이중 요청을 받으십니까? 또한 HTTP 헤더에서 ISO8859-1을 사용하고 ''태그를 사용하지만 그 인코딩을 사용할 수없는'getBytes() '를 사용합니다. 'getBytes ("ISO-8859-1")'를 사용하십시오. –

답변

0

명백히 오류는 pdfwriter가 원인입니다.

 response.reset(); 
     response.setContentType("application/pdf"); 
     response.setContentLength(pdfContent.length); 
     response.setHeader("Content-Disposition", "inline; filename=RANDOMFILE.pdf"); 
     response.addHeader("Accept-Ranges", "bytes"); 
     response.getOutputStream().write(pdfContent); 
     response.getOutputStream().flush(); 
     response.getOutputStream().close(); 

나는 이유는 모르겠지만, 가끔이 헤더 원인 어쨌든 제 2의 요청하십시오 errorprone 코드는이처럼 보였다. 다음과 같이 변경하면 pdf 생성 후 더 이상 화이트 페이지가 표시되지 않습니다. 그래서 이것이 해결책 인 것 같습니다.

response.setContentType("application/pdf"); 
response.setContentLength(pdfContent.length); 
response.getOutputStream().write(pdfContent); 
response.getOutputStream().flush(); 
response.getOutputStream().close(); 
관련 문제