Class ViewParamValidationFailed
- java.lang.Object
-
- jakarta.faces.view.facelets.TagHandler
-
- org.omnifaces.taghandler.ViewParamValidationFailed
-
- All Implemented Interfaces:
FaceletHandler
public class ViewParamValidationFailed extends TagHandler
<o:viewParamValidationFailed>
allows the developer to handle a view parameter validation failure with either a redirect or an HTTP error status, optionally with respectively a flash message or HTTP error message. This tag can be placed inside<f:metadata>
or<f|o:viewParam>
. When placed in<f|o:viewParam>
, it will be applied when the particular view parameter has a validation error as perUIInput.isValid()
. When placed in<f:metadata>
, and no one view parameter has already handled the validation error via its own<o:viewParamValidationFailed>
, it will be applied when there's a general validation error as perFacesContext.isValidationFailed()
.When the
sendRedirect
attribute is set, a call toFaces.redirect(String, Object...)
is made internally to send the redirect. So, the same rules as to scheme and leading slash apply here. When thesendError
attribute is set, a call toFaces.responseSendError(int, String)
is made internally to send the error. You can therefore customize HTTP error pages via<error-page>
entries inweb.xml
. Otherwise the server-default one will be displayed instead.<f:viewParam required="true"> fail
As a precaution; be aware that
<f:viewParam required="true">
has a design error in current Mojarra and MyFaces releases (as of now, Mojarra 2.2.7 and MyFaces 2.2.4). When the parameter is not specified in the query string, it is retrieved asnull
, which causes an internalisRequired()
check to be performed instead of delegating the check to the standardUIInput
implementation. This has the consequence thatPreValidateEvent
andPostValidateEvent
listeners are never invoked, which the<o:viewParamValidationFailed>
is actually relying on. This is fixed in<o:viewParam>
.Examples
In the example below the client will be presented an HTTP 400 error when at least one view param is absent.
<f:metadata> <o:viewParam name="foo" required="true" /> <o:viewParam name="bar" required="true" /> <o:viewParamValidationFailed sendError="400" /> </f:metadata>
In the example below the client will be redirected to "login.xhtml" when the "foo" parameter is absent, regardless of the "bar" parameter. When the "foo" parameter is present, but the "bar" parameter is absent, nothing new will happen. The process will proceed "as usual". I.e. the validation error will end up as a faces message in the current view the usual way.
<f:metadata> <o:viewParam name="foo" required="true"> <o:viewParamValidationFailed sendRedirect="login.xhtml" /> </o:viewParam> <o:viewParam name="bar" required="true" /> </f:metadata>
In the example below the client will be presented an HTTP 401 error when the "foo" parameter is absent, regardless of the "bar" or "baz" parameters. When the "foo" parameter is present, but either the "bar" or "baz" parameter is absent, the client will be redirected to "search.xhtml".
<f:metadata> <o:viewParam name="foo" required="true"> <o:viewParamValidationFailed sendError="401" /> </o:viewParam> <o:viewParam name="bar" required="true" /> <o:viewParam name="baz" required="true" /> <o:viewParamValidationFailed sendRedirect="search.xhtml" /> </f:metadata>
In a nutshell: when there are multiple
<o:viewParamValidationFailed>
tags, they will be applied in the same order as they are declared in the view. So, with the example above, the one nested in<f|o:viewParam>
takes precedence over the one nested in<f:metadata>
.Messaging
By default, the first occurring faces message on the parent component will be copied, or when there is none then the first occurring global faces message will be copied. When
sendRedirect
is used, it will be set as a global flash error message. WhensendError
is used, it will be set as HTTP status message.You can override this message by explicitly specifying the
message
attribute. This is applicable for bothsendRedirect
andsendError
.<o:viewParamValidationFailed sendRedirect="search.xhtml" message="You need to perform a search." /> ... <o:viewParamValidationFailed sendError="401" message="Authentication failed. You need to login." />
Note, although all of above examples use
required="true"
, this does not mean that you can only use<o:viewParamValidationFailed>
in combination withrequired="true"
validation. You can use it in combination with any kind of conversion/validation on<f|o:viewParam>
, even bean validation.Design notes
You can technically nest multiple
<o:viewParamValidationFailed>
inside the same parent, but this is not the documented approach and only the first one would be used.You can not change the HTTP status code of a redirect. This is not a Faces limitation, but an HTTP limitation. The status code of a redirect will always end up as the one of the redirected response. If you intend to "redirect" with a different HTTP status code, then you should be using
sendError
instead and specify the desired page as<error-page>
inweb.xml
.- Since:
- 2.0
- Author:
- Bauke Scholtz
-
-
Field Summary
-
Fields inherited from class jakarta.faces.view.facelets.TagHandler
nextHandler, tag, tagId
-
-
Constructor Summary
Constructors Constructor Description ViewParamValidationFailed(TagConfig config)
The tag constructor.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description void
apply(FaceletContext context, UIComponent parent)
If the parent component is an instance ofUIViewRoot
orUIViewParameter
and is new, and the current request is not a postback, and not in render response, and all required attributes are set, then subscribe the parent component to thePostValidateEvent
.protected void
processViewParamValidationFailed(ComponentSystemEvent event)
If the current request is not a postback and the current response is not already completed, and validation on the parent component has failed (forUIViewRoot
this is checked byFacesContext.isValidationFailed()
and forUIViewParameter
this is checked byUIInput.isValid()
), then send either a redirect or error depending on the tag attributes set.-
Methods inherited from class jakarta.faces.view.facelets.TagHandler
getAttribute, getRequiredAttribute, toString
-
-
-
-
Constructor Detail
-
ViewParamValidationFailed
public ViewParamValidationFailed(TagConfig config)
The tag constructor.- Parameters:
config
- The tag config.
-
-
Method Detail
-
apply
public void apply(FaceletContext context, UIComponent parent) throws IOException
If the parent component is an instance ofUIViewRoot
orUIViewParameter
and is new, and the current request is not a postback, and not in render response, and all required attributes are set, then subscribe the parent component to thePostValidateEvent
. This will invoke theprocessViewParamValidationFailed(ComponentSystemEvent)
method after validation.- Throws:
IllegalStateException
- When the parent component is not an instance ofUIViewRoot
orUIViewParameter
, or when there's already another<o:viewParamValidationFailed>
tag registered on the same parent.IllegalArgumentException
- When bothsendRedirect
andsendError
attributes are missing or simultaneously specified.IOException
-
processViewParamValidationFailed
protected void processViewParamValidationFailed(ComponentSystemEvent event)
If the current request is not a postback and the current response is not already completed, and validation on the parent component has failed (forUIViewRoot
this is checked byFacesContext.isValidationFailed()
and forUIViewParameter
this is checked byUIInput.isValid()
), then send either a redirect or error depending on the tag attributes set.- Parameters:
event
- The component system event.- Throws:
IllegalArgumentException
- When thesendError
attribute does not represent a valid 3-digit HTTP status code.
-
-