2016-04-14 6 views
1

eine Managed Bean (MyBean) gegeben, die eine abstrakte Klasse erweitert (AbstractMapModel), die im Wesentlichen ein Wrapper für eine Karte ist:Expression Language Bean-Eigenschaft Auswerteauftrag

Die AbstractMapModel Klasse enthält eine getValue (Object key) Methode.

Die MyBean-Klasse enthält eine getName() -Methode.

Die XPage hat einen Wert, der zu # {MyBean.name} führt.

Ich finde, dass es MyBean.getValue ("Name") aufruft und ignoriert MyBean.getName(). Meine Frage ist, ist diese korrekte Operation?

Logischerweise scheint es, als sollte es versuchen, die spezifischere getName() vor dem Versuch, den generalisierten getValue ("Name"). Wenn man nachforscht, scheint es, dass, wenn getValue() null zurückgibt, es nach einem bestimmten Getter suchen soll, der, selbst wenn ich die Logik zweifelhaft finde, zumindest das richtige Endergebnis erhalten würde. Aber beides passiert nicht.

Ich habe das Problem mit dem folgenden Code gelöst:

public Object getValue(final Object key) { 
    /* Following code added to check for specific getter before performing getValues() */ 
    String propertyName = key.toString(); 
    propertyName = propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); 
    Method method = null; 
    try { 
     method = this.getClass().getMethod("get" + propertyName, new Class[] {}); 
     if (method != null) { 
      return method.invoke(this); 
     } 
    } catch (Exception e) { 
     // Do nothing 
    } 
    try { 
     method = this.getClass().getMethod("is" + propertyName, new Class[] {}); 
     if (method != null) { 
      return method.invoke(this); 
     } 
    } catch (Exception e) { 

    } 
    /* --------------------------------------------- */ 
    return getValues().get(key); 
} 

Es scheint nicht, wie diese Abhilfe nötig sein sollte, so frage ich mich, ob ich etwas grundlegendes Missverständnis von dem, was los ist. Alternativ, gibt es einen besseren Weg, ich sollte das tun?

+1

Ich habe es schon lange nicht mehr gesehen, aber Tim Tripcony hat ein Video dazu für NotesIn9 gemacht und über dieses genaue Problem gesprochen, wenn ich mich richtig erinnere. Grundsätzlich ist alles, was Tim vorgeschlagen hat, die beste Lösung. –

+0

Was ich mache, ist von Tims Arbeit abgeleitet. Ich habe das NI9 seit einiger Zeit nicht mehr rezensiert, und ich glaube, ich habe mich nur schlecht erinnert, wie das funktionierte. Vielen Dank! –

Antwort

2

So oft es auch sinnvoll wäre, EL folgt keiner "Fallback" -Strategie. Stattdessen hat es eine Reihe von Schnittstellen, die es durchläuft - Map, DataObject usw. (ich erinnere mich nicht an die spezifische Reihenfolge) - und, wenn das Objekt mit einem dieser übereinstimmt, wird es diese Route ausschließlich verwenden. Was du dort getan hast, mit Reflektion, ist die gleiche Strategie, die ich benutzt habe, um dieses Verhalten zu bekommen.

+0

Hypothetisch könnten Sie einen neuen Handler am Anfang der Liste registrieren, der jedes Objekt nehmen würde und diese "Fallback" -Operation darauf ausführen würde, aber das wäre wahrscheinlich zu hacky, um es wert zu sein. –

+0

Ich versuche, für minimalen Hacking zu kodieren, also denke ich, dass ich bei dieser Methode bleiben werde. Gibt es einen Grund, es nicht so zu machen, wie schlechte Leistung oder so? Ich versuche zu entscheiden, ob das in die abstrakte Klasse gehört oder ob ich dieses Verhalten von Fall zu Fall überschreiben sollte. Ich konnte meinen getValue überschreiben, um nach bestimmten Schlüsseln zu suchen, und dann die Methode zurückgeben, anstatt den Wert von der Karte nachzuschlagen. Aber dieser Code würde wirklich hässlich aussehen. –

+1

Es gibt keinen großen Grund, sich Gedanken über die Leistung bei der Reflexion zu machen, bis es zu einem tatsächlichen Problem wird - während die Reflektion "langsam" ist, verglichen mit beispielsweise Integer-Tests, ist sie im Vergleich zu Datenbank-bezogenen sehr schnell. Ich nutze diese Route schon seit einer Weile und musste nicht lange überlegen. Wenn es sich als zu langsam erweist, ist die Route nach bestimmten Schlüsseln der richtige Weg - das sind die Objekte von IBM wie DominoViewEntry. –