首先看下怎么在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;
}
}
}
文章评论