I have the following page using JSF to upload a .pdf file to a folder designated on the server. However, the commandButton action does not seem to be firing at all, as none of my println()s show, nor my message update. If anyone could explain the issue, it would be greatly appreciated.
XHTML page:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:f="http://java.sun.com/jsf/core" xml:lang="en" lang="en">
<head>
<meta http-equiv="keywords" content="enter,your,keywords,here" />
<meta http-equiv="description"
content="A short description of this page." />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="Styles/style.css" />
<script type="text/javascript" src="http://ajax.microsoft.com/ajax/jquery/jquery-1.7.2.min.js"></script>
</head>
<body>
<h:form enctype="multipart/form-data">
<h:outputText value="First Name: " />
<h:inputText id="fname" size="40" value="#{userBean.firstName}" required="true"/> <br/>
<h:outputText value="Last Name: " />
<h:inputText id="lname" size="40" value="#{userBean.lastName}" required="true"/> <br/>
<h:outputText value="Position Sought: "/>
<h:inputText id="position" size="40" value="#{userBean.position}" required="true"/> <br/>
<h:outputText value="File to upload: " />
<t:inputFileUpload value="#{userBean.resume}" /> <br/>
<h:commandButton value="submit" action="#{userBean.submit}" />
<h:messages />
</h:form>
</body>
</html>
faces:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config version="2.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd">
<managed-bean>
<managed-bean-name>userProcessor</managed-bean-name>
<managed-bean-class>com.logic.UserProcessor</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>ID</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>firstName</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>lastName</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>password</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>resume</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>username</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>userBean</managed-bean-name>
<managed-bean-class>com.logic.UserBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>id</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>username</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>password</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>firstName</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>lastName</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>position</property-name>
<property-class>java.lang.String</property-class>
<value/>
</managed-property>
<managed-property>
<property-name>resume</property-name>
<property-class>org.apache.myfaces.custom.fileupload.UploadedFile</property-class>
<value/>
</managed-property>
</managed-bean>
<navigation-rule>
<from-view-id>/addUser.xhtml</from-view-id>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-view-id>/addUser.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/Home_Menu.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/Home_Menu.xhtml</from-view-id>
</navigation-rule>
<navigation-rule>
<from-view-id>/login.xhtml</from-view-id>
<navigation-case>
<from-outcome>failure</from-outcome>
<to-view-id>/login.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/Home_Menu.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/upload_resume.xhtml</from-view-id>
<navigation-case>
<from-action>#{userBean.submit}</from-action>
<from-outcome>success</from-outcome>
<to-view-id>/Home_Menu.xhtml</to-view-id>
</navigation-case>
<navigation-case>
<from-action>#{userBean.submit}</from-action>
<from-outcome>failure</from-outcome>
<to-view-id>/upload_resume.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
and the bean.submit()
public String submit() throws IOException {
String fileName = FilenameUtils.getName(resume.getName());
String contentType = resume.getContentType();
InputStream is = resume.getInputStream();
byte[] bytes = resume.getBytes();
Date date = new Date();
String ext = FilenameUtils.getExtension(fileName);
System.out.println("File upload started");
System.out.println("File name: " + fileName);
System.out.println("Timestamp: " + contentType);
System.out.println("Content type: " + date.toString());
System.out.println("File extension: " + ext);
// Now you can save bytes in DB (and also content type?)
if(ext != "pdf"){
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(String.format("File upload failed, please make sure that your file has the correct extension (.pdf)")));
System.out.println("File upload failed: incorrect file extension.");
return "failure";
} else {
writeInfoToDB();
is.read(bytes);
String folder = getFirstName().charAt(0) + getLastName(); //will not work if folder does not exist
File file = new File("C:\\Users\\MAR-PC01\\Desktop\\apache-tomcat-7.0\\uploads\\"
+ folder + "\\" + fileName);
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(String.format("File '%s' of type '%s' successfully uploaded!", fileName, contentType)));
return "success";
}
}
This form is submitted using multipart/form-data
encoding which is by default not supported by JSF. It would only work if Tomahawk's ExtensionsFilter
is properly been registered in web.xml
as per its documentation. This filter is the one responsible for parsing multipart/form-data
requests and converting the individual form-data
parts to normal request parameters so that JSF can transparently apply request parameters (so: the submitted values and the invoked actions) the usual way.
If the ExtensionsFilter
is not been registered and/or is not able to do its job properly due to some other disturbing factor in your webapp, then the form submit will never enter the JSF postback lifecycle.