StreamingTemplateEngine异常MissingPropertyException [英] StreamingTemplateEngine exception MissingPropertyException

查看:103
本文介绍了StreamingTemplateEngine异常MissingPropertyException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何避免Map中模板中缺少参数时发生MissingPropertyException并将未找到的值替换为null?

How to avoid occurrence MissingPropertyException at absence of parameters from a template in Map and to replace not found values by null?

import groovy.text.StreamingTemplateEngine
import groovy.text.Template

class Test {

    private static Writable binding(Map map, String string) {
        Template template = new StreamingTemplateEngine().createTemplate(string)
        return template.make(map)
    }

    static void main(String... args) {
        def template = "\${test1} \${test2}"
        def map = ["test1": "test1"]
        print binding(map, template)
    }
}

推荐答案

没有配置选项可以抑制此异常,但是您可以扩展传递给模板的映射并稍微改变其行为.考虑以下示例:

There is no configuration option to suppress this exception, however you can extend a map you pass to the template and change its behavior a bit. Consider following example:

import groovy.text.StreamingTemplateEngine
import groovy.text.Template

def string = '''
Dear <% out.print firstname %> ${lastname},

We <% if (accepted) out.print 'are pleased' else out.print 'regret' %> 
to inform you that your paper entitled
'$title' was ${ accepted ? 'accepted' : 'rejected' }.

The conference committee.
'''

def map = [
    firstname: 'test',
    lastname: 'test',
    accepted: true
]

Template template = new StreamingTemplateEngine().createTemplate(string)
println template.make(map)

它失败,但出现以下异常:

It fails with the following exception:

Caught: groovy.text.TemplateExecutionException: Template execution error at line 4:
         3:     We <% if (accepted) out.print 'are pleased' else out.print 'regret' %>     to inform you that your paper entitled
     --> 4:     '$title' was ${ accepted ? 'accepted' : 'rejected' }.
         5:     

groovy.text.TemplateExecutionException: Template execution error at line 4:
         3:     We <% if (accepted) out.print 'are pleased' else out.print 'regret' %>     to inform you that your paper entitled
     --> 4:     '$title' was ${ accepted ? 'accepted' : 'rejected' }.
         5:     

    at test.run(test.groovy:21)
Caused by: groovy.lang.MissingPropertyException: No such property: title for class: groovy.tmp.templates.StreamingTemplateScript1
    ... 1 more

它失败了,因为我们从4个模板变量中定义了3个(变量title缺失).

It fails because we have defined 3 from 4 template variables (variable title is missing).

让我们修复它.我们将通过以始终返回true的方式覆盖映射方法containsKey(Object key)来做到这一点(模板引擎使用此方法,如果它返回false,则模板引擎会引发异常).我们将创建一个包装器类,该包装器封装一个映射,并将不存在的方法的调用委托给该包装的类.我们将此类称为Bindings.

Let's fix it. We will do it by overriding map method containsKey(Object key) in a way that it always returns true (this method is used by the template engine and if it returns false, template engine throws an exception). We will create a wrapper class that encapsulates a map and delegates invocation of non existing methods to this wrapped class. We will call this class Bindings.

import groovy.text.StreamingTemplateEngine
import groovy.text.Template

class Bindings {
    @Delegate private final Map map

    Bindings(Map map) {
        this.map = map
    }

    boolean containsKey(Object key) {
        return true
    }
}

def string = '''
Dear <% out.print firstname %> ${lastname},

We <% if (accepted) out.print 'are pleased' else out.print 'regret' %> 
to inform you that your paper entitled
'$title' was ${ accepted ? 'accepted' : 'rejected' }.

The conference committee.
'''

def map = [
    firstname: 'test',
    lastname: 'test',
    accepted: true
]

Template template = new StreamingTemplateEngine().createTemplate(string)
println template.make(new Bindings(map))

输出:

Dear test test,

We are pleased 
to inform you that your paper entitled
'null' was accepted.

The conference committee.

不再抛出MissingPropertyException.但是,如您所见,null在字符串内被打印为null.如果您想打印一个空字符串,可以将Object get(Object key)方法添加到Bindings并覆盖其默认行为:

There is no MissingPropertyException thrown anymore. However, as you can see, null is printed as null inside the String. If you would like to print an empty string instead, you can add Object get(Object key) method to Bindings and override its default behavior:

class Bindings {
    @Delegate private final Map map

    Bindings(Map map) {
        this.map = map
    }

    boolean containsKey(Object key) {
        return true
    }

    Object get(Object key) {
        return map.getOrDefault(key, '')
    }
}

如果这样做,您将看到类似于以下内容的输出:

If you do so, you will see the output similar to:

Dear test test,

We are pleased 
to inform you that your paper entitled
'' was accepted.

The conference committee.

希望有帮助.

这篇关于StreamingTemplateEngine异常MissingPropertyException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆