jsp:setProperty for bean无法正常工作

时间:2009-12-02 13:52:30

标签: jsp properties set javabeans

您好我发现set属性标签无法正常工作。我有一个jsp,我将其作为portlet包含在webcenter中。

<jsp:useBean id="pathEditor" class="backing.bean.AppletBean" scope="page"/>

<jsp:getProperty name="pathEditor" property="username" />
${pageContext.request.remoteUser}
<jsp:setProperty name="pathEditor" property="username" value="${pageContext.request.remoteUser}"/>
<jsp:getProperty name="pathEditor"  property="username" />

我正在从同一个m / c的两个不同浏览器登录。第一个用户名值是正确的,而第二个登录打印${pageContext.request.remoteUser}正确但<jsp:getProperty name="pathEditor" property="username" />打印先前登录的用户。它给人的印象是setProperty根本没有被调用。可以任何身体建议什么可能这里错了。我使用两个不同的浏览器,没有静态变量。我保持两个浏览器打开这个测试用例。是不是因为在webcenter中处理portlet的方式。如果我将bean的范围声明为页面,是不是正确的线程安全方式。我能做些什么才能让它安全?我已经将bean属性变量设置为volatile,但这没有任何好处。还是我可以在使用后销毁豆子?我该如何销毁豆子?

所以如果我包括这个 - &lt;%@ page isThreadSafe =“false”%&gt;在jsp中,这应该工作。但它也无法正常工作。

编辑#调试代码后,我看到了这种不寻常的行为。 我将System.out.println放在我的bean中,以查看来自jsp的值。 虽然$ {pageContext.request.remoteUser}打印新值 - jsp:setProperty name =“pathEditor”property =“username”value =“$ {pageContext.request.remoteUser}”/&gt;将旧值传递给我的bean setter方法。这个我无法理解。请帮忙。

1 个答案:

答案 0 :(得分:2)

两种浏览器有何不同? 相同浏览器制作的不同标签/窗口/实例将共享相同会话。使用不同品牌的浏览器更好地测试,例如一个Firefox和其他IE,Safari,Chrome或Opera。

如果您实际上正在使用不同品牌的浏览器进行测试,而您仍然遇到同样的问题,那么代码很可能不是线程安全的。即您在某些类中将变量声明为static变量,或者将其声明为Servlet类的实例变量。您知道,static变量在所有线程之间共享,与Servlet类的实例变量一样。

编辑#1:作为您自己编辑的回复:代码根本不是线程安全的。毫无疑问,某个级别的static或servlet实例变量(in)直接保存信息。很难从这个距离指出确切的代码行。只需运行调试器并调试代码,或在此处发布SSCCE,或让本地专家审核您的代码。

编辑#2: jsp / servlets中的线程安全与是否使用synchronized / volatile / etc无关。这只是编写正确的代码。 static变量不是线程安全的。在servlet doXXX()方法中声明的所有内容都是线程安全的,但外部不是。那种事。请记住:一个HTTP请求帐户作为一个线程。在应用程序的生命周期中只有一个servlet实例。

示例:

public class MyBean { 
    private static String property1; // Certainly NOT threadsafe, there is only 1 of it during application's lifetime.
    private String property2; // Threadsafety depends on class which is holding the Bean instance.
}

public class MyServlet extends HttpServlet {
    private static Bean bean1 = new Bean(); // Certainly NOT threadsafe, there is only 1 of it during application's lifetime.
    private Bean bean2 = new Bean(); // This also NOT, because there's only 1 servlet in application's lifetime which is shared among all requests.

    protected void doSomething(request, response) {
        Bean bean3 = new Bean(); // Declared threadlocal, thus certainly threadsafe.
        request.setAttribute("bean", bean3); // 1 request = 1 thread, thus threadsafe.
        request.getSession().setAttribute("bean", bean3); // Session is shared among requests/threads from same client, thus NOT threadsafe.
        getServletContext().setAttribute("bean", bean3); // Context is shared among all sessions from different clients, thus certainly NOT threadsafe.
    }
}

JSP中的页面范围当然是线程安全的。你的问题在于更高层次。我在某处static变量上下注。