2010-05-26 3 views
11

JSF 애플리케이션을 만들었습니다. 링크를 클릭하면 백킹 빈이 일부 XML을 마샬링하고 페이지를 여는 링크를 페이지에 삽입하려고합니다. 사용자가 파일을 저장할 위치를 선택할 수 있도록 저장 대화 상자로 저장합니다. 이미 JAXB 코드를 작성했습니다.웹 브라우저에서 JSF 애플리케이션의 대화 상자로 강제 저장

어떻게 처리하나요?

감사

답변

33

를 사용합니다. 그러면 다른 이름으로 저장 대화 상자가 나타납니다. HttpServletResponse#setHeader()을 사용하면됩니다. ExternalContext#getResponse()에 의해 JSF 뚜껑 아래에서 HTTP 서블릿 응답을 얻을 수 있습니다.

JSF 컨텍스트에서는 IllegalStateException이 돌아 다니는 것을 피하기 위해 나중에 FacesContext#responseComplete()을 호출하면됩니다.

킥오프 예 :

public void download() throws IOException { 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 
    HttpServletResponse response = (HttpServletResponse) externalContext.getResponse(); 

    response.reset(); // Some JSF component library or some Filter might have set some headers in the buffer beforehand. We want to get rid of them, else it may collide. 
    response.setContentType("application/xml"); // Check http://www.iana.org/assignments/media-types for all types. Use if necessary ServletContext#getMimeType() for auto-detection based on filename. 
    response.setHeader("Content-disposition", "attachment; filename=\"name.xml\""); // The Save As popup magic is done here. You can give it any filename you want, this only won't work in MSIE, it will use current request URL as filename instead. 

    BufferedInputStream input = null; 
    BufferedOutputStream output = null; 

    try { 
     input = new BufferedInputStream(getYourXmlAsInputStream()); 
     output = new BufferedOutputStream(response.getOutputStream()); 

     byte[] buffer = new byte[10240]; 
     for (int length; (length = input.read(buffer)) > 0;) { 
      output.write(buffer, 0, length); 
     } 
    } finally { 
     close(output); 
     close(input); 
    } 

    facesContext.responseComplete(); // Important! Else JSF will attempt to render the response which obviously will fail since it's already written with a file and closed. 
} 
+0

대단히 감사합니다. 코드를 넣으면 링크를 클릭하면 현재 페이지가 다운로드 창을 표시하는 대신 파일 내용이 포함 된 페이지로 바뀝니다. 나는 무엇을 잘못하고있을 것인가? – volvox

+1

다른 브라우저 (IE, Chrome)에서도 사용해 보거나 FF로 깨끗한 프로필로 다시 시작하십시오. 웹 브라우저가 XML 파일의 기본 응용 프로그램으로 구성되고 XML 파일을 다운로드 할 때 자동으로 열어야 할 수도 있습니다. – BalusC

+1

아, 비동기 (ajaxical) 요청이 아니라 동기식 ("일반 바닐라") 요청이어야합니다. 나는. RichFaces, Ajax4jsf, IceFaces 등의 Ajaxical-powered 'UICommand' 컴포넌트가 아닌'h : commandLink' 또는'h : commandButton' 만 사용하십시오. – BalusC

3

content-disposition: attachment HTTP 헤더 attachment에 HTTP Content-Disposition 헤더를 설정

0

때때로 당신이 작가를 닫기 전에 response.getWriter().flush();를 호출하여 클라이언트에 내용을 보낼 수있는 작가를 강제 할 필요가있다. 이 경우 제 경우 팝업으로 저장하라는 메시지가 나타납니다.

+1

요청 - 응답 체인에 깨진 사용자 정의 작성기를 반환하는 깨진 사용자 정의'HttpServletResponseWrapper' 구현이 포함되어있는 경우에만 필요합니다. 표준 서블릿 및 JSF 구현의 경우에는 이것이 절대적으로 필요하지 않습니다. 해결 방법은 래퍼/작성기 구현을 수정하고 코드의 모든 부분을 수동으로 플러시하지 않아야합니다. – BalusC

관련 문제