0

How do I throw an error 404 if the ID was not found without sending a 302 redirect.

In my ViewScop I do a select and would like to return an error 404 with showing the content of the 404 error page (404.xhtml).

I tried the following which gives me justs a 302 redirect to the 404.xhtml:

@PostConstruct
public void initialize() {
    data = service.select(id.getValue());
    if (data == null) {
        FacesContext context = FacesContext.getCurrentInstance();
        context.getExternalContext().setResponseStatus(404);
        context.responseComplete();
        try {
            context.getExternalContext().redirect("/404.xhtml");
        } catch (IOException ex) {
        }
    }
}

Actually if I comment the redirect out, I get the correct error code, but still the called xhtml file gets rendered.

What is the best approach here? There are a lot of answers in SO but I didn't find one which was working for me.


EDIT: Here some other answers from SO, which was suggested by @Ben where with I found the correct answer:

wittich
  • 2,079
  • 2
  • 27
  • 50
  • 1
    Could you please add the answers you found here on SO and explain how they could not solve your problem so that no work is unneccesarily redone. – Ben Jun 21 '18 at 13:32

1 Answers1

0

Thx to @Ben I searched again and found the correct answer: How to throw 404 from bean in jsf !

The solution is to use .dispatch() on an ExternalContext.

dispatch

public abstract void dispatch(String path) throws IOException

Dispatch a request to the specified resource to create output for this response.

Servlet: This must be accomplished by calling the javax.servlet.ServletContext method getRequestDispatcher(path), and calling the forward() method on the resulting object.

If the call to getRequestDisatcher(path) returns null, send aServletResponse SC_NOT_FOUND error code.

Parameters:
path - Context relative path to the specified resource, which must start with a slash ("/") character

Throws:
FacesException - thrown if a ServletException occurs
IOException - if an input/output error occurs

So my solution looks like that now:

@PostConstruct
public void initialize() {
    data = service.select(id.getValue());
    if (data == null) {
        try {
            FacesContext context = FacesContext.getCurrentInstance();
            ExternalContext externalContext = context.getExternalContext();
            externalContext.setResponseStatus(HttpServletResponse.SC_NOT_FOUND);
            externalContext.dispatch("/404.xhtml");
            context.responseComplete();
        } catch (IOException ex) {
        }
    }
}
wittich
  • 2,079
  • 2
  • 27
  • 50