java 在 JSTL 循环中调用带参数的方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6760575/
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-30 17:09:29  来源:igfitidea点击:

Calling a method with parameter inside JSTL loop

javajspjstl

提问by mindas

I have a JSP which needs to print some text which is produced by taking loop iterator and feeding it to another object (Spring bean), something like:

我有一个 JSP,它需要打印一些文本,这些文本是通过获取循环迭代器并将其提供给另一个对象(Spring bean)而产生的,例如:

<c:forEach var="myVar" items="${myVars}">
   <c:out value="anotherObject.getFoo(myVar)"/>
</c:forEach>

Obviously the code above isn't valid as JSTL .operator only allows parameter-less invocations. I can see following solutions to the problem:

显然上面的代码是无效的,因为 JSTL.操作符只允许无参数调用。我可以看到以下问题的解决方案:

1) Scriptlets

1) 小脚本

<c:forEach var="myVar" items="${myVars}">
  <%
    SomeType myVar = (SomeType) pageContext.getAttribute("myVar");
    SomeOtherType anotherObject = (SomeOtherType) pageContext.getAttribute("anotherObject");
    YetAnotherType result = anotherObject.getFoo(myVar);
    pageContext.setAttribute("result", result);
  %>
  <c:out value="${result}"/>
</c:forEach>

The obvious con here is JSP code pollution and general ugliness.

这里明显的缺点是 JSP 代码污染和普遍的丑陋。

2) Writing a tag which does whatever is done inside scriptlets. Typical example of over-engineering, yuck!

2) 编写一个标签,它可以在 scriptlet 中执行任何操作。过度设计的典型例子,糟糕!

3) Decompose a collection of myVarsand replace each myVarwith a dynamic proxy, InvocationHandlerof which would add extra parameter-less method to make all getFoo()calls through anotherObject. All of that would be done in the controller so JSP would stay clean and myVarstays the same. But at what price?

3)分解的集合myVars,并替换每个myVar动态代理InvocationHandler这会增加额外的参数少的方法来使所有getFoo()通过电话anotherObject。所有这些都将在控制器中完成,因此 JSP 将保持干净并myVar保持不变。但价格是多少?

I can not add .getFoo()method to the myVarbecause it doesn't fit there and would break the separation of concerns.

我无法向 中添加.getFoo()方法,myVar因为它不适合那里并且会破坏关注点的分离。

It looks like passing parameters will be possible in JSP/EL 2.2, but I'm using Tomcat 6.0.29 which only bundles EL 2.1 API.

看起来在 JSP/EL 2.2 中可以传递参数,但我使用的 Tomcat 6.0.29 只捆绑了 EL 2.1 API。

Question:can anyone suggest the cleanest approach for this situation?

问题:任何人都可以针对这种情况提出最干净的方法吗?

采纳答案by mindas

Here's how I've done it at the end.

这是我最后的做法。

Instead of passing a collection of SomeTypeinstances, I am passing a map. Map keys are the same SomeTypes and values are instances of controller-specific inner class, let's call it SomeTypeSupplement.

SomeType我没有传递实例集合,而是传递了一个地图。映射键是相同SomeType的,值是特定于控制器的内部类的实例,我们称之为SomeTypeSupplement

SomeTypeSupplementadds necessary no-arg getters and wires everything together. JSP now iterates over map entries and is able to retrieve the data via JSTL.

SomeTypeSupplement添加必要的无参数吸气剂并将所有东西连接在一起。JSP 现在遍历映射条目并能够通过 JSTL 检索数据。

This way I avoid Proxymagic, unnecessary TLDs, keep JSPs tidy and reasonably type-safe.

这样我就避免了Proxy魔法、不必要的 TLD,保持 JSP 整洁和合理的类型安全。

回答by Rop

A simple Java-only "trick-fix" that works in the older JSTL version, too, and requires no extra taglibs/config/dependencies/frameworks, etc. is to "wrap" the function you want to call from JSTL in a class that extends from a Mapclass, and override its get()method.

一个简单的仅限 Java 的“技巧修复”也适用于较旧的 JSTL 版本,并且不需要额外的 taglibs/config/dependencies/frameworks 等,就是将要从 JSTL 调用的函数“包装”在一个类中从Map类扩展,并覆盖其get()方法。

As a minimal example, if you e.g. want to call the Math.sin()function from JSTL, you would define a class:

作为一个最小的例子,如果你想Math.sin()从 JSTL调用函数,你可以定义一个类:

public class Sine extends HashMap<Double, Double> {
    private static final long serialVersionUID = 1L; // Avoids compiler-warning

    @Override
    public Double get(Object arg) {
        Double x = (Double) arg;
        return Math.sin(x);
    }
}

Then in your Action execute() method, you do:

然后在您的 Action execute() 方法中,您执行以下操作:

...
request.setAttribute("sine", new Sine());
...

Then in jsp you can say:

然后在jsp中你可以说:

  ${sine[0.75]}

to calculate the value Math.sin(0.75)

计算值 Math.sin(0.75)

JSTL will treat the variable sine as a Map, but you can compute and return anything you like from the get() method.

JSTL 会将变量 sine 视为 a Map,但您可以从 get() 方法计算并返回您喜欢的任何内容。

I guess it gets a bit more involved if you have more than one argument to your function, but there should be workarounds for that, too :)

我想如果你的函数有多个参数,它会变得更复杂,但也应该有解决方法:)

回答by atrain

Why not just compose your object list in your backend Java code and then just use JSP to display it?

为什么不在后端 Java 代码中编写对象列表,然后仅使用 JSP 来显示它呢?

回答by pap

If you can't abide with scriptlets (your alternative 1), I would create a custom tag for it (your alternative 2) or a custom EL function. I don't agree that it's "over-engineering", it's using the available tools for their intended purpose.

如果您不能遵守 scriptlet(您的替代方案 1),我会为其创建一个自定义标记(您的替代方案 2)或自定义 EL 函数。我不同意这是“过度设计”,而是将可用工具用于其预期目的。

Your alternative 3, though, I don't like. If anything, THAT'S over-engineering plus it will make your system unnecessarily complex and harder for other people to follow. Adhere to the intentions of the specifications and standards you are working within. Don't make things harder or more complex for the sake of it.

不过,你的选择 3,我不喜欢。如果有的话,那就是过度设计,而且它会使您的系统变得不必要地复杂,并且其他人更难遵循。遵守您在其中工作的规范和标准的意图。不要为了它而使事情变得更难或更复杂。

回答by hyphan

Wanted to add a comment to the last (by time) answer of Rop, but missing "reputation", so here I am with an answer.

想在 Rop 的最后一个(按时间)回答中添加评论,但缺少“声誉”,所以我在这里给出了一个答案。

I shortly had the same idea with such a map, but tried to make it more generally usable, having a "DynamicMap", DynamicMapCalculator interface and letting you wrap any method call into such a map (without the need to make a new map implementation every time, just using anonymous class instantiation).

我很快对这样的地图有了同样的想法,但试图让它更普遍可用,有一个“DynamicMap”,DynamicMapCalculator 接口,让你把任何方法调用包装到这样的地图中(不需要每次都制作一个新的地图实现)时间,只需使用匿名类实例化)。

This would be the topic, if you are interested: A qu. of style: dynamic map JSTL hack to work around missing parameter function calls

如果您有兴趣,这将是主题: A qu。风格:动态映射 JSTL hack 以解决缺少的参数函数调用

And I would be interested in opinions there: is this something you may do without a bad conscience?

我对那里的意见很感兴趣:这是你可以在没有良心的情况下做的事情吗?

回答by John Kane

Another option is to use Velocity. It is much nicer than jstl.

另一种选择是使用Velocity。它比jstl好得多。