2012-07-16 10 views
7

Ich habe eine Sichtweite Bohne, wo ich eine Person erstellen. Eine Person kann ein Bild haben. Dieses Bild wird auf die gleiche Seite hochgeladen, auf der die Person erstellt wurde. Das Bild wird nicht in einer Datenbank oder auf einer Festplatte gespeichert (da die Person noch nicht erstellt wurde). Die Bean muss ein Sichtbereich sein, da eine Person an anderer Stelle erstellt werden kann und dieselbe Bean verwendet. Wenn die Bean für die Sitzung konfiguriert ist und ein Benutzer ein Bild hochlädt, aber die Person nicht speichert, wird das Bild beim nächsten Versuch des Benutzers, eine Person zu erstellen, angezeigt.Anzeige hochgeladenes Bild in JSF

Ich löste das mit zwei Bohnen; Eine Ansicht scoped Bean, um die Person zu erstellen, und eine Session-Bean, um das Bild hochzuladen und das Bild als Stream zu erhalten. Dies verursacht jedoch das oben erwähnte Problem.

Wie kann ich das besser lösen?

Die Upload-Bohne:

@ManagedBean(name = "uploadBean") 
@SessionScoped 
public class UploadBean 
{ 
    private UploadedFile uploadedFile; 

    public UploadedFile getUploadedFile() 
    { 
     return uploadedFile; 
    } 

    public StreamedContent getUploadedFileAsStream() 
    { 
     if (uploadedFile != null) 
     { 
      return new DefaultStreamedContent(new ByteArrayInputStream(uploadedFile.getContents())); 
     } 
     return null; 
    } 

    public void uploadFile(FileUploadEvent event) 
    { 
     uploadedFile = event.getFile(); 
    } 
} 

Der create-a-Person-Bean:

@ManagedBean(name = "personBean") 
@ViewScoped 
public class PersonBean 
{ 
    private Person newPerson = new Person(); 

    public Person getNewPerson() 
    { 
     return newPerson; 
    } 

    private UploadedFile getUploadedPicture() 
    { 
     FacesContext context = FacesContext.getCurrentInstance(); 
     ELContext elContext = context.getELContext(); 
     UploadBean uploadBean = (UploadBean) elContext.getELResolver().getValue(elContext, null, "uploadBean"); 
     return uploadBean.getUploadedFile(); 
    } 

    public void createPerson() 
    { 
     UploadedFile uploadedPicture = getUploadedPicture(); 
     // Create person with picture; 
    } 
} 

Die entsprechende JSF Seite Teil:

<h:form enctype="multipart/form-data"> 
    <p:outputPanel layout="block" id="personPicture"> 
     <p:graphicImage height="150" 
      value="#{uploadBean.uploadedFileAsStream}" 
      rendered="#{uploadBean.uploadedFileAsStream != null}" /> 
    </p:outputPanel> 
     <p:fileUpload auto="true" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" 
      fileUploadListener="#{uploadBean.uploadedFile}" 
      update="personPicture" /> 
    <p:commandButton value="Save" actionListener="#{personBean.createPerson()}"/> 
</h:form> 

Antwort

3

ich für einen anderen gegangen sind Ansatz. Ich ging ursprünglich für die Anzeige eines hochgeladenen Bildes, aber wenn die Person noch nicht erstellt wurde, schien es eine bessere Idee, es alle Client-Seite zu halten. Ich fand this question und erstellt die auf der gewählten Antwort basierend folgende:

Im Kopf I html5shiv umfassen, wenn der Browser IE ist und die Version von weniger als 9 für Kompatibilität:

<h:outputText value="&lt;!--[if lt IE 9]&gt;" escape="false" /> 
<h:outputScript library="js" name="html5shiv.js" /> 
<h:outputText value="&lt;![endif]--&gt;" escape="false" /> 

Anzeigen/laden die Bild ich habe diese Elemente:

<p:fileUpload binding="#{upload}" mode="simple" 
    allowTypes="/(\.|\/)(gif|jpe?g|png)$/" 
    value="#{personBean.uploadedPicture}"/> 
<p:graphicImage value="#" height="150" binding="#{image}" /> 

Und einige JavaScript/jQuery Magie:

function readPicture(input, output) 
{ 
    if (input.files && input.files[0]) 
    { 
     var reader = new FileReader(); 
     reader.onload = function(e) 
     { 
      output.attr('src', e.target.result); 
     }; 
     reader.readAsDataURL(input.files[0]); 
    } 
} 

$("[id='#{upload.clientId}']").change(
    function() 
    { 
     readPicture(this, $("[id='#{image.clientId}']")); 
    }); 

Die uploadedPicture Eigenschaft ist jetzt eine einfache Eigenschaft:

@ManagedBean(name = "personBean") 
@ViewScoped 
public class PersonBean 
{ 
    private UploadedFile uploadedPicture; 

    public UploadedFile getUploadedPicture() 
    { 
     return uploadedPicture; 
    } 

    public void setUploadedPicture(UploadedFile uploadedPicture) 
    { 
     this.uploadedPicture = uploadedPicture; 
    } 
} 
+2

Es ist interessant, dass Sie nach einem Beispiel in JSF gefragt haben und Sie mit etwas "Javascript/JQuery Magie" beendet haben. Auch Ihr Kommentar zu der anderen Antwort ist mehr als notwendig, weil das Beispiel von ihm ziemlich nett ist. Es gibt viele JSF-Wege, um Ihre Aufgabe gut zu erledigen - und Sie müssen JS hier nicht hinzufügen. Können Sie Ihre Frage auch bearbeiten oder beantworten? Frage und Antwort passen nicht zusammen. – alexander

+0

Die Antwort löste das Problem, das ich hatte, also wie passen sie nicht zusammen? Ich möchte auch sagen, dass die Frage auf den 16. Juli 2012 datiert ist, also vor mehr als zwei Jahren. Ich kann sicher sagen, dass diese Frage für mich irrelevant ist. Wenn etwas mit meiner Antwort nicht stimmt, können Sie sie bearbeiten. ;-) – siebz0r

3

Add.xhtml

<h:form id="add-form" enctype="multipart/form-data"> 
     <p:growl id="messages" showDetail="true"/> 
     <h:panelGrid columns="2"> 
       <p:outputLabel for="choose" value="Choose Image :" /> 
       <p:fileUpload id="choose" validator="#{productController.validateFile}" multiple="false" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" value="#{productController.file}" required="true" mode="simple"/> 
      <p:commandButton value="Submit" ajax="false" update="messages" id="save-btn" actionListener="#{productController.saveProduct}"/> 
     </h:panelGrid> 
</h:form> 

Hier wird Bean Code:

@ManagedBean 
@RequestScoped 
public class ProductController implements Serializable{ 
    private ProductBean bean; 
    @ManagedProperty(value = "#{ProductService}") 
    private ProductService productService; 
    private StreamedContent content; 
    private UploadedFile file; 
    public StreamedContent getContent() { 
     FacesContext context = FacesContext.getCurrentInstance(); 

     if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) { 
       return new DefaultStreamedContent(); 
      } 
     else{ 
      String imageId = context.getExternalContext().getRequestParameterMap().get("id"); 
      Product product = getProductService().getProductById(Integer.parseInt(imageId)); 
      return new DefaultStreamedContent(new ByteArrayInputStream(product.getProductImage())); 
     } 
    } 
    public ProductController() { 
     bean = new ProductBean(); 
    } 

    public void setContent(StreamedContent content) { 
     this.content = content; 
    } 
    public UploadedFile getFile() { 
     return file; 
    } 

    public void setFile(UploadedFile file) { 
     this.file = file; 
    } 
    public void saveProduct(){ 
     try{ 
      Product product = new Product(); 
      product.setProductImage(getFile().getContents()); 

      getProductService().saveProduct(product); 
      file = null; 

     } 
     catch(Exception ex){ 
      ex.printStackTrace(); 
     } 
    } 
    public void validateFile(FacesContext ctx, 
      UIComponent comp, 
      Object value) { 
     List<FacesMessage> msgs = new ArrayList<FacesMessage>(); 
     UploadedFile file = (UploadedFile)value; 
     int fileByte = file.getContents().length; 
     if(fileByte > 15360){ 
      msgs.add(new FacesMessage("Too big must be at most 15KB")); 
     } 
     if (!(file.getContentType().startsWith("image"))) { 
      msgs.add(new FacesMessage("not an Image file")); 
     } 
     if (!msgs.isEmpty()) { 
      throw new ValidatorException(msgs); 
     } 
    } 
} 

diese Zeilen Code in Web hinzufügen. xml

<filter> 
    <filter-name>PrimeFaces FileUpload Filter</filter-name> 
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class> 
</filter> 
<filter-mapping> 
    <filter-name>PrimeFaces FileUpload Filter</filter-name> 
    <servlet-name>Faces Servlet</servlet-name> 
</filter-mapping> 

Und folgende JAR-Dateien im WEBINF/lib-Ordner.

commons-io-X.X and commons-fileupload-X.X, recommended most recent version. 

commons-io-2.4, commons-io-2.4-javadoc, commons-io-2.4-Quellen, commons-io-2.4-Tests, commons-io-2.4-Test-Quellen, commons -fileupload-1.3, commons-Fileupload-1.3-javadoc, commons-Fileupload-1.3-Quellen, commons-Fileupload-1.3-Tests, commons-Fileupload-1.3-Test-Quellen

Ansicht.xhtml

+2

Versuchen Sie, Ihre Beispiele kurz zu halten. Es gibt eine Menge Code, der nicht notwendig ist. Es macht das Beispiel nur weniger lesbar. – siebz0r