Доступ к вложенным коллекциям в скорости

У меня есть этот шаблон скорости:

<userTestData>

#foreach( $user in $userList )
<user>
    <imsi>$user.imsi</imsi>
    #foreach ( $subscriptionToGroupMap in $user.subscriptionToGroupsList )
    <subscriptionToGroup>
        #foreach ( $key in subscriptionToGroupMap.keySet() )
        <$key>$subscriptionToGroupMap.get($key)</$key>
        #end
    </subscriptionToGroup>
    #end
</user>

#end
</userTestData>

Но при попытке я получаю следующее сообщение об ошибке:

16:23:58,872 ERROR [org.jboss.as.ejb3.invocation] (http-/127.0.0.1:8080-1) JBAS014134: EJB Invocation failed on component ... for method public void ...) ...: javax.ejb.EJBException: org.apache.velocity.exception.ParseErrorException: Invalid arg #2 in directive #foreach at userTestDataTemplate.vm[line 10, column 21]

Что в основном указывает на эту строку:

#foreach ( $subscriptionToGroupMap in $user.subscriptionToGroupsList )

Остальной код выглядит так:

ArrayList userList = new ArrayList();

    for(...) {
        Map user = new HashMap();
        user.put("imsi", i);

        ArrayList subscriptionToGroupsList = new ArrayList();

        Random rnd = new Random();
        int numberOfSubscriptionsToGroups = (rnd.nextInt(1000) % (BucketType.values().length)) + 1;
        LOG.log(Level.INFO, "...: numberOfSubscriptionsToGroups {0}", numberOfSubscriptionsToGroups);
        for(int j = 0; j < numberOfSubscriptionsToGroups; j++) {
            Map subscriptionToGroupMap = new HashMap();

            subscriptionToGroupMap.put("name", ...);

            subscriptionToGroupMap.put("priority", rnd.nextInt(Integer.MAX_VALUE) % (Integer.MAX_VALUE));

            ...
            Date startDate = new Date(dateGeneratorHelper);
            String stringFormattedStartDate = new SimpleDateFormat("dd-MM-yyyy'T'HH:mm:ss").format(startDate);
            subscriptionToGroupMap.put("startDate", stringFormattedStartDate);

            Date endDate = new Date(dateGeneratorHelper + dateGeneratorHelperHelper + 1);
            String stringFormattedEndDate = new SimpleDateFormat("dd-MM-yyyy'T'HH:mm:ss").format(endDate);
            subscriptionToGroupMap.put("endDate", stringFormattedEndDate);

            subscriptionToGroupsList.add(subscriptionToGroupMap);                
        }

        user.put("subscriptionToGroupsList", subscriptionToGroupsList);

        userList.add(user);           
    }

    String debugOutput = null;
    for (Iterator it = userList.iterator(); it.hasNext();) {
        HashMap userMap = (HashMap)it.next();
        debugOutput += "\n" + userMap.get("imsi") + "\n";
        ArrayList stgsList = (ArrayList)userMap.get("subscriptionToGroupsList");
        for (Iterator jt = stgsList.iterator(); jt.hasNext();) {
            Map stgMap = (HashMap)jt.next();
            for (Iterator nt = stgMap.entrySet().iterator(); nt.hasNext();) {
                Map.Entry<String, ArrayList> entry = (Map.Entry<String, ArrayList>)nt.next();
                debugOutput += "\t<" + entry.getKey() + ">" + entry.getValue() + "</" + entry.getKey() + ">\n";
            }
        }
    }

    ServletContext servletContext = (ServletContext)webServiceContext.getMessageContext().get(MessageContext.SERVLET_CONTEXT);
    VelocityEngine ve = new VelocityEngine();
    ve.setApplicationAttribute("javax.servlet.ServletContext", servletContext); 
    ve.setProperty("resource.loader", "webapp"); 
    ve.setProperty("webapp.resource.loader.class", "org.apache.velocity.tools.view.servlet.WebappLoader"); 
    ve.setProperty("webapp.resource.loader.path", "/WEB-INF/classes"); 
    VelocityContext velocityContext = new VelocityContext();
    velocityContext.put("userList", userList);
    Template t = ve.getTemplate("userTestDataTemplate.vm");
    StringWriter writer;
    writer = new StringWriter();
    t.merge(velocityContext, writer);

Я получаю правильный вывод отладки из фрагмента кода Java, поэтому информация есть.

У вас есть идеи, почему скорость не принимает доступ к списку в $user Map?


person soltzu    schedule 22.08.2014    source источник
comment
Это опечатка или отсутствует $ в #foreach ( $key in subscriptionToGroupMap.keySet() ) (должно быть $subscriptionToGroupMap.keySet())?   -  person Serge Ballesta    schedule 22.08.2014
comment
У меня нет с собой кода, поэтому я не могу его проверить, это было бы неловко, но в то же время большое облегчение. Итак, код выглядит нормально для вас?   -  person soltzu    schedule 23.08.2014
comment
вы должны быть в состоянии использовать $user.get("subscriptionToGroupsList"), верно?   -  person man.2067067    schedule 18.11.2016


Ответы (1)


Что ж, ваш контекст скорости содержит один объект «userList», который является List, и вы получаете из него $user: хорошо. $user — это Map, который, в свою очередь, содержит список карт.

Таким образом, ошибка нормальна: скорость использует нотацию . для доступа к методам объекта или атрибутам компонента, а не к элементам карты.

Вы должны написать:

#foreach ( $subscriptionToGroupMap in $user["subscriptionToGroupsList"] )

и за исключением отсутствующих строк $ to позже (см. мой комментарий выше), остальная часть шаблона выглядит нормально (но я не проверял...)

person Serge Ballesta    schedule 23.08.2014
comment
Спасибо! Я дам ему попробовать. - person soltzu; 23.08.2014
comment
Теперь это работает, с вашим предложением, большое спасибо. Кстати, мне не хватало знака «$», но я хотел бы думать, что исправил это, когда получил уведомление об ошибке. - person soltzu; 25.08.2014