在 ViewScop 上写入 404 并在 JAVA JSF 中显示错误文件而无需重定向

Write 404 on ViewScop and display error file without redirect in JAVA JSF

如果在未发送 302 的情况下未找到 ID,我该如何抛出错误 404重定向。

在我的 ViewScop 中我做了一个 select 并且想 return 一个错误 404 显示 404 错误页面 (404.xhtml).

我尝试了以下方法,它给了我一个 302 重定向到 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) {
        }
    }
}

实际上,如果我注释掉重定向,我会得到正确的错误代码,但仍会呈现调用的 xhtml 文件。

这里最好的方法是什么? SO 中有很多答案,但我没有找到适合我的答案。


编辑: 这里有一些来自 SO 的其他答案,由 建议,我在其中找到了正确答案:

感谢 I searched again and found the correct answer: How to throw 404 from bean in jsf

解决方法是使用.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

所以我的解决方案现在看起来像这样:

@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) {
        }
    }
}