2013-07-26 37 views
5

Có cách nào thích hợp để ghi đè cách JSF truy cập các trường bean từ một ngôn ngữ biểu thức không? Ý tưởng là bắt chước hành vi này để truy cập một giá trị Map<String, ?>, trong đó các trường bean sẽ là các khóa bản đồ.Làm cho JSF truy cập vào một giá trị Map <String, ?> từ một EL thay vì một trường bean?

Nói cách khác, có thể sử dụng bất kỳ cách nào để sử dụng #{beanContainingNestedMap.keyOfSaidNestedMap}, giống như nếu keyOfSaidNestedMap là trường của beanContainingNestedMap?

Nếu không, tôi có thể có giải pháp nào khác?


Ví dụ:

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" --> 

Điều gì sẽ là tuyệt vời là nếu tôi có thể làm điều gì đó tương tự (loại pseudo-code vì tôi không biết nếu một phương pháp như vậy tồn tại ;)):

@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

Vấn đề này không phải về JSF mà là EL. Có một phần truy cập bản đồ trong [Wiki StackOverflow EL] (http://stackoverflow.com/tags/el/info). Để trích dẫn hai ví dụ: '$ {someMap [dynamicKey]}', '$ {some ['class']. SimpleName}' –

+0

@LuiggiMendoza Cảm ơn bạn đã biết mẹo, nhưng ý tưởng đầu tiên là biết liệu có thể sử dụng '# {beanContainingAMap.keyOfTheSaidMap}' thay vào đó, giống như 'keyOfTheSaidMap' là một trường của bean. – sp00m

+0

Nếu bạn kiểm tra liên kết được cung cấp trong bình luận của tôi, bạn sẽ thấy rằng hiện tại là không thể. Bạn phải sử dụng '# {exampleBean.holder [foo]}'. –

Trả lời

13

Bạn có thể trực tiếp sử dụng bản đồ bằng EL.

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

[Phím của bạn] có thể là biểu thức năng động không? – MounirReg

+0

[Phím của bạn] có thể là biểu thức năng động không? Bất kỳ trợ giúp nào –

+0

@AnkitKumar: Điều đó phụ thuộc vào logic của bạn, nếu bạn muốn tạo khóa động, bạn có thể sử dụng '' –

-1

Vấn đề này không phải là về JSF nhưng EL. Như đã lưu ý trong bình luận @BalusC, bạn có thể trực tiếp sử dụng ký hiệu mà bạn đã muốn/cần với các đối tượng Map. Tôi đã chuẩn bị một ví dụ cơ bản về vấn đề này (lưu ý: đây chỉ là một ví dụ và nên duy trì như là hoặc được cải thiện kể từ khi nó sử dụng scriptlets và we must avoid scriptlets usage nhưng làm cho nó cho một thử nghiệm bẩn nhanh): mã lớp

<%@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> 

tài (hạn chế tối đa cho mục đích thử nghiệm):

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

này tạo ra một trang JSP mà in:

Luiggi - Mendoza 

Lưu ý rằng điều này (trừ phần scriptlet) sẽ làm việc trên một trang Facelets cũng vì đây là EL chứ không phải JSF.

Các vấn đề liên quan