我需要在 EL 表达式(使用 JSF)中使用带参数的函数,如下所示:
<h:outputText value="#{object.test(10)}" ></h:outputText>
但它不起作用。
我在网上读到,用 JSF 不可能做到这一点。我在 JSF 中使用 facelet。
有人知道该怎么做吗?
谢谢。
您可以在自己的 taglib 中将该方法作为自定义 facelet 函数提供。该方法必须是静态的,因此如果您尝试调用特定 bean 上的方法,则必须将 bean 和参数传递给您的静态 facelet 函数。在你的情况下,它会像
<h:outputText value="#{my:doStuff(object,10)}" ></h:outputText>
你的 facelet 功能将是
public static String doStuff( MyType o, int param )
{
return o.test( param );
}
然后,使用facelets文档中的信息,您将在 taglib.xml 文件中定义您的函数。
这不是最漂亮的解决方案,特别是如果您打算经常这样做,但我相信 EL 的下一个版本(在 java EE 6 中)将允许在某些情况下使用参数。
编辑:有关下一版本 el 中的参数化方法调用的一些信息可以在Ryan Lubke 的博客上找到
我找到了一个可悲的解决方案,但它正在工作。我重载这样的地图:
new AbstractMap<Integer, String>()
{
@Override
public Set<Entry<Integer, String>> entrySet()
{
return null;
}
@Override
public String get(final Object arg0)
{
Integer keywordDb = (Integer)arg0;
GregorianCalendar cal = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
HashMap<String, String> params = new HashMap<String, String>();
params.put("keywordDb", keywordDb.toString());
params.put("month", new Integer(cal.get(Calendar.MONTH) + 1).toString());
params.put("year", new Integer(cal.get(Calendar.YEAR)).toString());
DataAnalyzeManager manager = new DataAnalyzeManager();
manager.setEm(modelPosition.getEm());
DataAnalyze data = manager.findDataByParams(params, modelPosition.getSite(), false, DataAnalyzeManager.VISITBYMONTHBYKEYWORD);
if (data != null)
return data.getDataInt().toString();
return "0";
}
};
因此,我可以在我的 JSF 中做到这一点:
#{homePositionController.visitByMonth[keyword.keyword.keywordDb]}
我的功能被执行。
您可能必须<%@ page isELIgnored ="false" %>
在页面顶部。在这里阅读更多。 默认是忽略 el 表达式。您在 JSF 中使用了哪个版本的 JSP 规范?如果您在 JSP < 2.1 中使用 JSF 2,您将会遇到问题。
另外,你用的是什么版本的el?您不能使用旧版本传递方法参数。
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.1.2-b05</version>
</dependency>
有几种方法可以做到这一点,您可以使用 JBoss EL 表达式实现,它们支持使用参数检查 Seam 的方法调用,或者使用与@digitaljoel 建议的类似方法。这是我为此目的创建的,您可以调用静态和静态方法,这不是一个很好的解决方案,但它可以完成工作。
<c:if test="#{t:call(null, '@Util.SecurityUtility', 'isPanelWorkbookEnabledForUser','')}">
Hello Panel
</c:if>
@Util 只是 com.mycomp.util 的别名,其中
示例 2
<c:if test="#{item != null and t:call(item, 'java.lang.String', 'indexOf', t:params(t:param('flash-alert',''))) == 0}">
#{t:call(session, 'org.apache.catalina.session.StandardSessionFacade', 'removeAttribute', t:params(t:param(item,'')))}
</c:if>
语法 java.lang.Object call(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object[]) 其中 Object 是我们要调用方法的对象,String 是方法名, Object[] 是要传递的参数。
t:call, t:params, t:param 是 project-taglib.xml 中定义的函数
<function>
<function-name>call</function-name>
<function-class>util.Functions</function-class>
<function-signature>java.lang.Object call(java.lang.Object, java.lang.String, java.lang.String, java.lang.Object[])</function-signature>
</function>
<function>
<function-name>param</function-name>
<function-class>.util.Functions</function-class>
<function-signature>java.lang.String param(java.lang.Object, java.lang.String)</function-signature>
</function>
<function>
<function-name>params</function-name>
<function-class>util.Functions</function-class>
<function-signature>java.lang.Object[] params(java.lang.String)</function-signature>
</function>
这是实现
package mycompany.web.util;
导入 java.beans.XMLDecoder;导入 java.beans.XMLEncoder;导入 java.io.BufferedOutputStream;导入 java.io.ByteArrayInputStream;导入 java.io.ByteArrayOutputStream;导入 java.io.ObjectOutputStream;导入 java.io.StringWriter;导入 java.lang.reflect.Array;导入 java.lang.reflect.InvocationTargetException;导入java.lang.reflect.Method;导入 java.util.Date;导入 java.util.HashMap;导入 java.util.List;
导入 javax.el.MethodNotFoundException;
公共类函数{
private static HashMap<String, String> alliasMap;
static{
alliasMap=new HashMap<String, String>();
alliasMap.put("@DateUtil", "com.americanbanksystems.compliance.util.DateUtil");
//Match anything following the dot(.)
alliasMap.put("@Util.*", "com.americanbanksystems.compliance.util");
alliasMap.put("@Application.*", "com.americanbanksystems.compliance.application");
}
public static String param(Object obj, String cls) {
//make sure that passed in object is not null
if(obj==null){
obj="";
}
ByteArrayOutputStream baut=new ByteArrayOutputStream();
XMLEncoder encoder=new XMLEncoder( baut );
//Bug in the JDK
//http://bugs.sun.com/bugdatabase/view_bug.do;jsessionid=c993c9a3160fd7de44075a2a1fa?bug_id=6525396
if(obj instanceof java.sql.Timestamp){
Date o = new Date(((java.sql.Timestamp)obj).getTime());
obj=o;
}
//Checking if this is possible
if(String.class.isAssignableFrom(obj.getClass())){
//removed trailing +" " because it was causing indexOf return invalid value
//Unknown side effects
obj=FacesUtil.get(obj.toString());
}
encoder.writeObject( obj );
encoder.close();
return new String(baut.toByteArray());
}
private static Object decode(String str){
ByteArrayInputStream bais=new ByteArrayInputStream(str.getBytes());
XMLDecoder decoder=new XMLDecoder(bais);
return decoder.readObject();
}
public static Object[] params(String str){
// (?<=</java>)\s*(?=<?)
String[] obj=str.split("(?<=</java>)\\s*(?=<?)");
Object[] results=new Object[obj.length];
for(int i=0;i<obj.length;i++){
results[i]=decode(obj[i]);
}
return results;
}
@SuppressWarnings("unchecked")
public static Object call(Object owningObject, String qualifiedClassname, String methodName, java.lang.Object... methodArguments) {
if (null == methodName || methodName.equals("")) {
throw new IllegalArgumentException("Method name can't be null or empty");
}
if (null == methodArguments) {
methodArguments = new Object[0];
}
//Check for aliases
if(qualifiedClassname.indexOf("@")>-1){
String subpackage=qualifiedClassname;
String originalClass=qualifiedClassname;
//Split at the dot
boolean isPackageAllias=false;
String[] sp=subpackage.split("\\.");
if(sp.length>1){
subpackage=sp[0]+".*";
isPackageAllias=true;
}
if(alliasMap.containsKey(subpackage)){
String value = alliasMap.get(subpackage);
if(isPackageAllias){
qualifiedClassname=subpackage.replace(sp[0], value);
qualifiedClassname=qualifiedClassname.replace(".*", originalClass.replace(sp[0],""));
}else{
qualifiedClassname=value;
}
}else{
throw new IllegalArgumentException("Allias name '"+qualifiedClassname+"' not found");
}
}
Class clazz;
try {
clazz = Class.forName(qualifiedClassname);
//Find method by methodName,Argument Types
Class[] argumentTypes=new Class[methodArguments.length];
for(int i=0;i<methodArguments.length;i++){
argumentTypes[i]=methodArguments[i].getClass();
//Check if the passed in method argument is a string and if its represented as unicode char
//if it is then convert it into a char and reassign to the original parameter
//example 1: \u0022 == "
//example 2: \u0027 == '
// Reason for this functionality is that we can't pass " and ' from within t:call method
if (argumentTypes[i] == String.class && methodArguments[i].toString().indexOf("\\u") > -1) {
String arg = methodArguments[i].toString();
arg = arg.substring(2, arg.length());
try {
int outchar = Integer.parseInt(arg, 16);
if (Character.isDefined(outchar)) {
methodArguments[i] = String.valueOf((char) outchar);
}
} catch (NumberFormatException nfe) {
// Suppress error and continue assuming this is a regular string
}
}
}
Method methodToInvoke = null;
try{
methodToInvoke = clazz.getMethod(methodName, argumentTypes);
}catch(NoSuchMethodException nsm){//Find by method name/ argument count
for (Method method : clazz.getMethods()) {
if (method.getName().equals(methodName) && method.getParameterTypes().length == methodArguments.length) {
if (null == owningObject) {
owningObject = clazz.newInstance();
}
methodToInvoke=method;
break;
}
}
}
if(methodToInvoke!=null){
return methodToInvoke.invoke(owningObject, methodArguments);
}else{
throw new InstantiationException("method not found :" + methodName);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return null;
}
public static void main(String[] arg) {
// StringBuffer buff=new StringBuffer();
// buff.append("Gregs init");
// Functions.call(java.lang.Class<T>, T, java.lang.String, java.lang.String, java.lang.Object...)
/*
* Functions.call(StringBuffer.class, buff, "java.lang.StringBuffer","append"," Init ");
* Functions.call(StringBuffer.class, buff, "java.lang.StringBuffer","append"," greg ");
* System.out.println("output="+ buff);
*/
//#{t:call(null, ".util.DateUtil", "normalizeDate", t:parametize(editRiskActionPlan.riskActionPlan.completionDate,",","java.lang.Object"))}
// c(call(null, "util.DateUtil", "normalizeDate", new Date()));
// #{t:parametize(editRiskActionPlan.riskActionPlan.completionDate,",","java.lang.Object")}
//parametize((new Date()).toString(),",","java.lang.Object");
Date a=new Date();
Date b=new Date();
String rawString=param((Date)b, Date.class.toString() );
//System.out.println(rawString);
//Replaced=#{t:call("Gregs ' car", 'java.lang.String', 'replace', t:params( parameter ))}
String paramA=param("\\u0027","");
String paramB=param("\\u0022","");
String params=paramA+paramB;
String in="I need to ' have a replaced single quote with double";
String out=(String)call(in, "java.lang.String", "replace", params(params));
System.out.println(out);
/*
Object[] obj=params(rawString);
for(Object o:obj){
System.out.println(o);
}
//c(call(null, "@DateUtil", "normalizeDate", obj));
*/
}
}
我希望这会有所帮助,顺便说一句,这是从我的项目中复制/粘贴的,所以不确定我是否遗漏了什么。