我正在使用带有 freemarker 模板的 Gson。当我尝试将数组对象检查为 null 时出现错误

Am using Gson with freemarker template. When i try to check an array object as null then am getting error

我的Json代码如下

{
    "data": [
        {  
   "TEST": ["qasasas","zxXcxvxv"],
            "id": "5892574",
  },
  {  
   "TEST": null,
            "id": "121334",
  }
  ]
}

我的Freemarker模板Java代码如下

Gson g = new GsonBuilder()
                .setLenient()
                .create();
        JsonObject resultsResponse = g.fromJson(content, JsonObject.class);

        root.put(
                "datalist",
                resultsResponse);



        Configuration cfg = new Configuration(Configuration.VERSION_2_3_27);
        cfg.setDirectoryForTemplateLoading(new File("C:\Users\ponmanikandanb\Desktop\g\freemarker"));
        cfg.setDefaultEncoding("UTF-8");
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
        cfg.setLogTemplateExceptions(true);
        cfg.setWrapUncheckedExceptions(true);
        cfg.setAPIBuiltinEnabled(true);



        DefaultObjectWrapper owraop = new DefaultObjectWrapper(Configuration.VERSION_2_3_28);
       owraop.setIterableSupport(true);
        owraop.setExposeFields(true);
        owraop.setExposureLevel(BeansWrapper.EXPOSE_ALL);
        owraop.setMethodsShadowItems(true);
       owraop.setForceLegacyNonListCollections(true);
        owraop.setUseAdaptersForContainers(true);
        cfg.setObjectWrapper(owraop);

       Template temp = cfg.getTemplate("templates\sampleAccountInflow.xml");
       Writer out = new OutputStreamWriter(System.out);
        temp.process(root, out);
        String s = "";
        out.write(s);
        System.out.println(s);

我的 Freemarker 模板代码是

 <#list accountList.data as response>
  <#if response.TEST.isJsonNull()>is null</#if>
  </#list>

如果我尝试检查数组 TEST 字段是否为空,那么我将遇到异常。

Feb 27, 2019 1:34:14 PM freemarker.log._JULLoggerFactory$JULLogger error
SEVERE: Error executing FreeMarker template
FreeMarker template error:
For "." left-hand operand: Expected a hash, but this has evaluated to a collection (com.google.gson.JsonArray wrapped into f.t.DefaultIterableAdapter):
==> response.TEST  [in template "templates\sampleAccountInflow.xml" at line 18, column 16]

----
FTL stack trace ("~" means nesting-related):
    - Failed at: #if response.TEST.isJsonNull()  [in template "templates\sampleAccountInflow.xml" at line 18, column 11]
----

Java stack trace (for programmers):
----
freemarker.core.NonHashException: [... Exception message was already printed; see it above ...]
    at freemarker.core.Dot._eval(Dot.java:48)
    at freemarker.core.Expression.eval(Expression.java:83)
    at freemarker.core.MethodCall._eval(MethodCall.java:58)
    at freemarker.core.Expression.eval(Expression.java:83)
    at freemarker.core.Expression.evalToBoolean(Expression.java:161)
    at freemarker.core.Expression.evalToBoolean(Expression.java:147)
    at freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:48)
    at freemarker.core.Environment.visit(Environment.java:366)
    at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:291)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
    at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:242)
    at freemarker.core.Environment.visitIteratorBlock(Environment.java:642)
    at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:107)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:93)
    at freemarker.core.Environment.visit(Environment.java:330)
    at freemarker.core.Environment.visit(Environment.java:336)
    at freemarker.core.Environment.process(Environment.java:309)
    at freemarker.template.Template.process(Template.java:384)
    at com.temenos.data.transform.jsontoxml.JSONToXMLConversion.main(JSONToXMLConversion.java:83)

Exception in thread "main" FreeMarker template error:
For "." left-hand operand: Expected a hash, but this has evaluated to a collection (com.google.gson.JsonArray wrapped into f.t.DefaultIterableAdapter):
==> response.TEST  [in template "templates\sampleAccountInflow.xml" at line 18, column 16]

----
FTL stack trace ("~" means nesting-related):
    - Failed at: #if response.TEST.isJsonNull()  [in template "templates\sampleAccountInflow.xml" at line 18, column 11]
----

Java stack trace (for programmers):
----
freemarker.core.NonHashException: [... Exception message was already printed; see it above ...]
    at freemarker.core.Dot._eval(Dot.java:48)
    at freemarker.core.Expression.eval(Expression.java:83)
    at freemarker.core.MethodCall._eval(MethodCall.java:58)
    at freemarker.core.Expression.eval(Expression.java:83)
    at freemarker.core.Expression.evalToBoolean(Expression.java:161)
    at freemarker.core.Expression.evalToBoolean(Expression.java:147)
    at freemarker.core.ConditionalBlock.accept(ConditionalBlock.java:48)
    at freemarker.core.Environment.visit(Environment.java:366)
    at freemarker.core.IteratorBlock$IterationContext.executedNestedContentForCollOrSeqListing(IteratorBlock.java:291)
    at freemarker.core.IteratorBlock$IterationContext.executeNestedContent(IteratorBlock.java:271)
    at freemarker.core.IteratorBlock$IterationContext.accept(IteratorBlock.java:242)
    at freemarker.core.Environment.visitIteratorBlock(Environment.java:642)
    at freemarker.core.IteratorBlock.acceptWithResult(IteratorBlock.java:107)
    at freemarker.core.IteratorBlock.accept(IteratorBlock.java:93)
    at freemarker.core.Environment.visit(Environment.java:330)
    at freemarker.core.Environment.visit(Environment.java:336)
    at freemarker.core.Environment.process(Environment.java:309)
    at freemarker.template.Template.process(Template.java:384)
    at com.temenos.data.transform.jsontoxml.JSONToXMLConversion.main(JSONToXMLConversion.java:83)

首先我将 Json 转换为 GSON(JsonObject) 数据并映射到 freemarker 模板过程的映射。所有其他都在工作,同时检查 JsonArray 对象的 null 时出错。 如果我检查 null 的正常值,它工作正常。

以下解决方案将起作用。 我们需要覆盖 DefaultObjectWrapper 中的 wrap 方法。

    public class GsonObjectWraper extends DefaultObjectWrapper {

    public GsonObjectWraper(Version incompatibleImprovements){
                super(incompatibleImprovements);
    }

    @Override
    public TemplateModel wrap(Object obj) throws TemplateModelException {
        if (obj == null) {
            return super.wrap(null);
        }
        if (obj instanceof JsonArray) {
            return handleUnknownType(obj);
        }
        return super.wrap(obj);
    }
}