0

私は次のようなマネージド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)}"/>

私が知っているのは、 a および b パラメータを使用することはできません。

わかりました: これは、例では、taglib を使用してこれを呼び出す「静的」な可能性である必要があります。

public class CoolTaglib implements TagLibrary{
   ...
  public static void doSomething(int a, int b) {
    getHomeBeanFromSession().doSomething(a,b);
  }
}

動的に呼び出すのはどうですか?bcel または URLClassLoader を使用していますか?

4

2 に答える 2

1

このEL式の構文は静的メソッド専用であり、タグライブラリで定義し、ビューで名前空間を定義する必要があります。

 #{namespacePrefix:fn(arg)}

このEL式は、オブジェクトインスタンスでパラメータ化されたメソッドを呼び出します。

#{someInstance.method(arg)}

2番目の形式は、Expression Language 2.2以降(Java EE 6)で使用できます。これより前の一部のサードパーティJSFライブラリでは、同様の式がサポートされています。

JSFコンテキスト内で実行される限り、静的メソッドからマネージドBeanを検索することができます。

FacesContext context = FacesContext.getCurrentInstance();
SomeBean someBean = context.getApplication()
                           .evaluateExpressionGet(context, 
                                                  "#{someBean}", SomeBean.class);

ただし、これは理想的なアプローチではありません。このコードはJSF2に対して作成されました。以前のバージョンでは、異なる動的ルックアップ呼び出しが使用されていました。

静的メソッドでBeanが必要な場合は、次の形式の式を使用します。

#{namespacePrefix:fn(someBean, 1, 2)}
于 2012-03-21T13:20:27.023 に答える
0

ああ、私は働く方法を見つけました:

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;
}

これで、 #{cms:doSomething(1,2)} を呼び出すことができます

于 2012-03-21T22:21:37.547 に答える