How to Upload a file using JSF/Primefaces? - file-upload

I want to upload a file using JSF2.0/Primefaces using <p:fileUpload>. I haven't found any documentation that can help me.
I have two tables: Person(name,lastnam....) and file(id,path,name,size)
The scenario that I want to achieve is:
A user subscribe into my website, I save his information including the files uploaded
When the file is uploaded, I want to save it on my disk and save the
path into my database
(to keep the relation between a user and his files)
So when the user press the button Save button, I save all this information.
Here is my index.xhtml
<h:form >
<p:panel header="Add User" style="width: 500px; font-size: 14px">
<h:panelGrid width="width: 300px;" columns="2">
<h:outputLabel style="font-size: 13px" value="Name" /> <h:inputText value="#{AddPerson.lastname}" />
<h:outputLabel value="LastName"/> <h:inputText value="#{AddPerson.name}" />
<h:outputLabel value="Marital Status"/>
<h:selectOneMenu id="status" value="#{AddPerson.status}">
<f:selectItem itemValue="Single" itemLabel="Single"/>
<f:selectItem itemValue="Married" itemLabel="Married"/>
</h:selectOneMenu>
<h:outputLabel value="Bith date "/> <p:calendar value="#{AddPerson.birthdate}" id="popupButtonCal" showOn="button" />
<h:outputLabel value="email"/><h:inputText value="#{AddPerson.email}" />
<h:outputLabel value="mobile"/><h:inputText value="#{AddPerson.mobile}" />
<h:outputLabel value="fax"/><h:inputText value="#{AddPerson.fax}" />
<h:outputLabel value="Job"/><h:inputText value="#{AddPerson.Job}" />
<h:outputLabel value="addresse"/><h:inputText value="#{AddPerson.addresse}" />
<h:outputLabel value="code"/><h:inputText value="#{AddPerson.code}" />
<h:outputLabel value="Country"/><h:inputText value="#{AddPerson.country}" />
<h:outputLabel value="login"/><h:inputText value="#{AddPerson.login}" />
<h:outputLabel value="password"/><h:inputText value="#{AddPerson.password}" />
<h:outputLabel value="CV"/> <input type="file" name="uploaded_file"/>
<p:fileUpload fileUploadListener="#{AddPerson...." update="messages" sizeLimit="500000" allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
<p:growl id="messages" showDetail="true"/> // **example :taken from primefaces showcases**
<h:commandButton action="#{AddPerson.addUserDB}" value="Add User" />
</h:panelGrid>
</p:panel>
</h:form>
and here is My bean
public void addUserDB() {
try {
EntityTransaction entr = em.getTransaction();
entr.begin();
Person user = new Person();
user.setNom(lastname);
user.setPrenom(name);
user.setCodepostal(code);
user.setEmail(email);
user.setEtatCivil(status);
user.setFax(fax);
user.setDateNaissance(birthdate);
user.setMobile(mobile);
user.setAdresse(addresse);
user.setPays(country);
user.setLogin(login);
user.setPassword(password);
//**I should also add here the path of the file to the table and save the file on the disc !!!!**
em.persist(user);
entr.commit();
} catch (Exception e) {
System.out.println(e.getMessage());
System.out.println("Failed");
} finally {
em.close();
}
}

where's the implementation of the fileUploadListener? I normally just do this:
<p:fileUpload cancelLabel="#{msg['cancel']}" update="someComponent"
fileUploadListener="#{someBean.uploadListener}"
multiple="false" sizeLimit="1000000" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
Then my bean has a method that handles the file upload event. Something like this:
public void fileUpload(FileUploadEvent event) throws IOException {
String path = FacesContext.getCurrentInstance().getExternalContext()
.getRealPath("/");
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmss");
String name = fmt.format(new Date())
+ event.getFile().getFileName().substring(
event.getFile().getFileName().lastIndexOf('.'));
File file = new File(path + "catalogo_imagens/temporario/" + nome);
InputStream is = event.getFile().getInputstream();
OutputStream out = new FileOutputStream(file);
byte buf[] = new byte[1024];
int len;
while ((len = is.read(buf)) > 0)
out.write(buf, 0, len);
is.close();
out.close();
}
Keep a reference to the file path that has just been saved and use that for setting the corresponding user property in your addUserDB() method. So it's really a two step process. You first save the file somewhere in the server, then you save your user.

fileUpload has fileUploadListener. Note that, you should implement the logic to save the file contents yourself in your backing bean.
<p:fileUpload fileUploadListener="#{fileBean.handleFileUpload}">
public class FileBean {
public void handleFileUpload(FileUploadEvent event) {
UploadedFile file = event.getFile();
String fileName = file.getFileName();
long fileSize = file.getSize();
InputStream myInputStream = file.getInputstream();
//Save myInputStream in a directory of your choice and store that path in DB
}
}

Related

Selenium and JavaScript: Accessing multiple elements with the same ID

I've got a page (Angular8) with multiple button/input elements having the same ID.
The ID's are, in the order the appear on the page:
1: for="lastOppDokument-0-VERGE-LEGITIMASJON"
2: for="lastOppDokument-1-VERGE-VERGEMAL"
...
3: for="lastOppDokument-0-VERGE-LEGITIMASJON"
4: for="lastOppDokument-1-VERGE-VERGEMAL"
The elements on lines 1,3 and 2,4 have the same ID.
I'm trying to access the elements using XPath and index like this:
driver.findElement(By.xpath("(//input[#for='lastOppDokument-0-VERGE-LEGITIMASJON'])[1]
driver.findElement(By.xpath("(//input[#for='lastOppDokument-0-VERGE-LEGITIMASJON'])[2]
If I check the size:
int x = driver.findElements(By.xpath("(//input[#for='lastOppDokument-0-VERGE-LEGITIMASJON'])")).size();
it says "2", which is correct.
However, when I try to click those two buttons, the first one (LINE 1) is clicked, but then the next button on the page (LINE 2) i clicked istead of the one on LINE 3.
There's obviously something wrong with my XPath expression, but what? Also, the page is an Angular page, and in the markup code "for" is used to automatically index the ID. But selenium finds the elements (albeit not all the correct ones) using ID. But maybe I need to use something else to identify the correct elements?
UPDATE:
To troubleshoot, I'm skipping the use of a loop and just trying to access the two elements manually:
WebElement buttonToClick = driver.findElement(By.xpath("(//input[#id='lastOppDokument-0-VERGE-LEGITIMASJON'])[1]"));
filUtils.uploadFile(buttonToClick, legitimasjonfil);
WebElement buttonToClick2 = driver.findElement(By.xpath("(//input[#for='lastOppDokument-0-VERGE-LEGITIMASJON'])[2]"));
filUtils.uploadFile(buttonToClick2, legitimasjonfil);
The uploadFile (and related) methods:
public void uploadFile(WebElement id, String filename) {
id.sendKeys(getAbsolutePathToTestFile(TESTFILER_PATH + "/" + filename));
}
private String getAbsolutePathToTestFile(String path) {
return copyFileToTargetTempPath(path, path);
}
private String copyFileToTargetTempPath(String originPath, String destinationPath) {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream(originPath);
File destination = new File(TARGET_TEMP_PATH + destinationPath);
try {
assert resourceAsStream != null;
org.apache.commons.io.FileUtils.copyInputStreamToFile(resourceAsStream, destination);
} catch (IOException e) {
throw new RuntimeException(e);
}
return destination.getAbsolutePath();
}
UPDATE 2:
<td>
<span class="hb-felt knappesamling-gruppe hb-avstandIngen ng-star-inserted">
<input class="hb-lastOppFil-input hb-bare-skjermleser" type="file" id="lastOppDokument-0-VERGE-LEGITIMASJON"
accept=".pdf,.bmp,.gif,.jpeg,.jpg,.png,.tiff">
<label class="hb-knapp hb-knapp--standard hb-spinner-tekst" for="lastOppDokument-0-VERGE-LEGITIMASJON"> Velg fil </label><!---->
</span>
</td>
<td>
<span class="hb-felt knappesamling-gruppe hb-avstandIngen ng-star-inserted">
<input class="hb-lastOppFil-input hb-bare-skjermleser" type="file" id="lastOppDokument-1-VERGE-VERGEMAL"
accept=".pdf,.bmp,.gif,.jpeg,.jpg,.png,.tiff"><label class="hb-knapp hb-knapp--standard hb-spinner-tekst" for="lastOppDokument-1-VERGE-VERGEMAL"> Velg fil </label><!----></span>
<label class="hb-knapp hb-knapp--standard hb-spinner-tekst" for="lastOppDokument-1-VERGE-VERGEMAL"> Velg fil </label>
</span>

How to change wixsharp bootstrapper InstallDir

I have the following code in my HyperlinkLargeTheme.xml:
<Editbox Name="InstallDir" X="11" Y="143" Width="-91" Height="21" TabStop="yes" FontId="3" FileSystemAutoComplete="yes">[InstallDir]</Editbox>
<Button Name="BrowseButton" X="-11" Y="142" Width="75" Height="23" TabStop="yes" FontId="3">Browse</Button>
Here is the code how bootstrapper is used in C#:
var bootstrapper =
new Bundle(ProductInformation.ProductName, netPckg, cppRedistributables, erlangPackage, rabbitMqPackage, sdkPackage, webPackage)
{
OutFileName = ProductInformation.ProductName,
Manufacturer = ProductInformation.Manufacturer,
Version = new Version(ProductInformation.Version),
UpgradeCode = new Guid(ProductInformation.UpgradeCodeBundle),
StringVariablesDefinition = #"InstallDir=[ProgramFilesFolder][WixBundleManufacturer];ServerIp=127.0.0.1;ServerPort=12543;DbConnStr=;WebSitePort=80"
};
bootstrapper.DisableModify = "yes";
bootstrapper.IncludeWixExtension(WixExtension.Util);
bootstrapper.Application.LogoFile = #"Images\WizardSmallImageFile.bmp";
bootstrapper.Application.Attributes.Add("ThemeFile", #"Theme\HyperlinkLargeTheme.xml");
bootstrapper.Application.LocalizationFile = #"Theme\HyperlinkTheme.wxl";
bootstrapper.WixSourceGenerated += Bootstrapper_WixSourceGenerated;
bootstrapper.IconFile = ProductInformation.IconFile;
bootstrapper.OutFileName = ProductInformation.ProductName + " " + ProductInformation.Version;
bootstrapper.OutDir = AppDomain.CurrentDomain.BaseDirectory;
bootstrapper.PreserveTempFiles = true;
var productMsi = bootstrapper.Build();
The content of the editbox is then used by the installer to put files in the right destination. However when browsing for folder using the BrowseButton the content of the editbox is not changed. If I chenge the name attribute of the Editbox to "FolderEditbox" the browse button works as expexted, but then the files get installed to the default install directory regardless of the content of the editbox. How can I accomplish both browsing with button and installing to the selected directory?

Load file into textarea from uploaded files in primefaces

I would like to display text file into textarea in primefaces.
Following user define steps are:
Click on Upload control (user can upload multiple files)
I am fetching all uploaded files and displaying file name in radio button
From radio buttons, User will select one of the file and that file
will load into textarea.
While performing 3rd steps, I am getting following error
java.io.FileNotFoundException: C:\Users\UserName\Workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\ProjectDummy\upload_d8a75697_ad88_43fe_acd8_8133bf93d727_00000017.tmp (The system cannot find the file specified)
javax.servlet.ServletException: java.io.FileNotFoundException: C:\Users\UserName\Workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\work\Catalina\localhost\ProjectDummy\upload_d8a75697_ad88_43fe_acd8_8133bf93d727_00000017.tmp (The system cannot find the file specified)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:659)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
Following is the code:
Xhtml code:
<h:form method="POST" enctype="multipart/form-data"
prependId="false">
<p:growl id="messages" showDetail="true" />
<p:panelGrid columns="1">
<p:fileUpload
fileUploadListener="#{backingBean.handleFileUpload}"
mode="advanced" update="messages,console" auto="true"
multiple="true" />
<br />
<br />
<p:selectOneRadio id="console" value="#{backingBean.fileName}"
layout="grid" columns="1">
<f:selectItems value="#{backingBean.fileNames}" var="f"
itemLabel="#{fileName}" itemValue="#{fileName}" />
</p:selectOneRadio>
<p:commandButton value="Load" action="#{backingBean.loadFile}"
ajax="false" update="txtInput" process="#all" style="width:80px"></p:commandButton>
<br />
<br />
<p:inputTextarea id="txtInput" value="#{backingBean.fileText}"
rows="10" cols="50">
</p:inputTextarea>
</p:panelGrid>
</h:form>
BackingBean.java
public void handleFileUpload(FileUploadEvent event) throws IOException, NotSerializableException {
li = new ArrayList<UploadedFile>();
li.add(event.getFile());
setLi(li);
ListIterator<UploadedFile> list = li.listIterator();
while (list.hasNext()) {
String str = event.getFile().getFileName();
System.out.println(str);
++count;
fileNames.add(str);
fileList.add(event.getFile());
list.next();
}
}
public void loadFile() throws IOException, NotSerializableException {
String filenameRadio = getFileName();
for (int i = 0; i < count; i++) {
String fileS = fileList.get(i).getFileName();
if (fileS.equalsIgnoreCase(filenameRadio)) {
setUploadedFile(fileList.get(i));
InputStream is = getUploadedFile().getInputstream();
int read = 0;
byte[] bytes = new byte[(int) fileList.get(i).getSize()];
String s1;
while ((read = is.read(bytes)) != -1) {
s1 = new String(fileList.get(i).getContents());
setFileText(s1);
System.out.println(getFileText());
}
is.close();
}
}
}
Could help me to solve this error ?

How do I alter the text property of my label to display my "if" statements?

What do I need to place in my SLabel text=" " to display what is defined with my if statements?
Here is my code so far:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.events.SliderEvent;
protected function ValueSlider_changeHandler(event:SliderEvent):void
{
ValueLabel.text = String(ValueSlider.value);
if(String(ValueSlider.value) == "0")
ValueLabel.text = "150";
if(String(ValueSlider.value) == "1")
ValueLabel.text = "333";
if(String(ValueSlider.value) == "2")
ValueLabel.text = "543";
if(String(ValueSlider.value) == "3")
ValueLabel.text = "9342";
}
]]>
</fx:Script>
<s:Panel x="199" y="141" width="250" height="200">
<s:HSlider id="ValueSlider" x="78" y="69" maximum="3" minimum="0" stepSize="1" value="1"/>
<s:Label id="ValueLabel" x="109" y="38" text= "{ValueLabel.text}"/>
</s:Panel>
import mx.events.SliderEvent;
<s:HSlider id="ValueSlider" x="78" y="69" maximum="3" minimum="0" stepSize="1" value="1"/>
s:HSlider spark has no SliderEvent
s:HSlider should bind to mx:HSlider. mx:HSlider has no stepSize so remove it.
so that the "ValueSlider_changeHandler(event)" to be effective, it must be set to:
change="ValueSlider_changeHandler(event)"
The complete Line:
<mx:HSlider id="ValueSlider" x="78" y="69" maximum="3" minimum="0" value="1" change="ValueSlider_changeHandler(event)"/>
Now it should look like:
<fx:Script>
<![CDATA[
import mx.events.SliderEvent;
private var slvalue:int = 0;
protected function ValueSlider_changeHandler(event:SliderEvent):void
{
slvalue = ValueSlider.value;
if(slvalue == 0)
ValueLabel.text = "150";
if(slvalue == 1)
ValueLabel.text = "333";
if(slvalue == 2)
ValueLabel.text = "543";
if(slvalue == 3)
ValueLabel.text = "9342";
}
]]>
</fx:Script>
<s:Panel x="199" y="141" width="250" height="200">
<mx:HSlider id="ValueSlider" x="78" y="69" maximum="3" minimum="0" value="1" change="ValueSlider_changeHandler(event)"/>
<s:Label id="ValueLabel" x="109" y="38" text= "{ValueLabel.text}"/>
</s:Panel>
You can NOT test it like :
ValueLabel.text = String(ValueSlider.value);
if(String(ValueSlider.value) == "0")
ValueLabel.text = "150";
ValueLabel.text = "150" is immediately overwritten by the next event !!!
Store it in a local variable! Above: slvalue

Identification of objects in Flash Builder 4

I have a very simple question, but I do not know how to do that i can handle in AS script object identifier.
For example, I have a few pictures:
<mx:Image x="125" y="262" source="card/1.jpg" width="98" height="165" id="card1"/>
<mx:Image x="247" y="262" source="card/1.jpg" width="98" height="165" id="card2"/>
<mx:Image x="379" y="262" source="card/1.jpg" width="98" height="165" id="card3"/>
I need to give them a variety of sources taken from the array:
card1.source = "http://***/gallery/7/"+String(arrayOfNumber[0])+".jpg";
card2.source = "http://***/gallery/7/"+String(arrayOfNumber[1])+".jpg";
card3.source = "http://***/gallery/7/"+String(arrayOfNumber[2])+".jpg";
But this is the wrong decision and need the cycle:
for (var i:uint=0; i<=arrayOfNumber.lenght; i++){
card[i].source = "http://***/gallery/7/"+String(arrayOfNumber[i])+".jpg";
}
But that i must use instead of card[i]?
If you place all the images inside a container such as Group (flex 4.x) or Box (Flex 3), you could cycle through the children / elements of that container:
<fx:Script>
<![CDATA[
private var arrayOfNumber:Array = []; // Place your image file names here
private function loopThroughImages():void
{
var n:int = imageContainer.numElements;
for (var i:int = 0; i < n; i++)
{
Image(imageContainer.getElementAt(i)).source = "http://***/gallery/7/"+arrayOfNumber[i]+".jpg";
}
}
]]>
</fx:Script>
<s:Group id="imageContainer">
<mx:Image x="125" y="262" width="98" height="165"/>
<mx:Image x="247" y="262" width="98" height="165"/>
<mx:Image x="379" y="262" width="98" height="165"/>
<s:Group />
[Edit: Wow just realized I'm a year too late.]