简体   繁体   English

Freemarker 调用 static java 方法来自 java.lang.ZA0FAEF0851B4194C46F46Z 方法

[英]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:

  1. 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)

  2. 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。

  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM