使用除IE之外的其他浏览器时,在servlet中不可用会话范围内的受管bean [英] Session scoped managed bean not available in servlet when using another browser than IE

查看:178
本文介绍了使用除IE之外的其他浏览器时,在servlet中不可用会话范围内的受管bean的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

直到最近,我一直在Servlet中使用以下代码来定位会话支持bean(如BalusC所建议).现在,它仅可在Internet Explorer上使用. Chrome和Firefox似乎正在获得一个全新的支持bean,而不是原始的支持bean.当在后备Bean中调用函数时,对于在后备Bean中肯定已在原始对象中初始化的对象,它会因空指针错误而失败.

I have been using the following bit of code in a servlet to locate a session backing bean (as suggested by BalusC) without problems until recently. Now it only works on Internet Explorer. Chrome and Firefox appear to be getting a totally new backing bean rather than the original backing bean. When calling functions in the backing bean, it falls over with null pointer errors for objects in the backing bean that were definitely initialized in the original.

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更改了其代码中的某些内容(不太可能).还有其他人有类似的问题吗?我对于从这里去哪里不知所措,因为似乎没有与找不到后备bean相关的任何错误,并且我的Java lib代码调试技巧也不是那么好(他们不注释他们的代码)很好,很难遵循);任何建议将不胜感激.

It is a while since I tested this code and there have been several updates to Java but I'm not sure if these are the cause; I have changed something in my configuration or Chrome and Firefox have changed something in their code (unlikely). Is anyone else having similar problems? I am at a loss as to where to go from here, as there does not appear to be any errors associated with not finding the backing bean and my debugging skills for the java lib code are not that great (they don't comment their code very well and it is hard to follow); any suggestions would be greatly appreciated.

我正在使用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.

I am using Netbeans 7.01, JSF 2.0, Glassfish 3.1, and a Derby database. I tested it on my tower and laptop and it is doing it on both (Win XP and Win 7). The JRE is 7 update 40 build 1.7.0_40-b43. JDK is 1.6.0_04. Chrome version is 29.0.1547.76 m. Firefox is 23.0.1. Internet Explorer is 8.0.6001.18702.

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

The FacesUtil is slightly different to BalusC's code (but it was working fine):

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

在此先感谢...

推荐答案

工作轮:由于某种原因,当从applet调用servlet时,Firefox和Chrome上的会话ID正在更改.我最终存储了会话ID,并在与Servlet的HttpURLConnection连接上进行设置,这迫使Servlet获取正确的后备bean.

Work-a-round: The session Id is changing on Firefox and Chrome when the servlet is called from the applet, for some reason. I ended up storing the session ID and setting it on the HttpURLConnection connection to the servlet, which forces the servlet to get the correct backing bean.

在productSelection支持bean中:

In the productSelection backing bean:

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

在包含小程序的网页上,我正在使用javascript函数等待小程序完全加载,然后告诉它加载标准文件,该文件将由用户修改,然后发送回辅助Bean进行处理.我只是将会话ID和条件文件传递给了applet:

On the web page containing the applet I am using a javascript function to wait until the applet is fully loaded before telling it to load a criteria file, which will be modified by the user and then sent back to the backing bean for processing. I have simply passed the session ID along with the criteria file to the applet:

<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>

在applet按钮代码中,要将修改后的条件文件通过servelet提交回支持bean,我将会话ID添加到HttpURLConnection连接中:

In the applet button code, to submit the modified criteria file back to the backing bean via the servelet, I added the session ID to the HttpURLConnection connection:

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

这篇关于使用除IE之外的其他浏览器时,在servlet中不可用会话范围内的受管bean的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆