Distinguish between conversion failure and validation failure in o: viewParamValidationFailed
I am using the OmniFaces <o:viewParam>
taghandler in my current project. I like it, it's great. And even more <o:viewParamValidationFailed>
. We can now send an error message if the validation or conversion fails. But I'm wondering if it is possible to distinguish between conversion failure and validation failure.
Let's say we want to send a Bad Request if the given view parameter is invalid and cannot be converted; in this case, send a "Not Found" message if the conversion was successful but the object was not found in the database; and send Forbidden if the user who was unable to access the selected object should not be available to the user.
Does anyone know a way to achieve this?
source to share
Unfortunately, it is impossible to distinguish between a ConverterException
and ValidatorException
when you only have UIInput#isValid()
. In theory, you could inspect and test the faces post to see if it represents a conversion or validation error, but this is not a foolproof approach, certainly not when localized.
Alternatively, you can declare multiple view parameters with the same parameter name. You don't have to specify value
to set it as a model value.
In an example based on your description, note that the model value is only set on the latter:
<o:viewParam name="foo">
<f:converter converterId="yourFooConverter" />
<o:viewParamValidationFailed sendError="400" />
</o:viewParam>
<o:viewParam name="foo">
<f:converter converterId="yourFooConverter" />
<f:validateRequired />
<o:viewParamValidationFailed sendError="404" />
</o:viewParam>
<o:viewParam name="foo" value="#{bean.foo}">
<f:converter converterId="yourFooConverter" />
<f:validateRequired />
<f:validator validatorId="yourRestrictedAccessValidator" />
<o:viewParamValidationFailed sendError="403" />
</o:viewParam>
To avoid the costly db invocation on every conversion, let the implementation YourFooConverter
store the converted value as a custom attribute FacesContext
and then validate it on every pass.
source to share