2013-09-16 5 views
0

Эта простая программа, использующая OGNL, возвращает мне список нулевых значений вместо [A, B, D]. Я пробовал #root{#x.get(#this)} и все еще возвращает мне список нулей. Зачем? Благодарю.Выбор OGNL с картой

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 


import ognl.Ognl; 



public class ognlTest { 
    static public void main(String[] args) throws Exception 
    { 
     Map<String, Object> m = new HashMap<String, Object>(); 

     m.put("a", "A"); 
     m.put("b", "B"); 
     m.put("c", "C"); 
     m.put("d", "D"); 

     List<String> k = new ArrayList<>(); 
     k.add("a"); 
     k.add("b"); 
     k.add("d"); 


     Map<String, Object> context = new HashMap<String, Object>(); 
     context.put("x", m); 

     Object expression = Ognl.parseExpression("#root.{ #x[#this] }"); 

     Object value = Ognl.getValue(expression, context, k); 

     System.out.println("value = [" + value + "]"); 

    } 
} 

Update:

Использование #root.{#z=#this, #x[#z]}. Глупо, но это работает. Я считаю, что это ошибка, но Apache OGNL 4 находится в подвешенном состоянии, а OGNL 3.0.6 - это ... Я не уверен, что он поддерживается; дистрибутив даже не компилируется, потому что он имеет неправильные зависимости.

+0

Не могли бы вы рассказать, чего вы пытаетесь достичь с помощью этого выражения? Возможно, это может быть сделано по-другому. В любом случае для объяснения, почему он возвращает null, см. Мой ответ. –

+0

Он должен возвращать [A, B, D]. Учитывая массив ключей, верните мне список значений с карты. –

+0

Да, но почему вы так делаете? Зачем использовать проекцию над корневым объектом, а не над картой? Любая причина для этого? –

ответ

1

Прежде всего, всегда лучше указывать тип ключа при получении значений с карты. Например, построив новую строку.

map[new java.lang.String(#this)] 

Тем не менее, это выражение возвращает аннулирует, потому что #this в этом контексте относится к корневому объекту.

Вы можете с легкостью проверить это, создав свой список k, прежде чем карта и положить k.toString() в качестве ключа.

m.put(k.toString(), "k_is_here"); 

Object expression = Ognl 
        .parseExpression("#root.{ #x[new java.lang.String(#this)] }"); 

Выход будет:

value = [[k_is_here, k_is_here, k_is_here]] 

Update

Для выбора значений из карты со списком значений, переданных в качестве ключей использовать это выражение:

#x.entrySet().{? #this.key in #root}.{#this.value} 

Сначала это выберет из entrySet карты все записи, которые находятся в списке, а затем получает значения выбранных записей.

+0

Почему это должно быть # this это корневой объект, когда #this предположительно ссылается на каждый элемент #root? Как я понимаю, #this относится к каждому элементу коллекции при использовании с оператором выбора '. {}'. Например, #root. {# This.length()} вернет [1,1,1] не [3,3,3]. –

+0

Также я не уверен, что мне нужно передать новую строку в карту, которую я уже знаю, использует клавиши String. –

+0

@ApprenticeQueue: Вы пробовали код, который я разместил? Очевидно, что '# this' в этом контексте внутри' [] 'reference root object. –

Смежные вопросы