2012-03-21 5 views
0

を呼び出すmanagedbeanするには私はこのような管理対象Bean(セッションスコープ)を持つ:のtaglibコール

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)}"/> 

を呼び出すために好きなものを私が知っていることである:それは使用することが可能にイマイチおよびbパラメータ。

OK:これが例でのtaglibを使用して、これを起動するための「静的」可能性が次のようになります。

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

dynamiclyそれを呼び出すために約何? bcelまたはURLClassLoaderを使用していますか?

答えて

1

このEL式の構文は、静的メソッドのみのためのものであり、タグライブラリで定義する必要があり、名前空間はビューで定義されています:

#{namespacePrefix:fn(arg)} 

と、このEL式はオブジェクトインスタンス上parameterized method呼び出します。

#{someInstance.method(arg)} 

Expression Language 2.2以上(Java EE 6)で使用できます。これに先立って、サードパーティ製JSFライブラリでも同様の式がサポートされています。

とても長い間、それがJSFコンテキスト内で実行されるよう、静的メソッドから管理対象Beanを検索することが可能である:

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

しかしこれは理想的なアプローチではありません。このコードはJSF 2に対して書かれています。以前のバージョンでは、異なる動的参照呼び出しが使用されていました。

あなたは、静的メソッドでBeanが必要な場合は、フォームの式を使用します。

#{namespacePrefix:fn(someBean, 1, 2)} 
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)}を呼び出す

+0

シンプルに行うことができれば、なぜ難しいのですか? – BalusC

+0

jsf 1.2の「シンプルな」方法はありますか? 「シンプルな」とは、ゲッター・セッターのオーバーヘッドをすべて持たないということです。 –

+1

Servlet 2.5を実行した場合、JBoss ELをインストールしてEL 2.2のような拡張機能をインストールすることができます。 – BalusC

関連する問題