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
Related
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).
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);
}
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.
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
I'm using Spring 3.2.0. I have registered a few custom property editors for some basic needs as follows.
import editors.DateTimeEditor;
import editors.StrictNumberFormatEditor;
import java.math.RoundingMode;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import org.joda.time.DateTime;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.beans.propertyeditors.URLEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.WebRequest;
#ControllerAdvice
public final class GlobalDataBinder
{
#InitBinder
public void initBinder(WebDataBinder binder, WebRequest request)
{
binder.setIgnoreInvalidFields(true);
binder.setIgnoreUnknownFields(true);
//binder.setAllowedFields(someArray);
NumberFormat numberFormat=DecimalFormat.getInstance();
numberFormat.setGroupingUsed(false);
numberFormat.setMaximumFractionDigits(2);
numberFormat.setRoundingMode(RoundingMode.HALF_UP);
binder.registerCustomEditor(DateTime.class, new DateTimeEditor("MM/dd/yyyy HH:mm:ss", true));
binder.registerCustomEditor(Double.class, new StrictNumberFormatEditor(Double.class, numberFormat, true));
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
binder.registerCustomEditor(URL.class, new URLEditor());
}
}
I have this many editors registered so far. Two of them DateTimeEditor and StrictNumberFormatEditor have been customized by overriding respective methods to fulfill custom needs of number format and Joda-Time.
Since I'm using Spring 3.2.0, I can take advantage of #ControllerAdvice.
Spring recommends to list a set of allowed fields with the setAllowedFields() method so that malicious users can not inject values into bound objects.
From the docs about DataBinder
Binder that allows for setting property values onto a target object,
including support for validation and binding result analysis. The
binding process can be customized through specifying allowed fields,
required fields, custom editors, etc.
Note that there are potential security implications in failing to set
an array of allowed fields. In the case of HTTP form POST data for
example, malicious clients can attempt to subvert an application by
supplying values for fields or properties that do not exist on the
form. In some cases this could lead to illegal data being set on
command objects or their nested objects. For this reason, it is highly
recommended to specify the allowedFields property on the DataBinder.
I have a big application and obviously there are thousands of fields. Specifying and listing all of them with the setAllowedFields() is a tedious job. Additionally, somehow I need to remember them.
Changing a web page to remove some fields or add additional fields as the need arises again requires to modify the parameter value of the setAllowedFields() method to reflect those changes.
Is there any alternative to this?
Instead of using setAllowedFields() to white-list, you can use setDisallowedFields() to black-list. For example, from the petclinic sample application:
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {
dataBinder.setDisallowedFields("id");
}
From a pure security standpoint white-listing is preferred to black-listing, but it maybe help ease the burden some.
setAllowedFields() is very handy when using entity objects directly in web layer. Alternatively, one could use dedicated data transfer objects (DTO), from which entity objects are constructed in the service layer. Not only can the factories be re-used, but also used outside the web context, e.g. for asynchronous messages. Besides, DTO inheritance doesn't have to follow entity inheritance, so you are free to design the DTO hierarchy according to the needs of the use-cases.
from http://static.springsource.org/spring-webflow/docs/2.0.x/reference/htmlsingle/spring-webflow-reference.html#view-model
4.9. Specifying bindings explicitly
Use the binder element to configure the exact set of model bindings usable by the view. This is particularly useful in a Spring MVC environment for restricting the set of "allowed fields" per view.
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="creditCard" />
<binding property="creditCardName" />
<binding property="creditCardExpiryMonth" />
<binding property="creditCardExpiryYear" />
</binder>
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
If the binder element is not specified, all public properties of the model are eligible for binding by the view. With the binder element specified, only the explicitly configured bindings are allowed.
Each binding may also apply a converter to format the model property value for display in a custom manner. If no converter is specified, the default converter for the model property's type will be used.
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" converter="shortDate" />
<binding property="checkoutDate" converter="shortDate" />
<binding property="creditCard" />
<binding property="creditCardName" />
<binding property="creditCardExpiryMonth" />
<binding property="creditCardExpiryYear" />
</binder>
<transition on="proceed" to="reviewBooking" />
<transition on="cancel" to="cancel" bind="false" />
</view-state>
In the example above, the shortDate converter is bound to the checkinDate and checkoutDate properties. Custom converters may be registered with the application's ConversionService.
Each binding may also apply a required check that will generate a validation error if the user provided value is null on form postback:
<view-state id="enterBookingDetails" model="booking">
<binder>
<binding property="checkinDate" converter="shortDate" required="true" />
<binding property="checkoutDate" converter="shortDate" required="true" />
<binding property="creditCard" required="true" />
<binding property="creditCardName" required="true" />
<binding property="creditCardExpiryMonth" required="true" />
<binding property="creditCardExpiryYear" required="true" />
</binder>
<transition on="proceed" to="reviewBooking">
<transition on="cancel" to="bookingCancelled" bind="false" />
</view-state>
In the example above, all of the bindings are required. If one or more blank input values are bound, validation errors will be generated and the view will re-render with those errors.
A solution to use binder with DTO (companydata in example) in case most of the form input values should be converted to null if empty, but there is a need to add few exceptions (setDisallowedFields didn't work for me).
#InitBinder()
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
}
#InitBinder
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {
binder.registerCustomEditor(String.class, "companydata.companyName", new StringTrimmerEditor(false));
binder.registerCustomEditor(String.class, "companydata.companyNumber", new StringTrimmerEditor(false));
}