0

I'm using a primefaces fileUpload with multiples and fileUploadListener method. The listener is called each time for each file uploaded, I would like to store each file in a arrayList and after the last is uploaded loop through the list and store them in a database.

My managed bean is viewScoped, would it be alright to have a static arrayList to store the uploads or is there a better way to deal with this?

Facelet

    <p:fieldset legend="Info">
       <p:selectOneRadio id="newold" value="#{newmailer.selectedCompStatus}">  
            <f:selectItem itemLabel="Existing Company" itemValue="exist" />  
            <f:selectItem itemLabel="New Company" itemValue="new" />   
            <p:ajax  listener="#{newmailer.setComp}" event="valueChange" update="main" execute="@all" />
       </p:selectOneRadio>  

       <p:panelGrid columns="2" styleClass="Grid" style="margin-bottom:10px" cellpadding="5" rendered="#{newmailer.exist}">    
                <h:outputLabel value="Company"  id="Company" />
                <p:selectOneMenu value="#{newmailer.selectedComp}" id="companies"  label="Company">
                    <f:selectItem itemLabel="Choose Company" itemValue="" />  
                    <f:selectItems value="#{mailerInfo.companies}" var="comp" />
                    <p:ajax  listener="#{demo.getCompanyMailer}" event="valueChange"  execute="@all" />
                </p:selectOneMenu> 
        </p:panelGrid>
        <p:panelGrid  id="newPanel" styleClass="Grid"  columns="2" style="margin-bottom:10px" cellpadding="5" rendered="#{!newmailer.exist and newmailer.showInfo}"> 
            <h:outputLabel value="Company"  id="Company2" />   
            <p:inputText id="newCompany" value="#{newmailer.selectedComp}" immediate="true"> 
                <f:ajax event="change"/>                
            </p:inputText>
        </p:panelGrid>

        <p:panelGrid styleClass="Grid" columns="2" style="margin-bottom:10px" cellpadding="5" rendered="#{newmailer.showInfo}">    
            <h:outputLabel value="Mailer Id"  />   
            <p:inputText id="mailerId" value="#{newmailer.mailerId}" immediate="true">
                <f:ajax event="change"/> 
            </p:inputText>
        </p:panelGrid>

    </p:fieldset>
    <p:fieldset legend="Status" rendered="#{newmailer.showInfo}">                             
        <p:selectOneRadio id="status"  value="#{newmailer.status}" immediate="true">  
            <f:selectItem itemLabel="Active" itemValue="A" />  
            <f:selectItem itemLabel="Inactive" itemValue="I" />   
            <f:ajax event="change"/>
        </p:selectOneRadio>  

    </p:fieldset>
    <p:fieldset legend="Description" rendered="#{newmailer.showInfo}">
        <p:inputTextarea rows="5" cols="30" value ="#{newmailer.desc}" counter="counter" maxlength="10"       
            counterTemplate="{0} characters remaining." autoResize="false" immediate="true">
            <f:ajax event="change"/>
        </p:inputTextarea>        
    </p:fieldset>
    <p:fieldset legend="Load Image" rendered="#{newmailer.showInfo}"> 
        <p:fileUpload fileUploadListener="#{newmailer.handleFileUpload}"  
            mode="advanced"   
            update="messages"  
            sizeLimit="100000"   
            allowTypes="/(\.|\/)(gif|jpe?g|png|pdf)$/"
            process="@form"
            multiple="true"

        />  
    </p:fieldset>
    <p:growl id="messages" showDetail="true"/>  

</p:panelGrid>
 <!--  <p:commandButton value="Submit" type="sumbit" action="#{newmailer.submit}" ajax="false"/>-->


</h:form>

Bean

 @ViewScoped
 @ManagedBean(name="newmailer")
 public class NewMailerBean implements Serializable{

private String status;
private String compStatus;
private String selectedCompStatus;
private String selectedComp;
private String mailerId;
private String desc;
private boolean exist;
private boolean showInfo;
public static Mailer mail;
public static boolean multi=false;
public ArrayList<byte []> images = new ArrayList<byte []>();

    public void handleFileUpload(FileUploadEvent event) {  



        Mailer mail = new Mailer(); 
        mail.setCompany(selectedComp);
        mail.setDesc(desc);
        mail.setMailerId(mailerId);
        mail.setStatus(status);
        mail.setUserId("test");

     try{

         InputStream inputStream = event.getFile().getInputstream();
         ByteArrayOutputStream out=new ByteArrayOutputStream(1024);

         int read = 0;
         byte[] bytes = new byte[1024];

         while ((read = inputStream.read(bytes)) != -1) {
             out.write(bytes, 0, read);
         }

         byte[] bytearray = out.toByteArray();
         inputStream.close();
         out.flush();
         out.close();

         images.add(bytearray);
         mail.setImg(bytearray);


     }catch(IOException e) {
         e.printStackTrace();
    }
Justin Cox
  • 326
  • 4
  • 22

1 Answers1

1

A static variable is class-level and thus shared among all instances of the same class and thus behaves like as a global application-wide variable. Every single visitor of your webapp would share the very same variable. Every single uploaded file of every single visitor would end up in the same list which is in turn visible to every single visitor.

Is this what you really want?

I don't think so. Just don't make it a static variable at all. Remove the static modifier and you should be all set with a view scoped bean. A view scoped bean lives as long as you're interacting with the same view by ajax.

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • BalusC thanks for answering first of all. Your post and blog has helped a lot with learning JSF. With the FileUploadEvent triggered multiple times I lose what I have added to the arrayList. The arrayList instance is defined for the class. How can I keep a arrayList intact between events? – Justin Cox Sep 25 '12 at 19:53
  • You mentioned that the bean is in the view scope. You're then all set. The view scoped bean instance lives as long as you're postbacking to the same view (as would happen when uploading multiple files asynchronously using ``). All you basically need to do is to remove the `static` modifier, as answered. If you're still facing problems with this setup, then it's caused elsewhere and *definitely* not to be solved by making the property `static`. – BalusC Sep 25 '12 at 20:02
  • I fully agree BalusC, when I debug, though the array is blank on the second call to the event. I have added code to the question. If I add the new instance of the array to the constructor would it make a difference? – Justin Cox Sep 25 '12 at 20:25
  • In other words, the view scoped bean is recreated on every postback request to the same view and thus behaving like a request scoped bean? If you put a breakpoint in the bean's constructor, is it invoked on every request? This is not normal and explains the symptoms you're facing. – BalusC Sep 25 '12 at 20:31
  • Bean constructor is only invoked on first call to facelet like it should be. There is a post for both uploads in firebug. – Justin Cox Sep 26 '12 at 13:37
  • The arrayList will hold data if I use the individual upload buttons on each file but not when using the Upload button on the fileUpload button bar – Justin Cox Sep 26 '12 at 14:53