首先看下怎么在JSP里使用:
- JSP头部增加:
<% request.setAttribute("call", new Call()); %>
- 需要调用的静态方法,如Utils.java
package com.terrynow.test.utils public class Utils { public static String testMethod(String args, String arg2) { //省略 return "xxxx" } }
- JSP的代码里这样调用:
<%-- 带参数arg1 arg2这种这样使用--%> ${call["com.terrynow.test.utils.Utils.testMethod"]["arg1"][arg2]} <%-- 不带参数这样使用--%> ${call["com.terrynow.test.utils.Utils.testMethod"]}
看下需要准备的文件:
新建Call.java
/* * Copyright (c) 2015. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.terrynow.test.util; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * This class lets you call static methods from EL * * Step 1) Create an instance of this class and bind it to the "call" variable * in your EL. For example, in a JSP do the following: * request.setAttribute("call", new Call()); * * Step 2) Call any static method as follows: * * ${call["some.package.SomeClass.methodName"]["arg1"][arg2]} * * The first argument is the fully qualified class and method name. The * remaining arguments are arguments to the method that you are calling. * * Note: method overloading not supported * * Note: method must be static * * @author Vineet Manohar */ public class Call extends HashMap<String, Object> { private static final long serialVersionUID = 1L; @Override public Object get(Object key) { String fullyQualifiedMethodName = (String) key; // format of key is package.Class.method Pattern pattern = Pattern.compile("(.+)\\.([^\\.]+)"); Matcher m = pattern.matcher(fullyQualifiedMethodName); if (m.matches()) { String fqClassName = m.group(1); String methodName = m.group(2); Class<Object> clazz; try { clazz = (Class<Object>) Class.forName(fqClassName); } catch (ClassNotFoundException e) { throw new IllegalArgumentException("Invalid method name: " + key, e); } Method[] methods = clazz.getMethods(); for (final Method method : methods) { if ((method.getModifiers() & Modifier.STATIC) == 0) { continue; } if (method.getName().equals(methodName)) { // return the first method found int numParameters = method.getParameterTypes().length; if (numParameters == 0) { return invokeMethod(method); } return new ELMethod(numParameters) { @Override public Object result(Object[] args) { return invokeMethod(method, args); } }; } } } throw new IllegalArgumentException("Invalid method name: " + key + ". Must be a fully qualified class and method name"); } private Object invokeMethod(final Method method, Object... args) { try { return method.invoke(null, args); } catch (IllegalArgumentException e) { throw new RuntimeException("Exception while executing method", e); } catch (IllegalAccessException e) { throw new RuntimeException("Exception while executing method", e); } catch (InvocationTargetException e) { throw new RuntimeException("Exception while executing method", e); } } }
新建ELMethod.java
/* * Copyright (c) 2015. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package com.terrynow.test.util; import java.util.ArrayList; import java.util.HashMap; import java.util.List; /** * Extend this class to implement a server side method that takes arguments that * you would like to call via expression language. * * @author Vineet Manohar */ public abstract class ELMethod extends HashMap<Object, Object> { private static final long serialVersionUID = 1L; private final int numArgs; /** * @param numArgs * number of arguments this method takes */ protected ELMethod(int numArgs) { this.numArgs = numArgs; } @Override public Object get(Object key) { // if exactly one argument, call the result() method if (numArgs == 1) { return result(new Object[] {key}); } // if more tha one argument return new Arg(this, key); } public int getNumArgs() { return numArgs; } /** * 1) Implement this method in the child class. This method becomes * accesible via expression language. * * 2) Call this method using map syntax, by treating the instance of the * child class as a map of map of maps... * * For example, you could extends this class and create a class called * FormatDate. In that class, the result method would expect 2 arguments, * format string and date object. * * ${FormatDate["MMM dd"][user.creationDate]}, where dateFormat is an * instance of the child class. * * @param args * @return */ public abstract Object result(Object[] args); public static class Arg extends HashMap<Object, Object> { private static final long serialVersionUID = 1L; private List<Object> args = new ArrayList<Object>(); private ELMethod parent; public Arg(ELMethod eLMethod, Object key) { this.parent = eLMethod; this.args.add(key); } @Override public Object get(Object key) { this.args.add(key); // if all the arguments have been received, invoke the result method if (args.size() == parent.getNumArgs()) { Object retVal = parent.result(args.toArray()); return retVal; } return this; } } }
文章评论