会话范围的受管 Bean 在使用 IE 以外的其他浏览器时在 servlet 中不可用



直到最近,我一直在 servlet 中使用以下代码来定位支持会话的 bean(如 BalusC 所建议的那样(,没有问题。现在它只适用于Internet Explorer。Chrome和Firefox似乎得到了一个全新的支持Bean,而不是原来的支持bean。在后备 Bean 中调用函数时,对于后备 Bean 中明确在原始中初始化的对象,它会因空指针错误而失败。

FacesContext facesContext = FacesUtil.getFacesContext(req, res);
ProductSelection productSelection = (ProductSelection) facesContext.getApplication().evaluateExpressionGet(facesContext, "#{productSelection}", ProductSelection.class);
if(productSelection.getProductType() == null)
{
   System.out.println("Sevlet: product type is NULL; did not get the original backing bean");
}
else
{
   System.out.println("Sevlet: product type is: " + productSelection.getProductType().getProductTypeName());
}

自从我测试这段代码以来已经有一段时间了,并且对 Java 进行了几次更新,但我不确定这些是否是原因;我已经更改了配置中的某些内容,或者Chrome和Firefox在其代码中更改了某些内容(不太可能(。还有其他人有类似的问题吗?我不知道从这里开始,因为似乎没有任何与找不到支持豆相关的错误,而且我对 java lib 代码的调试技能不是那么好(他们没有很好地注释他们的代码,很难遵循(;任何建议将不胜感激。

我正在使用Netbeans 7.01,JSF 2.0,Glassfish 3.1和Derby数据库。我在我的塔式和笔记本电脑上测试了它,它正在两者(Win XP和Win 7(上进行测试。JRE 是 7 更新 40 内部版本 1.7.0_40-b43。JDK 是 1.6.0_04。Chrome 版本是 29.0.1547.76 m。Firefox 是 23.0.1。Internet Explorer 是 8.0.6001.18702。

FacesUtil与BalusC的代码略有不同(但它工作正常(:

    package searchselection;
import javax.faces.FactoryFinder;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import javax.faces.context.FacesContextFactory;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
// By BalusC http://balusc.blogspot.com
// Utility to get the FacesContext.
// Used by the CriteriaServlet to get the backing bean when the user submits a customised
// search criteria object.
public class FacesUtil 
{
    // Getters -----------------------------------------------------------------
    //
    public static FacesContext getFacesContext(ServletRequest request, ServletResponse response) 
    {
        // Get current FacesContext.
        FacesContext facesContext = FacesContext.getCurrentInstance();
        // Check current FacesContext.
        if (facesContext == null) 
        {
            // Create new Lifecycle.
            LifecycleFactory lifecycleFactory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
            Lifecycle lifecycle = lifecycleFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
            // Create new FacesContext.
            FacesContextFactory contextFactory = (FacesContextFactory) FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
            facesContext = contextFactory.getFacesContext(
                    request.getServletContext(), request, response, lifecycle);
            // Create new View.
            UIViewRoot view = facesContext.getApplication().getViewHandler().createView(
                    facesContext, "");
            facesContext.setViewRoot(view);
            // Set current FacesContext.
            FacesContextWrapper.setCurrentInstance(facesContext);
        }
        return facesContext;
    }
    // Helpers -----------------------------------------------------------------
    // Wrap the protected FacesContext.setCurrentInstance() in a inner class.
    private static abstract class FacesContextWrapper extends FacesContext 
    {
        protected static void setCurrentInstance(FacesContext facesContext) 
        {
            FacesContext.setCurrentInstance(facesContext);
        }
    }
}

提前感谢...

Work-a-round:由于某种原因,当从小程序调用servlet时,会话ID在Firefox和Chrome上正在更改。我最终存储了会话 ID 并将其设置在与 servlet 的 HttpURLConnection 连接上,这迫使 servlet 获得正确的后备 bean。

在产品选择背豆中:

private String sessionID = ""; // With getter
.
.
.
FacesContext facesContext = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);
sessionID = session.getId();

在包含小程序的网页上,我使用 javascript 函数等到小程序完全加载后再告诉它加载一个标准文件,该文件将由用户修改,然后发送回后备 Bean 进行处理。我只是将会话 ID 与标准文件一起传递给小程序:

<SCRIPT language="javascript">
        function waitUntilLoaded() 
        {
           if (document.criteriaApplet.isActive()) 
           {
             var object = document.getElementById ("criteriaApplet");  
             criteriaApplet.loadCriteriaFile((object.codeBase + "#{productSelection.productUsage.searchCriteriaObjectUrl}"), "#{productSelection.sessionID}");
            }
           else 
           {
               settimeout(waitUntilLoaded(),500)
           }
        }
 </SCRIPT>

在小程序按钮代码中,为了通过 servlet 将修改后的标准文件提交回支持Bean,我将会话 ID 添加到 HttpURLConnection 连接中:

HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setUseCaches(false);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type", "application/x-java-serialized-object");
            connection.setRequestProperty("Cookie","JSESSIONID=" + sessionID);
            ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
            out.writeObject(searchSubmitObject);
            out.flush();
            out.close();

相关内容

  • 没有找到相关文章

最新更新