ruthst00 commented on code in PR #16516:
URL: https://github.com/apache/grails-core/pull/16516#discussion_r4223554835
##########
grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/mvc/UrlMappingsInfoHandlerAdapter.groovy:
##########
@@ -161,11 +161,27 @@ class UrlMappingsInfoHandlerAdapter implements
HandlerAdapter, ApplicationContex
}
}
+ // render(view:) sets MODEL_AND_VIEW on the request and does
not set renderView=false,
+ // so this path is always intentional view resolution — honour
it unconditionally.
def modelAndView =
request.getAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW)
if (modelAndView instanceof ModelAndView) {
return (ModelAndView) modelAndView
}
- else if (result instanceof Map) {
+ if (result instanceof Map) {
+ // All render() variants except render(view:) set
webRequest.renderView = false.
+ // Check the raw flag (not the composite isRenderView(),
which also returns false
+ // for error status, committed response, or redirect) so
that only an explicit
+ // render() call suppresses view resolution. (#15819)
+ //
+ // redirect() sets REDIRECT_ISSUED on the request and a
3xx status without calling
+ // setRenderView(false), so renderViewRequested stays
true. Similarly, the response
+ // may already be committed (e.g. the body was written
directly) without that flag
+ // being cleared. In both cases there is nothing left for
DispatcherServlet to do.
+ if (!webRequest.renderViewRequested
+ ||
request.getAttribute(GrailsApplicationAttributes.REDIRECT_ISSUED) != null
+ || response.committed) {
Review Comment:
Fixed in
https://github.com/apache/grails-core/pull/16516/changes/53679a78227345e58c92d7725dc5897526e90321
##########
grails-web-url-mappings/src/test/groovy/org/grails/web/mapping/mvc/UrlMappingsHandlerMappingSpec.groovy:
##########
@@ -319,4 +405,73 @@ class FooController {
def notFound() {
RequestContextHolder.currentRequestAttributes().response.writer <<
"Not Found"
}
+
+ /**
+ * Calls render(text:), which sets renderView=false and writes the body.
The adapter must
+ * return null so DispatcherServlet does not attempt view resolution.
(#15819)
+ */
+ @Action
+ def renderText() {
+ render(text: 'hello')
+ null
+ }
+
+ /**
+ * Calls render(text:) and also returns a Map — the exact bug scenario
from #15819 where the
+ * adapter previously ignored renderView=false when result instanceof Map.
+ */
+ @Action
+ def renderTextWithMap() {
+ render(text: 'hello')
+ [foo: 'bar']
+ }
+
+ /**
+ * Calls redirect() (which sets REDIRECT_ISSUED on the request and a 3xx
status without calling
+ * setRenderView(false)) and also returns a Map. The adapter must return
null — there is nothing
+ * left for DispatcherServlet to do after a redirect. (#15819)
+ */
+ @Action
+ def redirectWithMap() {
+ request.setAttribute(
Review Comment:
Fixed in
https://github.com/apache/grails-core/pull/16516/changes/53679a78227345e58c92d7725dc5897526e90321
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]