如何通过c:set将参数传递给jsp:include?JSP 中变量的作用域是什么?

2022-09-01 15:39:28

我欢迎这个.jsp

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

在脑海中.jsp:

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

但变量为空,输出仅为空

Site Name -

我读过很多文章,但我无法弄清楚问题出在哪里。如果我在相同的欢迎.jsp其他地方回响,那么它输出很好。${pgTitle}

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


答案 1

这是因为变量是在页面范围内设置的。在这里检查(抱歉我无法获得这方面的官方文档)。pgTitle

如果要使此功能正常工作,则必须至少在请求范围内设置变量。要在请求范围内设置变量,请使用 上的属性:scope<c:set>

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

根据您的注释,在Web开发中,变量的范围很重要,因为它定义了可以使用变量的位置(类似于在类中声明为字段的变量和在方法中局部声明的变量)。JSP 中有四个称为上下文的作用域:

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

更多信息:

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

如果有 Servlet 或其他控制器来处理要在请求中设置的属性(例如 从 Spring MVC 或 JSF 托管 Bean),然后在那里设置属性,而不是直接在页面中设置。@Controller

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

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

答案 2

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

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

某页.jsp

<%@ taglib prefix="layout" tagdir="/WEB-INF/tags" %>

<html>
   <layout:head title="myRadTitle" />
   <body></body>
<html/>