바닐라 서블릿과 JSF
페이지 모두에 대한 오류를 처리하는 서블릿 필터가 있습니다.http GET 매개 변수 JSF 사용시 일부가 누락되었습니다.
오류가 감지되면 사용자는 피드백을 보낼 수있는 오류 페이지로 리디렉션됩니다. 그런 다음 ErrorBean
개체의 값을 읽으려고합니다. 그러나 때로는 오류가 존재하지 않습니다 - 오류가 50-50 번 발생할 가능성이 있습니다. 내가
FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()
를 사용하는 경우
는 때때로 1 개 항목, 때로는 빈지도와지도를 반환합니다. 모든 경우에 ID는 http 수준에서 전달됩니다.
저는이 문제의 원인을 실제로 재현 할 수 없습니다. 여기에 관련 코드 (도우미 메소드 + 빈 구현 생략)가 있습니다. ErrorFilter는 /*
에 맵핑되고 ErrorBean은 JSF가 관리하는 세션 범위 bean입니다.
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);
}
}
나는 그것이 왜 실패하는지 정확히 알지 못했습니다. 당신이 제안한 해결책이 잘 작동 했으므로, 그것을 해결 방법으로 구현했습니다. 세션에 토큰 속성을 저장합니다. 이것은 강력하게 작동합니다. –