2011-03-31 15 views
5

के साथ डेटाबेस में संग्रहीत फ़ाइल को डाउनलोड करने के लिए मुझे डेटाबेस में संग्रहीत फ़ाइल डाउनलोड करने की आवश्यकता है। मुझे लगता है कि मैंने सही ढंग से क्वेरी की है और इसे बुलाया है, मुझे नहीं पता कि मैं इसे जेएसएफ पेज में बटन से कैसे जोड़ सकता हूं। मैं भी सोच रहा हूं, क्या मुझे जेएसएफ पृष्ठ पर जाने से पहले सर्वर पर किसी फ़ोल्डर में उस छवि को सहेजना है। यदि हां, तो मैं यह कैसे कर सकता हूं? अब इसजेएसएफ 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; 
.... 

यहाँ एक सरल EJB कॉल कि क्वेरी तो आईडी मिलता है:

इस क्वेरी मैं db से बाइट [] वापस जाने के लिए उपयोग करें वह हिस्सा है जो मुझे भ्रमित करता है, मैं जेएसएफ पेज और प्रबंधित बीन के साथ कैसे कर सकता हूं?

@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... 

} 

} 

मैं जेएसएफ से प्रबंधित कमांड को कमांड बटन के भीतर से उस लंबी आईडी को कैसे पास कर सकता हूं? क्या यह अनुमति है? ईएल में

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

उत्तर

10

पासिंग मापदंडों केवल (6, बिलाव 7, आदि के रूप में Glassfish 3, JBoss) काम करता है जब web.xml सर्वलेट 3.0 के रूप में घोषित किया जाता है और servletcontainer भी इसका समर्थन करता है। कि इस विशेष मामले में बेहतर है

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

तुम भी पूरे वस्तुओं के साथ पारित कर सकते हैं,: वहाँ, अपने प्रयास में केवल एक सिंटैक्स त्रुटि है यहाँ सही तरीका है।

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

फिर, startDownload() विधि प्रतिक्रिया हेडर स्थापित करना चाहिए ताकि webbrowser क्या सामग्री प्रतिक्रिया शरीर का प्रतिनिधित्व करता टाइप करें और इसके साथ क्या करना है और अंत में प्रतिक्रिया शरीर के लिए सामग्री लिखने को समझता है। आप इसे ExternalContext की सहायता से कर सकते हैं। यहाँ एक किकऑफ़ उदाहरण है:

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() साथ अंतिम पंक्ति अनिवार्य है ताकि JSF समझता है कि यह संभावित रूप से कुछ दृश्य पर जाएं, नहीं करना चाहिए और इस तरह बाद में एक और JSF पृष्ठ के साथ प्रतिक्रिया malform।

+0

यदि सामग्री एक .doc फ़ाइल है तो ContentType क्या होना चाहिए। क्या उस विधि को कॉन्टेंट टाइप() वापस "टेक्स्ट/एक्सएमएल" या "टेक्स्ट/सादा" मिलना चाहिए? – sfrj

+2

ओह, एक शब्द दस्तावेज़ निश्चित रूप से एक पाठ फ़ाइल नहीं है। '.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

संबंधित मुद्दे