Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JSF时,http GET参数有时会丢失_Java_Http_Jsf_Servlets - Fatal编程技术网

Java 使用JSF时,http GET参数有时会丢失

Java 使用JSF时,http GET参数有时会丢失,java,http,jsf,servlets,Java,Http,Jsf,Servlets,我有一个servlet过滤器,用于处理普通servlet和JSF页面的错误 如果检测到错误,用户将被重定向到错误页面,在那里他可以给出反馈。然后我尝试读取ErrorBean对象中的值。然而,有时错误并不存在——存在错误的可能性为50% 当我使用 FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap() 它有时返回一个带有1个条目的映射,有时返回一个空映射。在任何情况下,id都是在http级别传

我有一个servlet过滤器,用于处理普通servlet和
JSF
页面的错误

如果检测到错误,用户将被重定向到错误页面,在那里他可以给出反馈。然后我尝试读取
ErrorBean
对象中的值。然而,有时错误并不存在——存在错误的可能性为50%

当我使用

FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap()
它有时返回一个带有1个条目的映射,有时返回一个空映射。在任何情况下,id都是在http级别传递的

我真的无法重现是什么导致了这一切。以下是相关代码(省略了helper方法+空实现)。ErrorFilter映射到
/*
,ErrorBean是由JSF管理的会话范围bean

错误过滤器

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);
  }
}

我认为FacesContext在Servlet过滤器中不可用。在点击FacesServlet(创建FacesContext)之前是否运行过滤器


试着阅读:

在任何比JSF本身更大的上下文中,错误页面通常都不适合JSF(例如,在webapp框架中)。是的,FaceContext并不是任何时候都可以使用的东西。它是由facesservlet创建的,用于处理JSF请求,当请求完成时,它将被丢弃。它不再具有从一个请求到另一个请求的长期持久性


而且,URL在JSF中的意义与在大多数web应用程序中的意义完全不同。它们更像是用于跟踪对话的句柄,而不是请求或显示的页面的绝对指示。

以我的拙见来看,当请求已经重定向时,faces上下文应该第一次看到参数vary:
resp.sendRedirect(“/faces/error.jsp?token=“+token”)

但是,当您发出一些其他请求时,Faces会对其导航系统进行操作并重定向页面,显然,过滤器正在执行
chain.doFilter(req,resp)

我的建议是,您可以将其添加到另一个会话值中,这样会更容易操作。

我相信他的意思是错误页面是一个JSF页面,它使用托管bean来查找过滤器设置的HTTP参数(在这种情况下,上下文将可用)。他有注释“创建带有“int”标记的errorInfo对象”。如果看不到这个物体以及它是如何使用的,很难说。据我们所知,该对象上的.getToken()可能会返回null。该标记只是一个如下生成的随机字符串:this.token=new DecimalFormat(“00000000”).format(Math.abs(random.nextInt()%Integer.MAX_VALUE));请注意,在过滤器中根本不使用facescontext。在ErrorBean中使用它来获取参数。我没有弄清楚它有时失败的确切原因。。您提出的解决方案效果很好,我以这种方式实现了它。在会话中存储令牌属性。这一点非常有效。