У меня есть фильтр сервлетов, который обрабатывает ошибки как ванильных сервлетов, так и 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);
}
}