2013-07-26 23 views
5

Gibt es eine geeignete Möglichkeit, die Art und Weise, wie JSF auf die Beans-Felder von einer Ausdruckssprache zugreift, außer Kraft zu setzen? Die Idee ist, dieses Verhalten nachzuahmen, um auf Map<String, ?> Werte zuzugreifen, wobei die Bean-Felder die Map-Schlüssel wären.Machen Sie JSF Zugriff auf eine Karte <String, ?> Werte von einer EL statt einer Bean-Felder?

Mit anderen Worten, ist es jedenfalls möglich #{beanContainingNestedMap.keyOfSaidNestedMap} zu verwenden, als ob keyOfSaidNestedMap ein Feld der beanContainingNestedMap waren?

Wenn nicht, welche andere Lösung könnte ich haben?


Beispiel:

Holder.java

public class Holder { 

    private Map<String, Object> objects = new HashMap<String, Object>(); 

    public void add(String key, Object value) { 
     objects.put(key, value); 
    } 

    public Object getObject(String key) { 
     return objects.get(key); 
    } 

} 

ExampleBean.java

public class ExampleBean { 

    private Holder holder = new Holder(); 

    public ExampleBean() { 
     holder.add("foo", 42); 
     holder.add("bar", 'X'); 
    } 

    public Holder getHolder() { 
     return holder; 
    } 

} 

example.xhtml

<c:out value="#{exampleBean.holder.foo}" /> <!-- should print "42" --> 
<c:out value="#{exampleBean.holder.bar}" /> <!-- should print "X" --> 

Was groß ist, wäre, wenn ich so etwas wie tun könnte (eine Art Pseudo-Code, da ich weiß nicht, ob eine solche Methode besteht ;)):

@Override // override JSF's (if any...) 
public Object resolveEl(String el) { 
    try { 
     super.resolveEl(el); 
    } catch (ElException e) { 
     Object bean = e.getBean(); 
     String fieldName = e.getFieldName(); 
     if (bean instanceof Holder) { 
      Holder holder = (Holder) bean; 
      Object value = holder.getObject(fieldName); 
      if (value == null) { 
       throw e; 
      } else { 
       return value; 
      } 
     } 
    } 
} 
+0

Bei diesem Problem handelt es sich nicht um JSF, sondern um EL. Es gibt einen Kartenzugriffsbereich im [StackOverflow EL Wiki] (http://stackoverflow.com/tags/el/info). Um zwei Beispiele zu nennen: '$ {someMap [dynamicKey]}', '$ {einige ['Klasse']. SimpleName}' –

+0

@LuiggiMendoza Danke für die Tipps, aber die Idee war zuerst zu wissen, ob es irgendwie möglich ist Verwenden Sie '# {beanContainingAMap.keyOfTheSaidMap}' stattdessen, als wäre 'keyOfTheSaidMap' ein Feld der Bean. – sp00m

+0

Wenn Sie den Link in meinem Kommentar überprüfen, werden Sie feststellen, dass dies derzeit nicht möglich ist. Sie müssen '# {exampleBean.holder [foo]}' 'verwenden. –

Antwort

13

Sie können direkt Karte von EL verwenden.

Holder.java

public class Holder { 

    private Map<String, Object> objects = new HashMap<String, Object>(); 

    public void add(String key, Object value) { 
     objects.put(key, value); 
    } 

    public Map<String, Object> getObjectsMap() { 
     return objects; 
    } 

} 

EL

#{exampleBean.holder.objectsMap[your-key]} 
+2

Kann [your-key] ein dynamischer Ausdruck sein? – MounirReg

+0

Kann [your-key] ein dynamischer Ausdruck sein? Jede Hilfe –

+0

@AnkitKumar: Das hängt von Ihrer Logik ab, wenn Sie einen dynamischen Schlüssel konstruieren möchten, können Sie '' verwenden –

-1

Dieses Problem ist nicht über JSF sondern EL. Wie im @BalusC-Kommentar erwähnt, können Sie die Notation, die Sie bereits benötigen/benötigen, direkt mit Map Objekten verwenden. Ich habe ein einfaches Beispiel zu dieser vorbereitet (Anmerkung: Dies ist nur ein Beispiel und soll so oder verbessert bleiben, da es Scriptlets verwendet und we must avoid scriptlets usage aber machte es für einen schnellen schmutzigen Test):

<%@page import="edu.home.model.entity.User"%> 
<%@page import="java.util.HashMap"%> 
<%@page import="java.util.Map"%> 
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" 
    pageEncoding="ISO-8859-1"%> 
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 
<!DOCTYPE html> 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>Insert title here</title> 
</head> 
<body> 
    <% 
     //Scriptlets usage, sorry. This code must be moved to a Servlet or another controller component 
     //defining the map 
     Map<String, User> aMap = new HashMap<String, User>(); 
     //defining a value for the map 
     User user = new User(); 
     user.setFirstName("Luiggi"); 
     user.setLastName("Mendoza"); 
     //adding the value in the map 
     aMap.put("userLM", user); 
     //making the map accesible in EL through PageContext attribute 
     pageContext.setAttribute("aMap", aMap); 
    %> 
    <!-- Accessing directly to the userLM key and its attributes --> 
    ${aMap.userLM.firstName} - ${aMap.userLM.lastName} 
</body> 
</html> 

Benutzerklassencode (für Testzwecke minimiert):

public class User { 
    private String firstName; 
    private String lastName; 
    //empty constructor 
    //getters and setters 
} 

Dies erzeugt eine JSP-Seite, die gedruckt:

Luiggi - Mendoza 

Beachten Sie, dass diese (mit Ausnahme des scriptlet Teil) auf einer Facelets Seite arbeiten wird auch da dies EL ist und nicht JSF.