xwiki livedata

52 阅读2分钟

xwiki livedata

1、xwiki支持livedata加载数据

extensions.xwiki.org/xwiki/bin/v…

安装官方实例很容易渲染出来表格了。

 {{liveData
   id="recentPages"
   properties="doc.title,doc.location,doc.author,doc.date"
   source="liveTable"
   sourceParameters="translationPrefix=platform.index."
   filters="doc.location=help"
   sort="doc.date:desc"
   limit="5"
 /}}

image-20250826132403441.png

2、livedata还支持静态json

 {{liveData
   id="movies"
   properties="title,genre,releaseDate,director"
 }}{
   "data": {
     "count": 2,
     "entries": [
       {
         "title": "Meet John Doe",
         "url": "https://www.imdb.com/title/tt0033891/",
         "genre": ["Comedy", "Romance"],
         "releaseDate": -904615200,
         "director": "Frank Capra",
         "directorURL": "https://www.imdb.com/name/nm0001008/"
       },
       {
         "title": "Modern Times",
         "url": "https://www.imdb.com/title/tt0027977/",
         "genre": ["Comedy", "Drama"],
         "releaseDate": -1068256800,
         "director": "Charlie Chaplin",
         "directorURL": "https://www.imdb.com/name/nm0000122/"
       }
     ]
   },
   "meta": {
     "propertyDescriptors": [
       {
         "id": "title",
         "name": "Title",
         "visible": true,
         "displayer": {"id": "link", "propertyHref": "url"}
       },
       {
         "id": "genre",
         "name": "Genre",
         "visible": true
       },
       {
         "id": "releaseDate",
         "name": "Release Date",
         "visible": true,
         "displayer": "date"
       },
       {
         "id": "director",
         "name": "Director",
         "visible": true,
         "displayer": {"id": "link", "propertyHref": "directorURL"}
       }
     ]
   }
 }{{/liveData}}

image-20250826132639578.png

3、xwiki还支持velocity去编译livedata(官方文档中写的不太详细)

image-20250826132758589.png

 {{velocity}}
 $services.liveData.render({
   'id': "recentPages",
   'properties': "doc.title,doc.location,doc.author,doc.date",
   'source': "liveTable",
   'sourceParameters': "translationPrefix=platform.index.",
   'filters': "doc.location=help",
   'sort': "doc.date:desc",
   'limit': 5
 })
 {{/velocity}}

页面上渲染出来是html语句,需要使用下面语法才可以

 {{velocity}}
 {{html}}
 $services.liveData.render({
   'id': "recentPages",
   'properties': "doc.title,doc.location,doc.author,doc.date",
   'source': "liveTable",
   'sourceParameters': "translationPrefix=platform.index.",
   'filters': "doc.location=help",
   'sort': "doc.date:desc",
   'limit': 5
 })
 {{/html}}
 {{/velocity}}

image-20250826133021369.png

4、 xwiki 加载其他页面

官方实例中看到在 sourceParameters="resultPage=XWiki.LoggingAdminTableJson"指定页面即可

image-20250826133408884.png

于是我定义了一个页面,叫f的页面

 {{groovy}}
 import groovy.json.JsonOutput
 ​
 // 设置 JSON 内容类型
 if (request?.getParameter("xpage") == "plain") {
     response.setContentType("application/json");
 }
 ​
 // 模拟数据库数据
 def all = [
     [id: "620000000000000", name: "甘肃省", level: 1, parentId: "0"],
     [id: "630000000000000", name: "青海省", level: 1, parentId: "0"],
     [id: "640000000000000", name: "宁夏回族自治区", level: 1, parentId: "0"],
     [id: "650000000000000", name: "新疆维吾尔自治区", level: 1, parentId: "0"]
 ]
 ​
 // 处理参数
 def offset = (request?.getParameter("offset") ?: "0") as int
 def limit = (request?.getParameter("limit") ?: "15") as int
 def searchName = request?.getParameter("name")?.trim()
 def sort = request?.getParameter("sort") ?: "id"
 def dir = request?.getParameter("dir")?.toLowerCase() ?: "asc"
 ​
 // 过滤逻辑
 def filtered = searchName ? all.findAll { it.name.contains(searchName) } : all
 ​
 // 排序逻辑
 if (dir == "desc") {
     filtered = filtered.sort { -it[sort] ?: 0 }
 } else {
     filtered = filtered.sort { it[sort] ?: 0 }
 }
 ​
 // 计算总数
 def totalCount = filtered.size() ?: 0
 def entries = filtered.drop(offset).take(limit)
 ​
 // 构造 Live Table JSON
 def result = [
     totalrows: totalCount,
     returnedrows: entries.size(),
     offset: offset + 1,
     reqNo: (request?.getParameter("reqNo") ?: "1") as int,
     rows: entries.collect { entry ->
         [
             id: entry.id,
             name: entry.name,
             level: entry.level,
             parentId: entry.parentId,
             doc_viewable: true
         ]
     }
 ]
 ​
 // 输出 JSON
 print JsonOutput.toJson(result)
 {{/groovy}}

image-20250826133533302.png

image-20250826133619880.png

通过接口,可以查询到json数据 http://localhost:8080/xwiki/bin/view/f?xpage=plain&outputSyntax=plain&limit=5&srid=GJsc9c7n

image-20250826133638274.png

4.1 遇到500错误 org.xwiki.livedata.LiveDataException: Failed to execute the live data query.

在livedata中指定加载f页面

 {{liveData
   id="adminDataGroovy"
   source="liveTable"
   sourceParameters="resultsPage=Main.f"
   layouts="table"
   showPageSizeDropdown="true"
   pageSizes="5,10,20"
   properties="id,name,level,parentId"
   propertyDescriptors='[{"id":"id","name":"政区编码","sortable":true},{"id":"name","name":"政区名字","sortable":true,"filterable":true},{"id":"level","name":"政区等级","sortable":true},{"id":"parentId","name":"父级编码","sortable":true}]'
 {{/liveData}}

image-20250826133940616.png 会导致接口500

 jakarta.servlet.ServletException: javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: org.xwiki.livedata.LiveDataException: Failed to execute the live data query.
     org.xwiki.rest.jersey.internal.JerseyServletContainer.service(JerseyServletContainer.java:141)
     org.xwiki.rest.jersey.internal.XWikiRESTServlet.service(XWikiRESTServlet.java:95)
     com.xpn.xwiki.web.XWikiContextInitializationFilter.doFilter(XWikiContextInitializationFilter.java:72)
     org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
     org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:66)
     org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:135)
     org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:211)
     org.xwiki.container.servlet.filters.internal.SafeRedirectFilter.doFilter(SafeRedirectFilter.java:106)
     org.xwiki.container.servlet.filters.internal.ResolveRelativeRedirectFilter.doFilter(ResolveRelativeRedirectFilter.java:129)
     org.xwiki.container.servlet.filters.internal.SourceURLResolverFilter.doFilter(SourceURLResolverFilter.java:177)
     org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:120)
     org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
     org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
     org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:670)
     org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
     org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:395)
     org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
     org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
     org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1748)
     org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
     org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1148)
     org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
     org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
     java.base/java.lang.Thread.run(Thread.java:833)

根本原因。

 javax.servlet.ServletException: org.glassfish.jersey.server.ContainerException: org.xwiki.livedata.LiveDataException: Failed to execute the live data query.
     org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:413)
     org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:350)
     org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:379)
     org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:312)
     org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
     org.xwiki.rest.jersey.internal.JerseyServletContainer.service(JerseyServletContainer.java:139)
     org.xwiki.rest.jersey.internal.XWikiRESTServlet.service(XWikiRESTServlet.java:95)
     com.xpn.xwiki.web.XWikiContextInitializationFilter.doFilter(XWikiContextInitializationFilter.java:72)
     org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
     org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:66)
     org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:135)
     org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:211)
     org.xwiki.container.servlet.filters.internal.SafeRedirectFilter.doFilter(SafeRedirectFilter.java:106)
     org.xwiki.container.servlet.filters.internal.ResolveRelativeRedirectFilter.doFilter(ResolveRelativeRedirectFilter.java:129)
     org.xwiki.container.servlet.filters.internal.SourceURLResolverFilter.doFilter(SourceURLResolverFilter.java:177)
     org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:120)
     org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
     org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
     org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:670)
     org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
     org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:395)
     org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
     org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
     org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1748)
     org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
     org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1148)
     org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
     org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
     java.base/java.lang.Thread.run(Thread.java:833)

根本原因。

 org.glassfish.jersey.server.ContainerException: org.xwiki.livedata.LiveDataException: Failed to execute the live data query.
     org.glassfish.jersey.servlet.internal.ResponseWriter.rethrow(ResponseWriter.java:260)
     org.glassfish.jersey.servlet.internal.ResponseWriter.failure(ResponseWriter.java:242)
     org.glassfish.jersey.server.ServerRuntime$Responder.process(ServerRuntime.java:445)
     org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:264)
     org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
     org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
     org.glassfish.jersey.internal.Errors.process(Errors.java:292)
     org.glassfish.jersey.internal.Errors.process(Errors.java:274)
     org.glassfish.jersey.internal.Errors.process(Errors.java:244)
     org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
     org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:235)
     org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:684)
     org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:398)
     org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:350)
     org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:379)
     org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:312)
     org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
     org.xwiki.rest.jersey.internal.JerseyServletContainer.service(JerseyServletContainer.java:139)
     org.xwiki.rest.jersey.internal.XWikiRESTServlet.service(XWikiRESTServlet.java:95)
     com.xpn.xwiki.web.XWikiContextInitializationFilter.doFilter(XWikiContextInitializationFilter.java:72)
     org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
     org.xwiki.container.servlet.filters.internal.SetHTTPHeaderFilter.doFilter(SetHTTPHeaderFilter.java:66)
     org.xwiki.resource.servlet.RoutingFilter.doFilter(RoutingFilter.java:135)
     org.xwiki.container.servlet.filters.internal.SavedRequestRestorerFilter.doFilter(SavedRequestRestorerFilter.java:211)
     org.xwiki.container.servlet.filters.internal.SafeRedirectFilter.doFilter(SafeRedirectFilter.java:106)
     org.xwiki.container.servlet.filters.internal.ResolveRelativeRedirectFilter.doFilter(ResolveRelativeRedirectFilter.java:129)
     org.xwiki.container.servlet.filters.internal.SourceURLResolverFilter.doFilter(SourceURLResolverFilter.java:177)
     org.xwiki.container.servlet.filters.internal.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:120)
     org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:483)
     org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
     org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:670)
     org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
     org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:395)
     org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
     org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:905)
     org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1748)
     org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
     org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1148)
     org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
     org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
     java.base/java.lang.Thread.run(Thread.java:833)

4.2 解决方法

然后查看官方文档给出列子,通过f12去查看接口请求,最后一步一步测试出正确的设置 sourceParameters="resultPage=xwiki:f.WebHome

 {{liveData id="adminDataGroovy" properties="id,name,level,parentId" source="liveTable" sourceParameters="resultPage=xwiki:f.WebHome&translationPrefix=admin.livetable." layouts="table" showPageSizeDropdown="true" pageSizes="5,10,20" sort="id:asc" limit="15"}}
 {
   "meta": {
     "propertyDescriptors": [
       {
         "id": "id",
         "name": "政区编码",
         "description": "政区编码",
         "sortable": true,
         "filterable": false
       },
       {
         "id": "name",
         "name": "政区名字",
         "description": "政区名字",
         "sortable": true,
         "filterable": true
       },
       {
         "id": "level",
         "name": "政区等级",
         "description": "政区等级",
         "sortable": true,
         "filterable": false
       },
       {
         "id": "parentId",
         "name": "父级编码",
         "description": "父级编码",
         "sortable": true,
         "filterable": false
       }
     ]
   }
 }}
 {{/liveData}}
 ​

image.png 后边会xwiki实现自定义表查询