2012-07-16 22 views
7

私は人を作成するビュースコープのbeanを持っています。人は写真を撮ることができます。この写真は人物と同じページにアップロードされます。写真は、データベースまたはディスクに保存されません(人物はまだ作成されていないため)。人は他の場所で作成でき、同じBeanを使用するため、Beanはビュースコープにする必要があります。 Beanがセッションスコープで、ユーザーが画像をアップロードしてもその人物を保存しない場合は、次にユーザーが人物を作成しようとしたときに画像が表示されます。JSFでアップロードした画像を表示

私は2つの豆を使ってこれを解決しました。 1つのビューのスコープ付きBeanを使用してユーザーを作成し、セッションスコープ付きBeanを使用してピクチャをアップロードし、ピクチャをストリームとして取得します。しかし、これは上記の問題を引き起こします。

どうすればこの問題を解決できますか?

アップロード豆:

@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(); 
    } 
} 

作成-人の豆:

@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; 
    } 
} 

関連するJSFページの一部:私は異なるために行ってきた

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

答えて

3

アプローチ。私は最初にアップロードされたイメージを表示するために行ったが、Personがまだ作成されていない場合は、それをすべてのクライアント側に保つ方が良い考えのように思えた。私はthis questionを発見し、選ばれた回答に基づいて次のように作成しました:

ヘッドでは、ブラウザはIEとバージョンは互換性のために9未満である場合、私はhtml5shivを含める:

<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" /> 

表示する/アップロード

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

そして、いくつかのJavaScript/jQueryの魔法:

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}']")); 
    }); 
画像私は、これらの要素を持っています

uploadedPictureプロパティが単純なプロパティです:

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

    public UploadedFile getUploadedPicture() 
    { 
     return uploadedPicture; 
    } 

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

興味深いことに、JSFでの例を尋ねて、「Javascript/JQueryの魔法」で終わりました。他の答えに対するあなたのコメントは、彼の例がとてもいいので、欲張り以上のものです。あなたの仕事をかなりうまくやるJSFの方法がたくさんあります.JSをここに入れる必要はありません。質問や回答を編集してもらえますか?質問と回答が合わない。 – alexander

+0

答えは私が持っていた問題を解決しました。私はまた、質問が2012年7月16日であることを述べたいと思います。それは2年以上前です。私はこの質問が私にとって無関係だと言うことはできます。私の答えに何か問題があれば、それを編集することができます。 ;-) – 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> 

ここで豆コード管理されている:

@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); 
     } 
    } 
} 

はウェブでこれらのコード行を追加します。 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> 

以下のWEBINF/libフォルダのjarファイル。

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

コモンズ-IO-2.4、コモン-IO-2.4のJavadoc、コモン-IO-2.4ソース、コモン-IO-2.4試験、コモン-IO-2.4テストソース、コモン-fileupload-1.3、コモンズ・ファイルアップロード-1.3-javadocの、コモンズ・ファイルアップロード-1.3-源、コモンズ・ファイルアップロード-1.3-テスト、コモンズ・ファイルアップロード-1.3-テストソース

ビュー。xhtml

<h:form id="ShowProducts"> 
    <p:dataTable rowsPerPageTemplate="3,6,9" var="products" paginator="true" rows="3" emptyMessage="Catalog is empty" value="#{productController.bean.products}"> 
     <p:column headerText="Product Name"> 
      <p:graphicImage width="80" height="80" value="#{productController.content}"> 
       <f:param name="id" value="#{products.productId}" /> 
      </p:graphicImage> 
      #{products.productName} 
     </p:column> 
    </p:dataTable> 
</h:form> 
+2

例を短くしてください。そこには不要なコードがたくさんあります。これは例をあまり読みにくくするだけです。 – siebz0r

関連する問題