2011-09-28 4 views
1

backing bean을 사용하여 PDF 문서를 브라우저로 스트리밍하는 JSF 페이지가 있습니다. 이 기능은 훌륭하게 작동하며 iOS 기기에서이 기능을 테스트 할 때까지는 아무런 문제가 없었습니다.iOS 디바이스의 JSF 스트리밍 PDF

iPad 및 iPod Touch에서 Safari를 사용하면 PDF 스트림이 응답을 받으면 웹 페이지에서 스크롤 할 수없는 레이어로 붙여 넣기 만합니다. 바탕 화면의 브라우저에서 파일은 Adobe Reader로 저장하거나 열거 나 제대로 열지 묻는 메시지를 표시합니다. 이는 PDF의 첫 페이지의 일부만이 iOS 기기에 표시되고 다른 부분을 볼 방법이 없기 때문에 문제입니다.

나는 웹에서이 장치들에 대한 다른 PDF들을 테스트 해본 결과 동일하지 않습니다. PDF 응용 프로그램이 시작되거나 Safari는 원하는 결과 인 스크롤 가능한 미리보기를로드합니다. 다른 사람이 가지고 있니?

내 백업 빈은 PDF의 버퍼링 된 입력 스트림을 출력 스트림에 씁니다. 다음과 같은 응답 헤더를 설정했습니다 :

response.setContentType ("application/pdf"); 
response.setContentLength(inputLength); 
response.setHeader ("Content-Disposition", "inline;filename=\"" + saveFilename + ".pdf\""); 
response.setHeader ("Cache-Control", "must-revalidate, post-check=0, pre-check=0, public"); 

콘텐츠 처리를 인라인에서 첨부 파일로 전환하려고했으나 도움이되지 않았습니다.

답변

0

콘텐츠가 별도의 부분에서 요청 될 수 있도록 해당 장치가 서버 측에서 Range을 지원해야한다고 생각합니다. 결국 궁극적으로 불필요한 네트워크 대역폭을 절약하고 클라이언트 측에서 성능 감을 향상시킵니다.

이러한 PDF가 동적으로 생성되는 경우 가장 좋은 방법은 디스크 파일 시스템의 임시 위치에 작성하고 서블릿에서 읽는 URL로 요청을 리디렉션하는 것입니다. 파일의 일부 내용을 반환 할 수 있으려면 RandomAccessFile을 사용하고 싶으므로 실제 파일을 가져야합니다. 이 클래스는 디스크에 실제 File이 필요합니다. 범위 요청을 지원

File tempFile = File.createTempFile(saveFilename, ".pdf"); 
OutputStream output = new FileOutputStream(tempFile); 
// Now write PDF to output. 
// ... 

// Then, redirect to some servlet URL. 
String tempFilename = tempFile.getName(); 
externalContext.redirect("/pdf/" + URLEncoder.encode(tempFilename, "UTF-8")); 

그런 다음, 당신이 this one 같은 서블릿이 필요합니다 : 여기

는 임시 파일을 만들 수 File#createTempFile()를 사용하고 URL 매개 변수로 파일 이름을 가진 서블릿에 대한 응답을 리디렉션 예입니다 . basePath 값을 System.getProperty("java.io.tmpdir")으로 변경하기 만하면됩니다. 마지막으로이 서블릿을 /pdf/*의 URL 패턴으로 매핑하십시오.

다른 방법으로 서버에 대한 전체 관리 권한이있는 경우 서버의 디스크 파일 시스템 어딘가에 절대 경로를 가리키는 추가 웹 응용 프로그램 컨텍스트를 만들 수도 있습니다. 예 : /var/webapp/pdf. 예를 톰캣의 경우, 당신은 /conf/server.xml에 다음을 추가하여 공개 할 수있다 :

<Context docBase="/var/webapp/pdf" path="/pdf" /> 

이 식으로 /var/webapp/pdf 폴더의 내용은 http://localhost:8080/context/pdf로 사용할 수 있습니다. 임시 파일 위치를 지정하는 위의 코드 예제에있는 작은 변화

,

File tempFile = File.createTempFile(saveFilename, ".pdf", "/var/webapp/pdf"); 
// ... 

당신은 더 이상 사용자 정의 서블릿이 필요하지 않습니다. Tomcat의 DefaultServletRange 요청을 올바르게 처리하는 작업을 수행합니다.

마지막으로 중요한 것은 세션에 임시 파일을 저장하고 세션이 만료되면 임시 파일을 삭제하는 또는 HttpSessionAttributeListener을 구현하는 것입니다.

+0

귀하의 게시물 BalusC에 감사드립니다. 임시 위치에 파일을 저장하는 방법을 시도하고 서블릿 예제를 사용하여/pdf /에 매핑 된 서블릿을 생성하고 요청을 다시 시도했습니다. 데스크톱 브라우저에서는 예상대로 처리되었으므로 열거 나 저장하라는 메시지가 나타납니다. iOS의 Safari에서는 이전 버전과 마찬가지로 response.redirect를 사용하여 기존 웹 페이지에 PDF를 겹쳐서 표시합니다. 나는 이것이 JSF와 Safari의 버그라고 생각하기 시작했다. 그러나 확실하지는 않다. 이는 기밀 문서이므로 파일에 직접 URL을 제공 할 수는 없습니다. – dlau

+0

흥미 롭습니다. 어쨌든 정적 샘플 PDF를 공개 웹 콘텐트에 넣었을 때 그것을 직접 참조해서'DefaultServlet'이 그 일을 수행하는 것은 어떨까요? – BalusC

+0

예, 정상적으로 작동했습니다. iOS 기기가 열어서 Microsoft Word 문서로 간주했습니다. – dlau

관련 문제