Как "выбросить" ошибку JSF2 404?

Скажем, что у меня есть приложение, которое управляет пользователями. Вы можете добавить нового пользователя, удалить его, редактировать детали и т.д. Каждый пользователь имеет идентификатор na и имеет страницу с подробной информацией по URL-адресу:

..../user/detail.jsf?id=123

Теперь, что должно произойти, если пользователь с ID 123 не существует? Я думаю, что естественная реакция была бы 404 стандартной ошибкой. Точно так же, как выводится, когда вы делаете опечатку в URL-адресе (например,/user/dtail.jsf). Итак, вопрос: есть ли такой метод?

Или, может быть, нужна ли эта реакция (404)?

Спасибо.

Ответ 1

Просто присоедините валидатор к параметру представления id и, если проверка не выполнена, установите код ошибки 404 в ответ.

например.

Рассмотрим этот простой Facelet:

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">

    <f:metadata>
        <f:viewParam id="id" name="id" value="#{myBean.id}" validator="#{myBean.validate}"/>
    </f:metadata>

    <h:body>

        <h:outputText value="#{myBean.id}"/>

    </h:body>

</html>

И следующая поддержка bean:

@ManagedBean
@ViewScoped
public class MyBean {

    private Long id;

    public void validate(FacesContext context, UIComponent component, Object object) {
        // Do some validation
        // And if failed:
        context.getExternalContext().setResponseStatus(404);
        context.responseComplete();
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

Ответ 2

(в итоге я искал что-то подобное, но вот еще один образец, который я использовал по аналогичной проблеме)

Отклик Validation/ExternalContext выше - это очень хороший способ справиться с этим, альтернативно (поскольку вы уже находитесь в контексте), вы можете справиться с ошибкой при анализе параметров из запроса и обработать его внутренне. Я думаю, что это больше того, как вы хотите справиться с этим в своем потоке, чем "здесь лучшее решение"

//Inside "SomeManagedBean"
  public String getParam()
  {
    String value = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("key");
    if(value == null)
      return "key not Exist";
    else
      return value;

  }

//Источник JSF 2.0 (something.xhtml) ... ...

Я думаю, что выше, как правило, проще работать внутри рамки (вам не нужно отправлять на страницу ошибок и прерывать поток), но на самом деле это просто архитектурное решение. Оба решения схожи, это просто вопрос нарушения потока или внутренней обработки. В любом случае ExternalContext является вашим другом.

Ответ 3

Как уже упоминалось, вы можете получить контекст из управляемого bean. Я пробовал использовать валидатор, но для меня это не применимо, поскольку я использовал два параметра для инициализации моего bean, и я хочу бросить 404. Для меня .setResponseStatus не выбрасывал 404-страничку. Просто дал неинформативную страницу браузера. Поэтому вместо этого я использовал responseSendError.