h:inputFile doesn't call Part setter - ajax

This is my first time using h:inputFile and I'm having some trouble.
The setter method for the Part attribute in my Managed Bean is never being called, so when the upload method is called, the Part object is always null.
Form and inputFile component
<h:form enctype="multipart/form-data">
<div class="pic add-pic">
<h:inputFile id="upload-test" required="true"
value="#{uploadController.uploadedFile}">
</h:inputFile>
<h:commandLink styleClass="pic add-pic"
action="#{uploadController.addPic()}">
<i class="fa fa-plus"></i>
<span>Add pic</span>
</h:commandLink>
</div>
</h:form>
Managed Bean
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.servlet.http.Part;
#ManagedBean
#ViewScoped
public class UploadController {
private Part uploadedFile;
public Part getUploadedFile() {
return this.uploadedFile;
}
public void setUploadedFile(Part uploadedFile) {
this.uploadedFile = uploadedFile;
}
public void addPic() {
System.out.println("Uploaded a file: " +
uploadedFile.getSubmittedFileName());
}
}
I've tried already with ajax in the inputFile
<h:inputFile id="upload-test" required="true"
value="#{uploadController.uploadedFile}">
<f:ajax execute="#form" listener="#{uploadController.addPic()}" />
</h:inputFile>
and with ajax in the commandLink
<h:commandLink styleClass="pic add-pic">
<i class="fa fa-plus"></i>
<span>Add pic</span>
<f:ajax execute="#form" listener="#{uploadController.addPic()}" />
</h:commandLink>
But neither options worked as well.
PS: I'm using javax.servlet-api version 3.1 and JSF 2.2.12 (Mojarra) and running on Wildfly 9.0.2
PS2: I'm using also Primefaces (not in this case), and I have the fileUpload filter in my web.xml (I've tried to remove it, tested and no success).

After several tries and after deploying a fresh project with only the defaults (just like #BalusC said in the comments of my question), I discovered that the problem was the PrimeFaces FileUploadFilter in web.xml!!
I got rid of it before, but I don't know why didn't worked that time, could've been some problem with the project deployment refresh provided by Eclipse.
But now I tried again and it worked!
Thanks #BalusC for your help!

Thanks BalusC and Diego Marques! I had a similar problem with my application, which was deployed on Tomcat 8 - the h:inputFile value "Part" setter was never called. Your help pointed me to some of my libraries which had already discovered that my issue was actually a Tomcat setting.
In case it helps to have it included here too, Tomcat (and likely Glassfish)needs the following setting to make it "spec-compliant".
<Context allowCasualMultipartParsing="true"
https://github.com/ocpsoft/rewrite/issues/136
Instead of doing the above context setting, you can have your bean marked with #MultipartConfig (and #WebServlet).

Related

Custom validator is not invoked when submitted value is empty [duplicate]

I created a custom validator which is not getting called when input is null.
My validator code:
#FacesValidator("requiredValidator")
public class RequredValidation implements Validator {
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
System.out.println("in valid GGGGGGGG");
}
My xhtml page code:
<p:message for="urlInput" />
<p:inputText id="urlInputv" value="#{coverageBean.firstname}" label="URL" maxlength="2" >
<f:validator validatorId="requiredValidator"></f:validator>
</p:inputText>
<p:message for="urlInputv" />
<p:commandButton value="submit" action="#{loginBean.validateText}" />
Now this is working when I am entering any value in text box, but it is not working when inputtext is null.
The server is using
Tomcat
primefaces 3.5
jsf2.0
Please could anyone tell what the problem is?
By default, JSF does not validate an empty submitted value if Bean Validation (JSR303) is not available in the environment. This behavior can be controlled with the context parameter javax.faces.VALIDATE_EMPTY_FIELDS.
The default value for javax.faces.VALIDATE_EMPTY_FIELDS is auto, meaning that empty fields are validated if Bean Validation (JSR303) is available in the class path.
If you want to validate empty fields anyway without Bean Validation, then explicitly set the context parameter in your web.xml to true like this:
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>true</param-value>
</context-param>
It must be said that you normally use required="true" in case you want to validate an input field as required. You don't need to perform that job in your custom validator then.
<p:inputText ... required="true" requiredMessage="Please enter value" />
Or, more abstract with <f:validateRequired>:
<p:inputText ... requiredMessage="Please enter value">
<f:validateRequired />
</p:inputText>
Do note that you can safely use multiple validators on the very same input component.
Did you try to put :
<p:inputText id="urlInputv" required="true"
....
required true is used to avoid null value by user.
If you don't want to have a required input, then initialize your value:
firstname = ""; //or a default value

Handling TagAttributeException and change ui:includeSrc

We have dynamic menu items in a page and the links for include-source .xhtml stored in the DB, in this scenario if source xhtml is wrongly input or failed to find the application context it throws TagAttributeException with Invalid Path message.
After this event, if we make any ajax request it failed, reason is in the restore-view phase tried to restore with invalid xhtml (include src).
Is there any way to handle this exception at the runtime and change the xhtml src to some default xhtml. So that any further AJAX call will work.
XHTML
<h:form prependId="false">
<p:commandButton actionListener="#{exceptionPF.includePage()}"
ajax="true"
value="Include Wrong Source" />
<p:commandButton actionListener="#{exceptionPF.includeRightPage()}"
ajax="true"
value="Include Right Source" />
<p:panel id="div1" >
<ui:include src="#{exceptionPF.srcPage}" />
</p:panel>
<p:ajaxExceptionHandler type="javax.faces.view.facelets.TagAttributeException"
update="exceptionDialog"
onexception="PF('exceptionDialog').show();" />
<p:dialog id="exceptionDialog" header="Exception '#{pfExceptionHandler.type}' occured!" widgetVar="exceptionDialog"
height="500px">
Message: #{pfExceptionHandler.message} <br/>
Stack-Trace: <h:outputText value="#{pfExceptionHandler.formattedStackTrace}" escape="false" /> <br />
<p:button onclick="document.location.href = document.location.href;"
value="Reload!"
rendered="#{pfExceptionHandler.type == 'javax.faces.application.ViewExpiredException'}" />
</p:dialog>
</h:form>
Bean
#Named
#ViewScoped
public class ExceptionPF implements Serializable {
String srcPage;
public String getSrcPage() {
return srcPage;
}
public void setSrcPage(String srcPage) {
this.srcPage = srcPage;
}
public void includePage()
{
setSrcPage("wrong.xhtml");
RequestContext.getCurrentInstance().update("div1");
}
public void includeRightPage()
{
setSrcPage("correct.xhtml");
RequestContext.getCurrentInstance().update("div1");
}
}
Error
19:38:08,978 INFO [stdout] (default task-14) *****BEFORE **** RESTORE_VIEW
19:38:08,985 INFO [stdout] (default task-14) *****AFTER **** RESTORE_VIEW
19:38:08,986 SEVERE [javax.enterprise.resource.webcontainer.jsf.context]
(default task-14) javax.faces.view.facelets.TagAttributeException:
/index.xhtml #33,62
<ui:include src="#{exceptionPF.srcPage}"> Invalid path : wrong.xhtml
at com.sun.faces.facelets.tag.ui.IncludeHandler.apply(IncludeHandler.jav
There's no way of handling an exception from the view side on when it's the view itself who is causing the exception.
You can use ViewDeclarationLanguage#viewExists() to check if a given view exists. You should do this before setting the srcPage and if necessary get hold of the wrong value in a separate (boolean) variable.
Here's how you can use it in flavor of an utility method:
public static boolean viewExists(String viewId) {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().getViewHandler()
.getViewDeclarationLanguage(context, viewId).viewExists(context, viewId);
}

OmniFaces equivalent of Seam <s:validateForm> to validate multiple fields

in seam faces is option of a validation of a whole form.
I can import:
xmlns:s="http://jboss.org/seam/faces"
and use:
<s:validateForm validatorId="oneOrMorePrimaryIndicesValidator"/>
Now we have to use omnifaces instead of seamfaces.
Is there any equivalent in omnifaces that do similar job?
Depends on the concrete functional requirement which isn't entirely clear from the question.
If you want to validate if one or more fields are filled out, use existing <o:validateOneOrMore>:
<o:validateOneOrMore components="foo bar baz" />
<h:inputText id="foo" />
<h:inputText id="bar" />
<h:inputText id="baz" />
Or, if you want to implement a custom validator for multiple fields, use <o:validateMultiple>:
<o:validateMultiple components="foo bar baz" validator="#{oneOrMorePrimaryIndicesValidator}" />
<h:inputText id="foo" />
<h:inputText id="bar" />
<h:inputText id="baz" />
Whereby #{oneOrMorePrimaryIndicesValidator} refers a managed bean (can be either JSF or CDI) which implements MultiFieldValidator:
#Named
#RequestScoped // Can also be #ApplicationScoped, depending on if validator should hold state.
public class OneOrMorePrimaryIndicesValidator implements MultiFieldValidator {
#Override
public boolean validateValues(FacesContext context, List<UIInput> components, List<Object> values) {
// ...
}
}
It should return false if values are invalid, otherwise true.
Either way, general usage instructions on e.g. components, message, invalidateAll and showMessageFor attributes can be found in ValidateMultipleFields javadoc.
A completely different alternative is to use <o:validateBean> with JSR303 bean validation groups to validate an entity at class level with a JSR303 ConstraintValidator<SomeGroupAnnotation, Bean>. Such a validator is not only useable in JSF (the web tier), but also in e.g. JPA (the data tier). E.g.
<h:inputText value="#{bean.entity.foo}" />
<h:inputText value="#{bean.entity.bar}" />
<h:inputText value="#{bean.entity.baz}" />
<o:validateBean value="#{bean.entity}" validationGroups="com.example.SomeGroup" />
A more concrete example is hard to give without having concrete code of current model and validator at hands.

JSF custom validator not invoked when submitted input value is null

I created a custom validator which is not getting called when input is null.
My validator code:
#FacesValidator("requiredValidator")
public class RequredValidation implements Validator {
public void validate(FacesContext context, UIComponent component,
Object value) throws ValidatorException {
System.out.println("in valid GGGGGGGG");
}
My xhtml page code:
<p:message for="urlInput" />
<p:inputText id="urlInputv" value="#{coverageBean.firstname}" label="URL" maxlength="2" >
<f:validator validatorId="requiredValidator"></f:validator>
</p:inputText>
<p:message for="urlInputv" />
<p:commandButton value="submit" action="#{loginBean.validateText}" />
Now this is working when I am entering any value in text box, but it is not working when inputtext is null.
The server is using
Tomcat
primefaces 3.5
jsf2.0
Please could anyone tell what the problem is?
By default, JSF does not validate an empty submitted value if Bean Validation (JSR303) is not available in the environment. This behavior can be controlled with the context parameter javax.faces.VALIDATE_EMPTY_FIELDS.
The default value for javax.faces.VALIDATE_EMPTY_FIELDS is auto, meaning that empty fields are validated if Bean Validation (JSR303) is available in the class path.
If you want to validate empty fields anyway without Bean Validation, then explicitly set the context parameter in your web.xml to true like this:
<context-param>
<param-name>javax.faces.VALIDATE_EMPTY_FIELDS</param-name>
<param-value>true</param-value>
</context-param>
It must be said that you normally use required="true" in case you want to validate an input field as required. You don't need to perform that job in your custom validator then.
<p:inputText ... required="true" requiredMessage="Please enter value" />
Or, more abstract with <f:validateRequired>:
<p:inputText ... requiredMessage="Please enter value">
<f:validateRequired />
</p:inputText>
Do note that you can safely use multiple validators on the very same input component.
Did you try to put :
<p:inputText id="urlInputv" required="true"
....
required true is used to avoid null value by user.
If you don't want to have a required input, then initialize your value:
firstname = ""; //or a default value

commandButton which is enabled by f:ajax does not invoke action when form is submitted

I am trying to make a commandButton enabled/disabled by using a checkbox. The commandbutton is disabled initially. When user checks the checkbox, the commandbutton turns into enabled. But it does not response when clicked the button.
If I make the commandbutton independent from checkbox, it works fine. But with checkbox, I get the problem that I mentioned above. Please help me
Here are codes.
index.xhtml
<h:form>
<h:selectBooleanCheckbox value="#{formSettings.licenseAccepted}" id="cb">
<f:ajax event="click" render="suB cb"/>
</h:selectBooleanCheckbox>
<h:outputText value="#{formSettings.msg}"/><br/>
<h:commandButton id="suB" disabled="false" value="Save" action="loginSuccessfull"/>
</h:form>
FormSettings.java
package classes;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
#ManagedBean
#RequestScoped
public class FormSettings
{
private boolean licenseAccepted = false;
private String msg = "Accept License";
public FormSettings(){};
public boolean isLicenseAccepted(){return this.licenseAccepted;};
public void setLicenseAccepted(boolean licenseAccepted){this.licenseAccepted = licenseAccepted;};
public String getMsg(){return this.msg;};
public void setMsg(String msg){this.msg = msg;};
}
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://java.sun.com/xml/ns/javaee"
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"
version="2.0">
<navigation-rule>
<from-view-id>/index.xhtml</from-view-id>
<navigation-case>
<from-outcome>loginSuccessfull</from-outcome>
<to-view-id>/login.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
</faces-config>
The bean has to be placed in the view scope in order to get it to work.
#ManagedBean
#ViewScoped
public class FormSettings {}
Enabling the button by ajax counts as one HTTP request. Submitting the form with the button thereafter counts as another HTTP request. As your bean is request scoped, it get freshly created on every HTTP request and garbaged by the end of request. As the boolean property defaults to false, the button get effectively disabled again when JSF is about to process the form submit on the second request.
See also:
How to choose the right bean scope?

Resources