Jsf 对managedbean调用的taglib调用
我有这样一个托管bean(会话范围):Jsf 对managedbean调用的taglib调用,jsf,facelets,taglib,bcel,Jsf,Facelets,Taglib,Bcel,我有这样一个托管bean(会话范围): class Home {// as homeBean public void doSomething(ActionEvent ae, int a, int b){ System.out.println("result="+(a+b)); } } 我喜欢称之为 <a4j:commandLink actionListener="#{homeBean:doSomething(1,2)}"/> 动态调用它怎么样?使用bcel或URL
class Home {// as homeBean
public void doSomething(ActionEvent ae, int a, int b){
System.out.println("result="+(a+b));
}
}
我喜欢称之为
<a4j:commandLink actionListener="#{homeBean:doSomething(1,2)}"/>
动态调用它怎么样?使用bcel或URLClassLoader?此EL表达式语法仅用于静态方法,必须在标记库中定义,并在视图中定义命名空间:
#{namespacePrefix:fn(arg)}
此EL表达式调用对象实例上的:
#{someInstance.method(arg)}
第二种形式在或更高版本(JavaEE6)中提供。在此之前,一些第三方JSF库支持类似的表达式
只要托管bean在JSF上下文中执行,就可以从静态方法中查找它:
FacesContext context = FacesContext.getCurrentInstance();
SomeBean someBean = context.getApplication()
.evaluateExpressionGet(context,
"#{someBean}", SomeBean.class);
然而,这不是理想的方法。这段代码是针对JSF2编写的;以前的版本使用不同的动态查找调用
如果需要静态方法中的bean,请使用以下形式的表达式:
#{namespacePrefix:fn(someBean, 1, 2)}
哦,酷,我找到了一种工作方式:
public class ... implements TagLibrary {
@Override
public Method createFunction(String taglib, String functionName) {
if (!map.containsKey(functionName)) {
String classname = "de.Test" + functionName;
ClassGen _cg = new ClassGen(classname,
"java.lang.Object", "Test.java", ACC_PUBLIC | ACC_SUPER,
new String[] {});
ConstantPoolGen _cp = _cg.getConstantPool();
InstructionFactory _factory = new InstructionFactory(_cg, _cp);
Method meth = find(functionName, getNavigation());
Class<?>[] parameterTypes = meth.getParameterTypes();
int countParams = parameterTypes.length;
Type[] types = new Type[countParams];
String[] names = new String[countParams];
for (int i = 0; i < countParams; i++) {
types[i] = new ObjectType(parameterTypes[i].getName());
names[i] = "arg" + i;
}
InstructionList il = new InstructionList();
MethodGen staticMethod = new MethodGen(ACC_PUBLIC | ACC_STATIC,
Type.OBJECT, types, names, functionName, getClass()
.getName(), il, _cp);
InstructionHandle ih_1 = il.append(new PUSH(_cp, functionName));
il.append(new PUSH(_cp, countParams));
il.append(_factory.createNewArray(Type.OBJECT, (short) 1));
il.append(InstructionConstants.DUP);
for (int i = 0; i < countParams; i++) {
il.append(new PUSH(_cp, i));
il.append(_factory.createLoad(Type.OBJECT, i));
il.append(InstructionConstants.AASTORE);
if (i != countParams - 1)
il.append(InstructionConstants.DUP);
}
il.append(_factory.createInvoke(getClass().getName(),
"call", Type.OBJECT, new Type[] { Type.STRING,
new ArrayType(Type.OBJECT, 1) },
Constants.INVOKESTATIC));
InstructionHandle ih_25 = il.append(_factory
.createReturn(Type.OBJECT));
staticMethod.setMaxStack();
staticMethod.setMaxLocals();
_cg.addMethod(staticMethod.getMethod());
il.dispose();
try {
byte[] bytes = _cg.getJavaClass().getBytes();
InjectingClassLoader icl = new InjectingClassLoader();
Method find =
find(functionName, icl.load(classname, bytes));
map.put(functionName, find);
} catch (Exception e) {
e.printStackTrace();
}
}
Method method = map.get(functionName);
return method;
}
public static Object call(String functionname, Object[] arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Navigation myTargetBean = getNavigation();
Method proxyMethod = find(functionname,myTargetBean);
Object result = proxyMethod.invoke(myTargetBean, arguments);
return result;
}
公共类。。。实现标记库{
@凌驾
公共方法createFunction(字符串taglib、字符串functionName){
if(!map.containsKey(functionName)){
字符串classname=“de.Test”+函数名;
ClassGen _cg=新的ClassGen(classname,
“java.lang.Object”、“Test.java”、ACC|u PUBLIC | ACC|u SUPER、,
新字符串[]{});
ConstantPoolGen _cp=_cg.getConstantPool();
指令工厂_工厂=新指令工厂(_cg,_cp);
方法meth=find(functionName,getNavigation());
类[]parameterTypes=meth.getParameterTypes();
int countParams=参数类型.length;
类型[]类型=新类型[countParams];
字符串[]名称=新字符串[countParams];
for(int i=0;i
现在,我可以调用#{cms:doSomething(1,2)}您有JSF1.2的“简单”方法吗?“简单”对我来说意味着不需要所有这些getter-setter-header。如果您碰巧运行Servlet 2.5,您可以安装JBoss EL来实现类似EL 2.2的增强。
public class ... implements TagLibrary {
@Override
public Method createFunction(String taglib, String functionName) {
if (!map.containsKey(functionName)) {
String classname = "de.Test" + functionName;
ClassGen _cg = new ClassGen(classname,
"java.lang.Object", "Test.java", ACC_PUBLIC | ACC_SUPER,
new String[] {});
ConstantPoolGen _cp = _cg.getConstantPool();
InstructionFactory _factory = new InstructionFactory(_cg, _cp);
Method meth = find(functionName, getNavigation());
Class<?>[] parameterTypes = meth.getParameterTypes();
int countParams = parameterTypes.length;
Type[] types = new Type[countParams];
String[] names = new String[countParams];
for (int i = 0; i < countParams; i++) {
types[i] = new ObjectType(parameterTypes[i].getName());
names[i] = "arg" + i;
}
InstructionList il = new InstructionList();
MethodGen staticMethod = new MethodGen(ACC_PUBLIC | ACC_STATIC,
Type.OBJECT, types, names, functionName, getClass()
.getName(), il, _cp);
InstructionHandle ih_1 = il.append(new PUSH(_cp, functionName));
il.append(new PUSH(_cp, countParams));
il.append(_factory.createNewArray(Type.OBJECT, (short) 1));
il.append(InstructionConstants.DUP);
for (int i = 0; i < countParams; i++) {
il.append(new PUSH(_cp, i));
il.append(_factory.createLoad(Type.OBJECT, i));
il.append(InstructionConstants.AASTORE);
if (i != countParams - 1)
il.append(InstructionConstants.DUP);
}
il.append(_factory.createInvoke(getClass().getName(),
"call", Type.OBJECT, new Type[] { Type.STRING,
new ArrayType(Type.OBJECT, 1) },
Constants.INVOKESTATIC));
InstructionHandle ih_25 = il.append(_factory
.createReturn(Type.OBJECT));
staticMethod.setMaxStack();
staticMethod.setMaxLocals();
_cg.addMethod(staticMethod.getMethod());
il.dispose();
try {
byte[] bytes = _cg.getJavaClass().getBytes();
InjectingClassLoader icl = new InjectingClassLoader();
Method find =
find(functionName, icl.load(classname, bytes));
map.put(functionName, find);
} catch (Exception e) {
e.printStackTrace();
}
}
Method method = map.get(functionName);
return method;
}
public static Object call(String functionname, Object[] arguments) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Navigation myTargetBean = getNavigation();
Method proxyMethod = find(functionname,myTargetBean);
Object result = proxyMethod.invoke(myTargetBean, arguments);
return result;
}