i have a servlet filter that handles errors for both vanilla servlets and jsf pages.
if an error is detected the user is redirected to an error page where he can give feedback.
then i try to read the value in the ErroBean it is there - SOMETIMES. :( about 50% of the time.
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()
sometimes returns a map with 1 entry and sometimes an empty map. in every case, id is passed at http level.
i can't really reproduce what is causing this. here are the relevant codes (helper methods + emptly implementations omitted) :
the ErrorFilter is mapped at /* and the ErrorBean is a session scope bean managed by JSF
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);
}
}
}
}
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);
}
}