2011-03-31 3 views
5

데이터베이스에 저장된 파일을 다운로드해야합니다. 내가 정확히 쿼리를 한 것 같아서 JSF 페이지의 버튼에 어떻게 연결할 수 있을지 모르겠다. 또한 궁금해서, JSF 페이지로 전달하기 전에 이미지를 서버의 폴더에 저장해야합니까? 그렇다면 어떻게 할 수 있습니까? 이제이JSF 2.0을 사용하여 데이터베이스에 저장된 파일을 다운로드하는 방법

@Stateless(name = "ejbs/FileDownloaderEJB") 
public class FileDownloaderEJB implements IFileDownloaderEJB { 

@PersistenceContext 
private EntityManager em; 

public byte[] downloadGarbage(Long id) { 
    Query query = em.createNamedQuery("downloadGarbage"); 
    query.setParameter("idParam", id); 

    Object o = query.getSingleResult(); 
    byte[] tmpArray = (byte[]) o; 
    return tmpArray; 
} 

: 여기

@NamedQuery(name = "downloadGarbage", query = "SELECT g.file FROM Garbage g WHERE g.id :idParam") 
@Entity 
public class Garbage implements Serializable { 
@Lob 
@Column(nullable = false) 
private byte[] file; 
.... 

해당 쿼리가 다음 ID를 얻을 호출하는 간단한 EJB는 다음과 같습니다

내가 DB에서 바이트 []를 반환하는 데 사용하는 쿼리입니다 저를 혼란스럽게하는 부분입니다. 위의 내용을 JSF 페이지와 관리 빈으로 어떻게 할 수 있습니까?

@ManagedBean 
@RequestScoped 
public class DownloadController { 

@EJB 
private FileDownloaderEJB fileDownloaderEJB; 

    ... 

    private Garbage garbage; 

public void startDownload(Long id) { 
    fileDownloaderEJB.downloadGarbage(id); 
//HOW TO START THE DOWNLOAD? 
//Other Get Set Methods... 

} 

} 

또한 어떻게 긴 ID를 commandButton 내에서 JSF의 managedBean으로 전달할 수 있습니까? 허용됩니까? web.xml 서블릿은 3.0로 선언하고 servletcontainer 또한 지원하는 경우에 EL

<!-- How to pass the value of id from --> 
<h:commandButton action="downloadController.startDownload(#{garbage.id})"> 

답변

10

매개 변수 전달 전용 (6 톰캣 (7) 등과 같은 글래스 피시 3 보스)을 작동한다. 단지 구문 오류가 여기에 올바른 방법, 당신의 시도에있다 : 심지어 함께 전체 개체를 전달할 수 있습니다

<h:commandButton action="#{downloadController.startDownload(garbage.id)}" /> 

, 즉이 특별한 경우에 좋습니다. 에서는 WebBrowser 콘텐츠는 응답 본문이 나타내는 입력하고 그것으로 무엇을해야하고 마지막으로 응답 본문에 내용을 쓰는 것을 이해할 수 있도록

<h:commandButton action="#{downloadController.startDownload(garbage)}" /> 

다음, startDownload() 메소드는 응답 헤더를 설정해야합니다. ExternalContext의 도움으로 모든 것을 할 수 있습니다. JSF는 몇 가지보기로 이동하고, 따라서 잠재적으로 이후 다른 JSF 페이지와 응답을 malform 안된다는 이해할 수 있도록

public void startDownload(Garbage garbage) { 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 
    externalContext.setResponseHeader("Content-Type", garbage.getContentType()); 
    externalContext.setResponseHeader("Content-Length", garbage.getContent().length); 
    externalContext.setResponseHeader("Content-Disposition", "attachment;filename=\"" + garbage.getFileName() + "\""); 
    externalContext.getResponseOutputStream().write(garbage.getContent()); 
    facesContext.responseComplete(); 
} 

FacesContext#responseComplete()와 마지막 줄은 필수입니다 : 여기에 킥오프 예입니다.

+0

.doc 파일 인 경우 ContentType이어야합니다. 해당 메소드 getContentType()이 "text/xml"또는 "text/plain"을 반환해야합니까? – sfrj

+2

오, Word 문서는 확실히 텍스트 파일이 아닙니다. '.doc'은'application/msword'이고'.docx'는'application/vnd.openxmlformats-officedocument.wordprocessingml.document'입니다. 파일 이름을 기반으로 프로그래밍 방식으로 결정하려면'ServletContext # getMimeType()'을 사용할 수 있습니다. http://stackoverflow.com/questions/2426773/when-do-browsers-send-application-octet-stream-as-content-type/2426952#2426952 – BalusC

+0

감사합니다. 시도해 보겠습니다. – sfrj

관련 문제