2013-07-26 37 views
2

我有下面這段代碼 -Freemarker的:遍歷LinkedHashMap中

public class Result { 
    private Map<String, String> dataPoints = new LinkedHashMap<String, String>(); 

    public Map<String, String> getData() { 
     return Maps.newHashMap(data); 
    } 

    public Set<Map.Entry<String, String>> getDataEntries() { 
     return data.entrySet(); 
    } 

    public void addData(final String key, final String value) { 
     this.data.put(key, value); 
    } 
} 

我使用LinkedHashMap的,因爲我想保持插入順序。我試圖在freemarker代碼中迭代地圖,如下所示。但是,我得到一個例外。

<#if (result.dataPoints?keys?size > 0) > 
    <#list result.getDataEntries() as entry> 
     <tr> 
      <td width="35%"> 
       <div>${entry.key}</div> 
      </td> 
      <td width="45%">${entry.value}</td> 
      <td width="19%">&nbsp;</td> 
     </tr> 
    </#list> 
</#if> 

例外:

Expression result.getDataEntries is undefined on line 50, column 24 in settings/settings- 
diagnostics.ftl. The problematic instruction: ---------- ==> list result.getDataEntries() 
as entry [on line 50, column 17 in settings/settings-diagnostics.ftl] in user-directive 
printDiagnosticResult [on line 64, column 25 in settings/settings-diagnostics.ftl] in 
user-directive printDiagnosticResult [on line 76, column 13 in settings/settings- 
diagnostics.ftl] in user-directive layout.landingbase [on line 1, column 1 in  
settings/settings-diagnostics.ftl] ---------- Java backtrace for programmers: ---------- 
freemarker.core.InvalidReferenceException: Expression result.getDataEntries is undefined 
on line 50, column 24 in settings/settings-diagnostics.ftl. at 
freemarker.core.TemplateObject.assertNonNull(TemplateObject.java:124) at 
freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:134) at 
freemarker.core.MethodCall._getAsTemplateModel(MethodCall.java:114) at  
freemarker.core.Expression.getAsTemplateModel(Expression.java:89) at 
freemarker.core.IteratorBlock.accept(IteratorBlock.java:94) at  
freemarker.core.Environment.visit(Environment.java:208) at 

如果我替換上面代碼:

<#if (result.dataPoints?keys?size > 0) > 
    <#list result.dataPoints?keys as key> 
     <tr> 
      <td width="35%"> 
       <div>${key}</div> 
      </td> 
      <td width="45%">${result.dataPoints[key]}</td> 
      <td width="19%">&nbsp;</td> 
     </tr> 
    </#list> 
</#if> 

任何想法,我怎麼遍歷在地圖上,讓我得到了相同的順序?

+0

什麼是與最後一個模板的問題? – ddekany

+0

@ddekany:'result.dataPoints?keys'返回的項目不按照插入操作排序。即使由'result.dataPoints?values'返回的項目也不符合插入順序。 – devang

+1

它保持我的訂單。 ''key'不會返回一些與鍵混合的方法或屬性?因爲那時我知道問題是什麼...... – ddekany

回答

2

這應該做的伎倆:

<#if result.dataPoints?has_content > 
    <#list result.dataPoints.entrySet() as entry> 
     <tr> 
      <td width="35%"> 
       <div>${entry.key}</div> 
      </td> 
      <td width="45%">${entry.value}</td> 
      <td width="19%">&nbsp;</td> 
     </tr> 
    </#list> 
</#if> 

可能還需要設置對象包裝程序freemarker模板配置。就像這樣:

BeansWrapper beansWrapper = (BeansWrapper) ObjectWrapper.BEANS_WRAPPER; 
beansWrapper.setExposeFields(true); 
config.setObjectWrapper(beansWrapper); 

哪裏configfreemarker.template.Configuration。 如果您在使用Spring框架,然後擴展FreeMarkerConfigurer

public class FreeMarkerBeanWrapperConfigurer extends FreeMarkerConfigurer { 
    @Override 
    protected void postProcessConfiguration(Configuration config) throws IOException, TemplateException { 
    super.postProcessConfiguration(config); 

    BeansWrapper beansWrapper = (BeansWrapper) ObjectWrapper.BEANS_WRAPPER; 
    beansWrapper.setExposeFields(true); 
    config.setObjectWrapper(beansWrapper); 
    } 
} 
+1

同樣,'?keys'意味着在LinkedHashMap的情況下以原始順序返回鍵。我試過它是100%肯定的,它在這裏工作。因此,儘管此解決方案可能有效,但最好找出問題的根源。 – ddekany

+0

@ddekany:我同意,我想我錯過了一些東西。我試圖找到根本原因。 – devang

+0

@gotuskar:如果沒有實現'SortedMap',Maps會自動被freemarker包裝到'SimpleHash'中。 'LinkedHashMap'沒有實現'SortedMap'並且被包裝到'HashMap'中。正如我所說的,你需要使用'BeansWrapper'來獲得'LinkedHashMap'的所有好處。你可以在這裏閱讀更多關於freemarker SimpleHash:[SimpleHash](http://freemarker.org/docs/api/freemarker/template/SimpleHash.html) –