- All Implemented Interfaces:
FaceletHandler
<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 per UIInput.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 per FacesContext.isValidationFailed().
When the sendRedirect attribute is set, a call to Faces.redirect(String, Object...) is made
internally to send the redirect. So, the same rules as to scheme and leading slash apply here.
When the sendError attribute is set, a call to Faces.responseSendError(int, String) is made
internally to send the error. You can therefore customize HTTP error pages via <error-page>
entries in web.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 as null, which causes an internal isRequired() check to
be performed instead of delegating the check to the standard UIInput implementation. This has the
consequence that PreValidateEvent and PostValidateEvent 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. When sendError 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
both sendRedirect and sendError.
<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 with required="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> in web.xml.
- Since:
- 2.0
- Author:
- Bauke Scholtz
-
Field Summary
Fields inherited from class jakarta.faces.view.facelets.TagHandler
nextHandler, tag, tagId -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionvoidapply(FaceletContext context, UIComponent parent) If the parent component is an instance ofUIViewRootorUIViewParameterand 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 voidIf the current request is not a postback and the current response is not already completed, and validation on the parent component has failed (forUIViewRootthis is checked byFacesContext.isValidationFailed()and forUIViewParameterthis 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 Details
-
ViewParamValidationFailed
The tag constructor.- Parameters:
config- The tag config.
-
-
Method Details
-
apply
If the parent component is an instance ofUIViewRootorUIViewParameterand 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 ofUIViewRootorUIViewParameter, or when there's already another<o:viewParamValidationFailed>tag registered on the same parent.IllegalArgumentException- When bothsendRedirectandsendErrorattributes are missing or simultaneously specified.IOException
-
processViewParamValidationFailed
If the current request is not a postback and the current response is not already completed, and validation on the parent component has failed (forUIViewRootthis is checked byFacesContext.isValidationFailed()and forUIViewParameterthis 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 thesendErrorattribute does not represent a valid 3-digit HTTP status code.
-