【问题标题】:How to pass parameter to jsp:include via c:set? What are the scopes of the variables in JSP?如何通过 c:set 将参数传递给 jsp:include? JSP中变量​​的作用域是什么?
【发布时间】:2013-05-13 05:03:04
【问题描述】:

我在welcome.jsp 上有这个

<c:set var="pgTitle" value="Welcome"/>
<jsp:include page="/jsp/inc/head.jsp" />

这在 head.jsp 中:

<title>Site Name - ${pgTitle}</title>

但是变量是空白的,输出只是

Site Name -

我已经阅读了很多文章,但我无法弄清楚问题所在。如果我在同一个welcome.jsp 中的其他地方回显${pgTitle},则输出正常。

我在两个页面上都包含了核心标签库。

【问题讨论】:

    标签: java jsp jstl el


    【解决方案1】:

    您可以通过使用&lt;c:import&gt;&lt;c:param&gt; 的组合来完成此操作。

    somePage.jsp

    <c:import url="header.jsp" >
        <c:param name="pageTitle" value="Whatever the title of the page is"/>
    </c:import>
    

    header.jsp

    <html>
        <head>
            <title>
                <c:out value="${param.pageTitle}" default="Default is optional" /> 
            </title>
        </head>
    </html>
    

    【讨论】:

      【解决方案2】:

      您必须将变量设置为(至少)request 作用域。您可以按以下方式执行 id:

      <c:set var="pgTitle" value="Welcome" scope="request"/>
      <jsp:include page="/jsp/inc/head.jsp" />
      

      然后,在head.jsp 中,您可以像这样输出变量:

      <c:out value="${requestScope.pgTitle}" />
      

      【讨论】:

      • 不需要添加requestScope,因为${}已经在所有范围属性中搜索了变量。
      【解决方案3】:

      一种方法是通过查询参数将变量传递给包含:

      <jsp:include page="/WEB-INF/views/partial.jsp?foo=${bar}" />
      
      <jsp:include page="/WEB-INF/views/partial.jsp">
          <jsp:param name="foo" value="${bar}" />
          <jsp:param name="foo2" value="${bar2}" />
      </jsp:include>
      

      然后您可以使用 ${param.foo} 访问这些参数

      另一个是使用自定义标签:

      /WEB-INF/tags/head.tag

      <%@ attribute name="title" %>
      
      <head>
          <title>${title}</title>
      </head>
      

      somePage.jsp

      <%@ taglib prefix="layout" tagdir="/WEB-INF/tags" %>
      
      <html>
         <layout:head title="myRadTitle" />
         <body></body>
      <html/>
      

      【讨论】:

        【解决方案4】:

        这是因为pgTitle 变量是在页面范围内设置的。检查它here(对不起,我无法获得官方文档)。

        如果你想让这个工作,你必须至少在请求范围内设置变量。要在请求范围内设置变量,请使用 &lt;c:set&gt; 上的 scope 属性:

        <c:set var="pgTitle" value="Welcome" scope="request" />
        

        根据您的评论,在 Web 开发中,变量的范围很重要,因为它定义了可以在何处使用变量(类似于在类中声明为字段的变量和在方法中本地声明的变量)。 JSP 中有四个范围称为上下文:

        • 页面范围(由PageContext处理)。只有在当前页面中设置为属性时才能访问变量。这意味着,只有当前页面可以访问这些属性,包含的页面是不同的页面,所以它们不能访问这些属性。
        • 请求范围(由ServletRequest 处理)。只有在当前请求中设置为属性时才能访问这些变量。这意味着,在同一请求中处理的每个页面都可以访问这些属性。 重要提示:重定向意味着新的请求/响应过程。这意味着,如果您在请求上设置属性并执行重定向,这些属性将不会被设置为新请求的属性。
        • 会话范围(由HttpSession 处理)。只有在当前用户会话中设置为属性时才能访问这些变量。这意味着,在同一用户会话中使用的每个页面都可以使用这些属性,直到它们被删除或会话过期。
        • 应用范围(由ServletContext处理)。只有在当前上下文中设置为属性时才能访问变量。这意味着,每个会话属性上的每个页面都可以访问这些变量,直到将它们从 SessionContext 中删除或取消部署 Web 应用程序。

        更多信息:

        这是完成我想做的事情的正确方法吗?

        如果有一个 Servlet 或另一个控制器来处理要在请求中设置的属性(例如,来自 Spring MVC 或 JSF 托管 bean 的 @Controller),则在此处设置属性,而不是直接在您的页面中。

        就个人而言,在 Web 应用程序中使用时,需要一些时间来积累经验并定义变量的最佳范围。基本示例:

        • 以逗号分隔 String 以用于演示目的只会影响当前视图,因此可以在页面范围内进行设置。
        • 错误和成功消息最适合请求范围。如果用户更新页面,除非重新处理数据,否则他/她可能不会看到相同的消息。
        • 可以在会话范围内设置用户信息,如姓名、昵称和首选项。
        • 如果您必须显示国家/地区列表(应该不会在几天内更改),您可以将此列表存储在应用程序范围内。

        【讨论】:

        • 这确实有效。我可以要求对这里发生的事情进行更技术性的解释吗?为什么 jsp:include 不能访问父级中的变量集?最后一个问题:这是完成我想做的事情的正确方法吗?
        • 超级有帮助。感谢您抽出宝贵时间提供这些详细信息!
        • @LuiggiMendoza 在句子“JS 中有四个范围称为上下文:”中有一个小错字 - 应该有 JSP 而不是 JS。我想了一会儿,突然我们在谈论 JavaScript :-)
        猜你喜欢
        • 2018-01-03
        • 1970-01-01
        • 2011-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-19
        • 1970-01-01
        • 2013-10-09
        相关资源
        最近更新 更多