Reputation: 3826
I have a JSF2 page with a view parameter that must be looked up in a database. On the page the properties of that entity are then displayed.
Now I would like to handle the case where the view parameter is missing/invalid
<f:metadata>
<f:viewParam name="id" value="#{fooBean.id}" />
<f:event type="preRenderView" listener="#{fooBean.init()}" />
</f:metadata>
And the init()
code is as follows:
String msg = "";
if (id == null) {
msg = "Missing ID!";
}
else {
try {
entity = manager.find(id);
} catch (Exception e) {
msg = "No entity with id=" + id;
}
}
if (version == null) {
FacesUtils.addGlobalMessage(FacesMessage.SEVERITY_FATAL, msg);
FacesContext.getCurrentInstance().renderResponse();
}
Now my problem is that the remaing page is still rendered and I get errors in the application server log saying that entity is null (and therefore some elements are not rendered properly). I would like only the error message to be displayed.
Should I be returning a String so that a POST
to an error page is issued?
However if I choose that way, how do I add a custom error message? Passing Strings as view
parameters does not seem like a good idea at all.
Upvotes: 0
Views: 1108
Reputation: 23906
In my opinion, the best thing to do in these cases, is to send an HTTP response with the appropriate error code (404 for not found/invalid, 403 for forbidden, etc):
Add to your FacesUtils this utility method:
public static void responseSendError(int status, String message)
throws IOException {
FacesContext facesContext = FacesContext.getCurrentInstance();
facesContext.getExternalContext().responseSendError(status, message);
facesContext.responseComplete();
}
and then, change in your preRenderView listener to:
public void init() throws IOException {
if (id == null || id.isEmpty()) {
FacesUtils.responseSendError(404, "URL incomplete or invalid!");
}
else {
try {
entity = manager.find(id);
} catch (Exception e) { // <- are you sure you want to do that? ;)
FacesUtils.responseSendError(404, "No entity found!");
}
}
}
Upvotes: 3