我是Java的初学者,但我一直面临修改现有软件的问题。我很感激我能得到的任何帮助。
FreeMarker模板向一个宁静的API发出请求,并获取一些代表论坛上最近20个回复的XML。然后迭代它们,一个接一个地显示。
<#assign recent = rest(restContext + "/boards/id/352/replies/recent").messages />
有一个单独的API端点可以发布最近发布的20个主题。两个调用都返回相同格式的XML。
我想要做的是将这两件事合二为一,这样我就可以显示最近的帖子和帖子&#34;。我会按response.messages.post_time
对合并的项目进行排序。
我的问题是:我将如何在模板中执行此操作,这是我可以访问的唯一代码? rest
是否内置于FreeMarker中?我已经超出了自己的范围,并希望得到一些帮助,Java对我来说还是新手。
答案 0 :(得分:1)
这看起来非常熟悉...... Lithium REST API v1请求,不是吗?
你可以做的基本上是将两个响应对象合并到正确的位置(v1往往不是非常直观的,它的响应结构......)但是正常的rest()上下文对象响应不能简单地在FreeMarker中合并(与+在相同的数据类型上,例如散列或序列),所以你需要的是Lithium v14.12或更高版本以及restd()上下文对象...你的代码看起来应该是这样的:
<#assign replies = restd("/replies/recent", "json")?replace("\\/", "/")?replace(':null', ':"null"')?eval />
<#assign threads = restd("/topics/recent", "json")?replace("\\/", "/")?replace(':null', ':"null"')?eval />
<#assign merged = replies.response.messages.message + threads.response.messages.message />
<#assign objects = [] />
<#list merged as obj>
<#-- to sort we have to create our own object with a more simple structure (right now the post_time is deeply nested and not accessible with ?sort_by) -->
<#assign object = {
"subject": obj.subject.$,
"href": obj.href,
"post_time": obj.post_time.$,
"author": obj.author.login.$
} />
<#assign objects = objects + [object] />
</#list>
<#-- now we can sort the objects we created above, you probably want the newest objects on top, right? if not, just remove the ?reverse -->
<#assign objects = objects?sort_by("post_time")?reverse />
<ul>
<#-- now we list again (yes...) over the sorted objects and output them -->
<#list objects as obj>
<li><a href="${obj.href}">${obj.subject}</a> on ${obj.post_time} from ${obj.author}</li>
</#list>
</ul>
上面代码的解释基本上是我们需要来自Lithium的REST API的东西,可以转换为“普通”FreeMarker对象/数据类型,JSON恰好或多或少像FreeMarker Hashes / Sequences,少数例外(如空值...),这就是为什么我们需要这些?替换build-ins来“清理”传入的JSON字符串,然后调用?eval(是的,它是邪恶的,但有时我们需要邪恶来对抗邪恶= D )在该字符串上从中创建FreeMarker对象。
之后我们可以简单地将对象合并到正确的位置(在您的情况下是response.messages.message节点)并从中创建一个新对象,然后我们可以使用它来模拟我们的组件。
排序部分使得必须基本上“重新构造”我们刚刚合并的对象,因为FreeMarker内置?sort_by()无法处理深层嵌套对象,因为我们现在拥有它们...所以我们循环(list)通过合并的对象并使用我们需要的属性创建一个新的对象序列,之后我们可以在新的对象序列上使用?sort_by来按所需的字段对其进行排序。然后对序列进行排序,并准备在另一个循环中进行模板化。