http GET параметр SOMETIMES отсутствует при использовании JSF - PullRequest
0 голосов
/ 28 мая 2009

У меня есть фильтр сервлетов, который обрабатывает ошибки как ванильных сервлетов, так и JSF страниц.

Если обнаружена ошибка, пользователь перенаправляется на страницу с ошибкой, где он может оставить отзыв. Затем я пытаюсь прочитать значение в объекте ErrorBean. Тем не менее, иногда ошибка отсутствует - существует 50-50 вероятность ее появления.

Когда я использую

FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()

иногда возвращает карту с 1 записью, а иногда и пустой картой. В каждом случае идентификатор передается на уровне http.

Я не могу действительно воспроизвести, что вызывает это. Вот соответствующий код (вспомогательные методы + пустые реализации опущены). ErrorFilter отображается в /*, а ErrorBean является компонентом области сеанса, управляемым JSF.

ErrorFilter

public class ErrorFilter implements Filter 
{
  public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException 
  {
    HttpServletRequest hreq = (HttpServletRequest) req;
    HttpServletResponse hres = (HttpServletResponse) resp;

    try 
    {
      chain.doFilter(req, resp);
    } 
    catch (IOException e) 
    {
      handleError(e, hreq, hres);
    } 
    catch (ServletException e) 
    {
      handleError(e, hreq, hres);
    } 
    catch (RuntimeException e) 
    {
      handleError(e, hreq, hres);
    }
  }

  private static void handleError(Throwable e, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
  {
    final RequestInfo requestInfo = new RequestInfo(getUri(req), req.getSession().getId(), null, null, UserFactory.getUser(), InetAddress.getByName(req.getRemoteAddr()));
    String token = new DecimalFormat("00000000").format(Math.abs(RANDOM.nextInt() % Integer.MAX_VALUE));
    //log msg
    //send mail in a different thread

    if (!req.getRequestURI().startsWith("/faces/error.jsp")) 
    {
      resp.sendRedirect("/faces/error.jsp?token=" + token);
    } 
    else 
    {
      //log that an infite loop occurred
      throw new ServletException(crapMsg, e);
    }
  }
}

ErrorBean

public class ErrorBean implements Serializable 
{
  private String feedback;
  private String lastToken;

  public String getLastErrorCode() 
  {
    return "your token: " + getToken();
  }

  private String getToken() 
  {
    final String token = (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("token");
    //here the "token" returns null although it is sent via get.

    if (token != null) 
    {
        if (!token.equals(lastToken)) 
        {
          // reset data on token change.
          feedback = null;
        }
        lastToken = token;
    }

    return lastToken;
  }

  public void setFeedback(String feedback) 
  {
    this.feedback = feedback;
  }

    public String getFeedback() 
    {
      if (feedback == null) 
      {
        feedback = getDefaultMessage();
      }

      return feedback;
    }

  public void send()
  {
    sendMail(lastToken,feedback);
  }
}

Ответы [ 3 ]

2 голосов
/ 02 июня 2009

С моей скромной точки зрения, в контексте «Лица» параметр должен изменяться в первый раз, когда запрос уже перенаправлен на: resp.sendRedirect("/faces/error.jsp?token=" + token);

Но когда вы делаете какой-то другой запрос, Faces манипулирует своей системой навигации и перенаправляет страницу, и, очевидно, что в это время фильтр делает chain.doFilter(req,resp);, что разрешает выполнение модели навигации JSF и, таким образом, удаляет ваш параметр запроса. .

Мое предложение заключается в том, что вы можете добавить его к другому значению сеанса. Тогда вам будет легче манипулировать.

0 голосов
/ 28 мая 2009

Страницы с ошибками, как правило, не являются хорошими кандидатами для JSF в контексте чего-либо большего, чем сам JSF (например, из фреймворка webapp). И да, FaceContext - это не то, от чего вы можете зависеть, когда хотите. Он создан сервлетом Faces для обработки запроса JSF и отбрасывается по завершении запроса. У него больше нет постоянства от запроса к запросу.

Кроме того, URL имеют совершенно другое значение в JSF, чем в большинстве веб-приложений. Они больше похожи на дескриптор, используемый для отслеживания разговора, чем на абсолютное указание того, какая страница запрашивается или отображается.

0 голосов
/ 28 мая 2009

Я не думаю, что FacesContext доступен в фильтре сервлетов. Не запускается ли фильтр до нажатия на FacesServlet (который создает FacesContext)?

Попробуйте прочитать: http://www.thoughtsabout.net/blog/archives/000033.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...