[英]Freemarker call static java method from java.lang.Integer
i have a question.我有个问题。 I would like to call a static java method
Integer.toHexString()
in a freemaker template.我想在 freemaker 模板中调用 static java 方法
Integer.toHexString()
。 In my code i implemented following lines:在我的代码中,我实现了以下几行:
....
cfg.setSharedVariable("Integer",BeansWrapper.getDefaultInstance().
getStaticModels().
get("java.lang.Integer");
....
);
My template looks like this我的模板看起来像这样
<#list Items.iterator() as var>
<#assign hex = Integer.toHexString(var) />
${hex}
</#list>
But if i execute the code i get following error:但是,如果我执行代码,我会收到以下错误:
freemarker.core._TemplateModelException: An error has occurred when reading existing sub-variable "Integer"; see cause exception! The type of the containing value was: extended_hash+string (org.json.JSONObject wrapped into f.e.b.StringModel)
----
FTL stack trace ("~" means nesting-related):
- Failed at: #assign hex = Integer.toHexString(var... [in template "decToHex.ftl"...]
What am i doing wrong?我究竟做错了什么? Thanks.
谢谢。
Based on the error message, your data-model (aka. template context) is a org.json.JSONObject
.根据错误消息,您的数据模型(又名模板上下文)是
org.json.JSONObject
。 FreeMarker doesn't know that API, but it discovers that JSONObject
has a get(String)
method, and tries to use that. FreeMarker 不知道 API,但它发现
JSONObject
有一个get(String)
方法,并尝试使用它。 Unfortunately, that get
method doesn't behave as a Map
-style get(key)
.不幸的是,该
get
方法的行为不像Map
风格的get(key)
。 FreeMarker first calls JSONObject.get("Integer")
to see if the variable is in a data-model. FreeMarker 首先调用
JSONObject.get("Integer")
来查看变量是否在数据模型中。 If it isn't, it expects a null
to be returned, and then will try to get it from higher scopes (like from there shared variables).如果不是,它期望返回一个
null
,然后会尝试从更高的范围(比如从那里共享变量)获取它。 But JSONObject.get(String)
throws JSONException
instead of returning null
, which is what you see in the error log (if you look at the whole stack trace, JSONException
should be there as the cause exception).但是
JSONObject.get(String)
抛出JSONException
而不是返回null
,这是您在错误日志中看到的(如果您查看整个堆栈跟踪, JSONException
应该作为原因异常存在)。
To solve this, you need teach FreeMarker how to deal with JSONObject
-s:为了解决这个问题,你需要教 FreeMarker 如何处理
JSONObject
-s:
Create a class, let's call it JSONObjectAdapter
, which implements TemplateHashModelEx2
(or, the much simpler TemplateHashModel
can be enough for basic use-cases).创建一个 class,我们称之为
JSONObjectAdapter
,它实现了TemplateHashModelEx2
(或者,更简单的TemplateHashModel
足以满足基本用例)。 Inside that, when implementing TemplateHashModel.get(String)
, you must call JSONObject.has(key)
to check if the key exists, and if not, return null
, otherwise continue with calling JSONObject.get(key)
.其中,在实现
TemplateHashModel.get(String)
时,必须调用JSONObject.has(key)
来检查密钥是否存在,如果不存在,则返回null
,否则继续调用JSONObject.get(key)
。
Create a class, let's call it DefaultObjectWrapperWithJSONSupport
, that extends DefaultObjectWrapper
.创建一个 class,我们称之为
DefaultObjectWrapperWithJSONSupport
,它扩展DefaultObjectWrapper
。 Your class should wrap JSONObject
-s with JSONObjectAdapter
.您的 class 应该用
JSONObjectAdapter
包装JSONObject
-s。
Where you already configure FreeMarker (NOT before each template processing), specify the objectWrapper
to be a DefaultObjectWrapperWithJSONSupport
.如果您已经配置了 FreeMarker(不是在每个模板处理之前),请将
objectWrapper
指定为DefaultObjectWrapperWithJSONSupport
。
There's a few non-obvious things with doing above properly, so I strongly recommend starting out from this example: https://freemarker.apache.org/docs/pgui_datamodel_objectWrapper.html#pgui_datamodel_customObjectWrappingExample正确执行上述操作有一些不明显的事情,所以我强烈建议从这个例子开始: https://freemarker.apache.org/docs/pgui_datamodel_objectWrapper.html#pgui_datamodel_customObjectWrappingExample
Above linked example does the above 3 steps, but to support the Tupple
class, instead of JSONObject
.上面链接的示例执行了上述 3 个步骤,但支持
Tupple
class,而不是JSONObject
。 That's a TemplateSequenceModel
, instead of TemplateHashModel
, but otherwise what has to be done is very similar.那是一个
TemplateSequenceModel
,而不是TemplateHashModel
,但除此之外必须做的事情非常相似。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.