GrailsV3.3.3,json视图1.2.7:对父对象进行深度渲染时出现堆栈溢出

GrailsV3.3.3,json视图1.2.7:对父对象进行深度渲染时出现堆栈溢出,grails,stack-overflow,json-view,Grails,Stack Overflow,Json View,在使用json视图深度呈现域对象时出现堆栈溢出 我已经创建了一个Customer域对象和Sites域对象,其中Customer有许多站点 我在bootsrap中创建了两个客户和一个站点,并将该站点分配给第一个客户 我已经使用gorm数据服务从接口创建了customerService实例 根据json视图文档(第2.5.2节),我已经保证,当我在控制器上使用索引操作时,我会对站点进行连接获取,并确保在一个hibernate会话中有客户列表和站点传递给视图 在调用“json g.render(cus

在使用json视图深度呈现域对象时出现堆栈溢出

我已经创建了一个Customer域对象和Sites域对象,其中Customer有许多站点

我在bootsrap中创建了两个客户和一个站点,并将该站点分配给第一个客户

我已经使用gorm数据服务从接口创建了customerService实例

根据json视图文档(第2.5.2节),我已经保证,当我在控制器上使用索引操作时,我会对站点进行连接获取,并确保在一个hibernate会话中有客户列表和站点传递给视图

在调用“json g.render(customer,[deep:true])中的_customerRest.gson视图中。我为站点域对象/控制器配对准备了一个_siteRest.gson模板(当我仅使用rest获取站点或正确呈现的特定站点时,此模板有效)

当我用Postman调用我的'/api/customers'uri时,我会得到一个重复的json输出,如下所示

[{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1...
Grails application running at http://localhost:8080 in environment: development
CustomerRest.customerRest.index method invoked
param map to customerService contains [controller:customerRest, action:index, max:10, fetch:[sites:join]]
service returned collection  [ttrestapi.model.Customer : 1, ttrestapi.model.Customer : 2]
2018-03-20 16:36:21.504 ERROR --- [nio-8080-exec-4] o.g.web.errors.GrailsExceptionResolver   : StackOverflowError occurred when processing request: [GET] /api/customers
Stacktrace follows:

java.lang.reflect.InvocationTargetException: null
    at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
    at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
    at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
    at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: grails.views.ViewRenderException: Error rendering view: Error rendering view: null
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:43)
    at grails.views.mvc.GenericGroovyTemplateView.renderMergedOutputModel(GenericGroovyTemplateView.groovy:73)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
    at grails.views.mvc.renderer.DefaultViewRenderer.render(DefaultViewRenderer.groovy:111)
    at grails.artefact.controller.RestResponder$Trait$Helper.internalRespond(RestResponder.groovy:188)
    at grails.artefact.controller.RestResponder$Trait$Helper.respond(RestResponder.groovy:98)
    at ttrestapi.model.CustomerRestController.index(CustomerRestController.groovy:27)
    ... 14 common frames omitted
Caused by: grails.views.ViewRenderException: Error rendering view: null
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:43)
    at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper$6.writeTo(DefaultGrailsJsonViewHelper.groovy:792)
    at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:123)
    at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:146)
    at ttRestApi_customerRest_index_gson.run(ttRestApi_customerRest_index_gson:9)
    at grails.plugin.json.view.JsonViewWritableScript.doWrite(JsonViewWritableScript.groovy:28)
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:40)
    ... 20 common frames omitted
Caused by: java.lang.StackOverflowError: null
    at java.io.InputStream.<init>(InputStream.java:45)
    at java.util.zip.ZipFile$ZipFileInputStream.<init>(ZipFile.java:711)
    at java.util.zip.ZipFile.getInputStream(ZipFile.java:375)
    at java.util.jar.JarFile.getInputStream(JarFile.java:447)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:454)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.curryDelegateAndGetContent(StreamingJsonBuilder.java:809)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeObject(StreamingJsonBuilder.java:775)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeCollectionWithClosure(StreamingJsonBuilder.java:766)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeObjects(StreamingJsonBuilder.java:706)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.call(StreamingJsonBuilder.java:610)
    at .....
import ttrestapi.model.Site

model {
    Site site
}

json jsonapi.render (site)
然后像这样的堆栈溢出

[{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1...
Grails application running at http://localhost:8080 in environment: development
CustomerRest.customerRest.index method invoked
param map to customerService contains [controller:customerRest, action:index, max:10, fetch:[sites:join]]
service returned collection  [ttrestapi.model.Customer : 1, ttrestapi.model.Customer : 2]
2018-03-20 16:36:21.504 ERROR --- [nio-8080-exec-4] o.g.web.errors.GrailsExceptionResolver   : StackOverflowError occurred when processing request: [GET] /api/customers
Stacktrace follows:

java.lang.reflect.InvocationTargetException: null
    at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
    at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
    at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
    at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: grails.views.ViewRenderException: Error rendering view: Error rendering view: null
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:43)
    at grails.views.mvc.GenericGroovyTemplateView.renderMergedOutputModel(GenericGroovyTemplateView.groovy:73)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
    at grails.views.mvc.renderer.DefaultViewRenderer.render(DefaultViewRenderer.groovy:111)
    at grails.artefact.controller.RestResponder$Trait$Helper.internalRespond(RestResponder.groovy:188)
    at grails.artefact.controller.RestResponder$Trait$Helper.respond(RestResponder.groovy:98)
    at ttrestapi.model.CustomerRestController.index(CustomerRestController.groovy:27)
    ... 14 common frames omitted
Caused by: grails.views.ViewRenderException: Error rendering view: null
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:43)
    at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper$6.writeTo(DefaultGrailsJsonViewHelper.groovy:792)
    at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:123)
    at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:146)
    at ttRestApi_customerRest_index_gson.run(ttRestApi_customerRest_index_gson:9)
    at grails.plugin.json.view.JsonViewWritableScript.doWrite(JsonViewWritableScript.groovy:28)
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:40)
    ... 20 common frames omitted
Caused by: java.lang.StackOverflowError: null
    at java.io.InputStream.<init>(InputStream.java:45)
    at java.util.zip.ZipFile$ZipFileInputStream.<init>(ZipFile.java:711)
    at java.util.zip.ZipFile.getInputStream(ZipFile.java:375)
    at java.util.jar.JarFile.getInputStream(JarFile.java:447)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:454)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.curryDelegateAndGetContent(StreamingJsonBuilder.java:809)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeObject(StreamingJsonBuilder.java:775)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeCollectionWithClosure(StreamingJsonBuilder.java:766)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeObjects(StreamingJsonBuilder.java:706)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.call(StreamingJsonBuilder.java:610)
    at .....
import ttrestapi.model.Site

model {
    Site site
}

json jsonapi.render (site)
当我查看customerService.list查询的结果时,我通过fetch:[sites:“join”]查询得到了第一个客户和他的单个站点

my_customerRest.gson看起来像

    import ttrestapi.model.Customer

    model {
        Customer customer
    }

    json g.render (customer , [deep:true])
相应的站点_siteRest.gson如下所示

[{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1,"sites":[{"id":1,"name":"Canary Wharf","customer":{"id":1...
Grails application running at http://localhost:8080 in environment: development
CustomerRest.customerRest.index method invoked
param map to customerService contains [controller:customerRest, action:index, max:10, fetch:[sites:join]]
service returned collection  [ttrestapi.model.Customer : 1, ttrestapi.model.Customer : 2]
2018-03-20 16:36:21.504 ERROR --- [nio-8080-exec-4] o.g.web.errors.GrailsExceptionResolver   : StackOverflowError occurred when processing request: [GET] /api/customers
Stacktrace follows:

java.lang.reflect.InvocationTargetException: null
    at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
    at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
    at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55)
    at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
    at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: grails.views.ViewRenderException: Error rendering view: Error rendering view: null
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:43)
    at grails.views.mvc.GenericGroovyTemplateView.renderMergedOutputModel(GenericGroovyTemplateView.groovy:73)
    at org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:303)
    at grails.views.mvc.renderer.DefaultViewRenderer.render(DefaultViewRenderer.groovy:111)
    at grails.artefact.controller.RestResponder$Trait$Helper.internalRespond(RestResponder.groovy:188)
    at grails.artefact.controller.RestResponder$Trait$Helper.respond(RestResponder.groovy:98)
    at ttrestapi.model.CustomerRestController.index(CustomerRestController.groovy:27)
    ... 14 common frames omitted
Caused by: grails.views.ViewRenderException: Error rendering view: null
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:43)
    at grails.plugin.json.view.api.internal.DefaultGrailsJsonViewHelper$6.writeTo(DefaultGrailsJsonViewHelper.groovy:792)
    at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:123)
    at grails.plugin.json.view.JsonViewWritableScript.json(JsonViewWritableScript.groovy:146)
    at ttRestApi_customerRest_index_gson.run(ttRestApi_customerRest_index_gson:9)
    at grails.plugin.json.view.JsonViewWritableScript.doWrite(JsonViewWritableScript.groovy:28)
    at grails.views.AbstractWritableScript.writeTo(AbstractWritableScript.groovy:40)
    ... 20 common frames omitted
Caused by: java.lang.StackOverflowError: null
    at java.io.InputStream.<init>(InputStream.java:45)
    at java.util.zip.ZipFile$ZipFileInputStream.<init>(ZipFile.java:711)
    at java.util.zip.ZipFile.getInputStream(ZipFile.java:375)
    at java.util.jar.JarFile.getInputStream(JarFile.java:447)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:454)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.curryDelegateAndGetContent(StreamingJsonBuilder.java:809)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeObject(StreamingJsonBuilder.java:775)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeCollectionWithClosure(StreamingJsonBuilder.java:766)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.writeObjects(StreamingJsonBuilder.java:706)
    at grails.plugin.json.builder.StreamingJsonBuilder$StreamingJsonDelegate.call(StreamingJsonBuilder.java:610)
    at .....
import ttrestapi.model.Site

model {
    Site site
}

json jsonapi.render (site)

我已经在提交了一份错误报告

此时的模板如下所示:

import williamwoodman.Customer

model {
    Customer customer
}

json g.render(customer, [deep: true])
import williamwoodman.Customer

model {
    Customer customer
}

json {
    id customer.id
    name customer.name
    sites g.render(customer.sites ?: [])
}
[{"id":1,"name":"Customer One",
  "sites":[{"id":1,"name":"Site One","customer":{"id":1}},       
           {"id":3,"name":"Site Three","customer":{"id":1}},
           {"id":2,"name":"Site Two","customer":{"id":1}}]}]
这将触发错误。根据您希望呈现的JSON的外观,您有许多选项。您可以做的一件事是编写模板,使其看起来像这样:

import williamwoodman.Customer

model {
    Customer customer
}

json g.render(customer, [deep: true])
import williamwoodman.Customer

model {
    Customer customer
}

json {
    id customer.id
    name customer.name
    sites g.render(customer.sites ?: [])
}
[{"id":1,"name":"Customer One",
  "sites":[{"id":1,"name":"Site One","customer":{"id":1}},       
           {"id":3,"name":"Site Three","customer":{"id":1}},
           {"id":2,"name":"Site Two","customer":{"id":1}}]}]
在该示例项目中,将模板更改为那样,然后向发送请求将生成如下所示的JSON:

import williamwoodman.Customer

model {
    Customer customer
}

json g.render(customer, [deep: true])
import williamwoodman.Customer

model {
    Customer customer
}

json {
    id customer.id
    name customer.name
    sites g.render(customer.sites ?: [])
}
[{"id":1,"name":"Customer One",
  "sites":[{"id":1,"name":"Site One","customer":{"id":1}},       
           {"id":3,"name":"Site Three","customer":{"id":1}},
           {"id":2,"name":"Site Two","customer":{"id":1}}]}]
您可能希望从单个
站点
地图中排除
客户
,也可能不这样做


我希望这能有所帮助。

您的问题太长,示例应用程序包含太多不相关的内容,所有这些都让我很难弄清楚到底发生了什么,但我花了足够的时间整理您的应用程序正在做什么,以确保它看起来像一个bug。我认为链接自的示例项目可能更容易使用。当然,您可以渲染
\u site.gson
模板,并在那里定义
站点
表示形式,而不是
站点g.render(customer.sites?:[])
。根据您想要生成的内容,您有许多选项。HTHJeff为问题的复杂性/长度表示歉意,但我最终选择了太多的选项,“如果我试试这个会怎么样”等等,所以git上的项目反映了这一点。我想要的是尝试使用jsonapi格式的响应,而手动渲染的更改最少。谢谢你为我提出这个问题——永远不知道是我愚蠢还是真的。目前,我将使用指示的一些选项进行练习,同时修复子关系“sites”中的comes-through.PS。您可能不希望back-point指针“customer:{id:1}”作为其父级的隐式指针。因此,在这种情况下,您希望父级的呈现过程在调用_site.gson模板呈现子级时能够识别这一点。我不确定jsonapi.render()助手类是否会自动处理这个问题,因此不确定在父对象上调用jsonapi.render()时如何指定要为子对象调用的默认模板。