jsp:useBean范围属性如何工作?

时间:2017-01-16 15:32:53

标签: jsp servlets jstl jsp-tags usebean

我试图理解scope JSP动作标记中的jsp:useBean属性是如何工作的。在我的理解中,scope用于指示bean的位置(请求,会话,应用程序等),但经过一些测试后,我遇到了一个有趣的情况,并非如此,请考虑以下JSP代码(我在这里使用scriplets只是为了简单起见):

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"  import="package2JSP.User" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Title</title>
</head>

<body>
    <%
        User user1 = new User("id1","name1");
        User user2 = new User("id2","name2");
        request.setAttribute("user", user1);
        session.setAttribute("user", user2);
    %>
    <%-- Here I expect to create user bean that represents user2 from session scope--%>
    <jsp:useBean id="user" class="package2JSP.User" scope="session"/>

    <%-- Here I expect user name to be name2 but it is name1 instead--%>
    <jsp:getProperty property="name" name="user"/>
</body>
</html>

所以基本上我在这里创建了2个用户对象并将它们设置为&#34; user&#34;请求和会话范围中的属性,当我尝试检索&#34; user&#34;来自&#34; session&#34;使用jsp:useBean的范围好像&#34;用户&#34;来自&#34;请求&#34;范围已被检索。

你能解释一下为什么会这样吗?使jsp:useBean以这种方式工作的开发理由是什么,而不是通常从指定范围中选择属性,它有什么优点吗?

现在我知道我可以使用JSTL / EL来检索所需的值,即<c:out value="${sessionScope.user.name}" />,但我只是想知道jsp:useBean的工作原理。

1 个答案:

答案 0 :(得分:0)

在这种情况下涉及2个标签:

  • JS​​P:useBean的
  • JS​​P:的getProperty

jsp:useBean

根据Specification - CHAPTER JSP.5 - JSP.5.1 <jsp:useBean>

  

jsp:useBean操作关联Java编程的实例   语言对象在给定范围内定义可用于   给定id具有相同id的新声明的脚本变量。   在无脚本页面中或在脚本中使用操作时   无脚本上下文(如在所指示的动作的主体中),那里   没有创建Java脚本变量,而是EL变量   创建

编译的java代码是:

      package2JSP.User user = null;
      synchronized (session) {
        user = (package2JSP.User) _jspx_page_context.getAttribute("user", PageContext.SESSION_SCOPE);
        if (user == null){
          try {
            user = (package2JSP.User) java.beans.Beans.instantiate(this.getClass().getClassLoader(), "package2JSP.User");
          } catch (ClassNotFoundException exc) {
            throw new InstantiationException(exc.getMessage());
          } catch (Exception exc) {
            throw new ServletException("Cannot create bean of class " + "package2JSP.User", exc);
          }
          _jspx_page_context.setAttribute("user", user, PageContext.SESSION_SCOPE);
        }
      }

如果要访问此用户对象,可以使用scriptlet(表达式)<%=user.getName()%>

jsp:getProperty

根据Specification - CHAPTER JSP.5 - JSP.5.3 <jsp:getProperty>说:

  

中的name属性的值   jsp:setProperty和jsp:getProperty将引用一个对象   是通过findAttribute从pageContext对象获得的   方法

JSP编译器从jsp:getProperty标记调用findAttribute()

out.write(org.apache.jasper.runtime.JspRuntimeLibrary.toString(
  (((package2JSP.User)_jspx_page_context.findAttribute("user")).getName())));
  

findAttribute()
  在页面,请求,会话中搜索命名属性(如果有效),   和应用程序范围,并返回相关的值或   空。

基本上:返回第一场比赛。

使用useBeangetProperty被视为不良做法 使用JSTL / EL是处理属性的更好方法。