I want to validate my url with prettyfaces and get an HTTP 404 if the object does not exist. My URL should look like /code/788?date=13.12.2015
.
My prettyfaces config looks something like:
<url-mapping id="code">
<pattern value="/code/#{/[0-9]+/ code: prettyUrlCheckBean.newCode}" />
<query-param name="date">#{navigationBean.calendarDateAsString}</query-param>
<view-id value="/content/codes.jsf"/>
<action>#{prettyUrlCheckBean.checkEntryUrlWithNewCode}</action>
</url-mapping>
Currently the action will take the parameter from the beans, look if the code exists at the given date in the database and then redirect either to the homepage (with the parameters set in the session) or to the 404 page. However the HTTP codes will be 302
and 200
instead of a direct 404
.
I tried a validator in both the pattern and the query-param but in either case I have not access to the other part of the URL and can therefore not validate if the object exists.
My prettyfaces version is 2.0.12.Final.
I think the simplest way to perform such validation is to do it in the action method. There you have all the information you need and sending a 404 in case of validation errors is straight forward. I always use a small helper class for this:
public class FacesRequests {
public static void sendForbidden() {
sendStatusCode( 403 );
}
public static void sendNotFound() {
sendStatusCode( 404 );
}
private static void sendStatusCode( int status ) {
FacesContext context = FacesContext.getCurrentInstance();
try {
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
response.sendError( status );
context.responseComplete();
}
catch( IOException e ) {
throw new IllegalStateException( "Could not send error code", e );
}
}
}
Than you can basically do something like this:
public String myActionMethod() {
boolean valid = ...;
if( !valid ) {
FacesRequests.sendNotFound();
return null;
}
// business code here
}