public class ViewParamValidationFailed extends TagHandler implements ComponentSystemEventListener
<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, String...)
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.
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>
.
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>
.
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.
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 JSF 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
.
nextHandler, tag, tagId
Constructor and Description |
---|
ViewParamValidationFailed(TagConfig config)
The tag constructor.
|
Modifier and Type | Method and Description |
---|---|
void |
apply(FaceletContext context,
UIComponent parent)
If the parent component is an instance of
UIViewRoot or UIViewParameter 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 the PostValidateEvent . |
void |
processEvent(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 (for
UIViewRoot this is checked by
FacesContext.isValidationFailed() and for UIViewParameter this is checked by
UIInput.isValid() ), then send either a redirect or error depending on the tag attributes set. |
getAttribute, getRequiredAttribute, toString
public ViewParamValidationFailed(TagConfig config)
config
- The tag config.public void apply(FaceletContext context, UIComponent parent) throws IOException
UIViewRoot
or UIViewParameter
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 the PostValidateEvent
. This will invoke the
processEvent(ComponentSystemEvent)
method after validation.apply
in interface FaceletHandler
IllegalArgumentException
- When the parent component is not an instance of UIViewRoot
or
UIViewParameter
, or when there's already another <o:viewParamValidationFailed>
tag
registered on the same parent, or when both sendRedirect
and sendError
attributes are
missing or simultaneously specified.IOException
public void processEvent(ComponentSystemEvent event) throws AbortProcessingException
UIViewRoot
this is checked by
FacesContext.isValidationFailed()
and for UIViewParameter
this is checked by
UIInput.isValid()
), then send either a redirect or error depending on the tag attributes set.processEvent
in interface ComponentSystemEventListener
IllegalArgumentException
- When the sendError
attribute does not represent a valid 3-digit
HTTP status code.AbortProcessingException
Copyright © 2012–2014 OmniFaces. All rights reserved.