java 使用 pagecontext.include 将页面范围属性传递给 JSP 以在 JSTL 中使用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2806097/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 22:56:30  来源:igfitidea点击:

Pass page scope attributes to a JSP using pagecontext.include for use in JSTL?

javajsplegacy

提问by Will Hartung

We're using this JSP template solution almost verbatim at work:

我们在工作中几乎一字不差地使用这个 JSP 模板解决方案:

http://java.sun.com/developer/technicalArticles/javaserverpages/jsp_templates/

http://java.sun.com/developer/technicalArticles/javaserverpages/jsp_templates/

When it gets JSP pages to be included, it uses pageContext.include, which leaves us with one problem, and that is that we have a lot of scriplet code that gets initialized in the JSP itself (tag soup). My thought was to modify the template tag with an additional attribute that is a package path reference to a class with an init or execute method. That execute would get called first, and would add page context attributes before including the JSP. We would then use JSTL to access those attributes. However, I was told this wouldn't work because of how pageContext.include works, and the inability to pass through attributes scoped to the page. Is that true, and are there workarounds? I'm so-so on knowing all my scoping rules.

当它获取要包含的 JSP 页面时,它使用 pageContext.include,这给我们留下了一个问题,那就是我们有很多在 JSP 本身中初始化的脚本代码(标记汤)。我的想法是使用附加属性修改模板标记,该属性是对具有 init 或 execute 方法的类的包路径引用。该执行将首先被调用,并在包含 JSP 之前添加页面上下文属性。然后我们将使用 JSTL 来访问这些属性。但是,有人告诉我这行不通,因为 pageContext.include 是如何工作的,并且无法传递作用域到页面的属性。是真的吗,是否有解决方法?我马马虎虎地知道我所有的范围规则。

回答by Will Hartung

Correct, the problem is that the PageContext is literally that, a Page Context. When you run the include, that resource (assuming it's a JSP) get's its own PageContext, and that is lost upon return.

正确,问题在于 PageContext 从字面上看就是一个页​​面上下文。当您运行包含时,该资源(假设它是一个 JSP)获得它自己的 PageContext,并且在返回时丢失。

JSP has 4 scopes: Application, Session, Request, and Page. Each of those has its own lifecycle, which should be self explanatory.

JSP 有 4 个作用域:Application、Session、Request 和 Page。每个都有自己的生命周期,这应该是不言自明的。

The use of the Request scope here is the right idea.

在这里使用 Request 范围是正确的想法。

If you look at the template code that you linked to, that's exactly what the Insert tag is doing. In this case, it's putting Hashtables on to a Stack that is maintained in the Request.

如果您查看链接到的模板代码,这正是 Insert 标记正在执行的操作。在这种情况下,它将哈希表放在请求中维护的堆栈上。

Then it uses the "put" and "get" tags to put/get items on and off that current "stack".

然后它使用“放置”和“获取”标签在当前“堆栈”上放置/获取项目。

A simple thing that you can do is before the PageContext.include, invoke your "execute" method as appropriate. Have that method simply return a Map of name/value pairs. Then you can take that Map and populate the existing (or soon to be existing) Hashtable on the Stack.

您可以做的一件简单的事情是在 PageContext.include 之前,根据需要调用您的“执行”方法。让该方法简单地返回名称/值对的 Map。然后,您可以使用该 Map 并在堆栈上填充现有(或即将存在)的 Hashtable。

Basically your Init class is logic that's similar to calling a lot of the "put" tags.

基本上,您的 Init 类是类似于调用许多“放置”标签的逻辑。

Other than that your template tags work the same.

除此之外,您的模板标签的工作方式相同。

Or you can merge the results straight in to the Request, for use by the JSTL. Or you can keep the "stack" nature, pushing your own "context" in to the Request.

或者您可以将结果直接合并到请求中,供 JSTL 使用。或者您可以保持“堆栈”性质,将您自己的“上下文”推送到请求中。

回答by Tobias M

You can pass an attribute scoped to the request:

您可以传递范围为请求的属性:

<c:set var="myAttribute" value="myValue" scope="request" />

or

或者

<% request.setAttribute("myAttribute", "myValue"); %>

And then on your included page:

然后在您包含的页面上:

<c:out value="${myAttribute}" />