ruthst00 commented on code in PR #16516:
URL: https://github.com/apache/grails-core/pull/16516#discussion_r4340300660


##########
grails-web-common/src/main/groovy/org/grails/web/servlet/mvc/GrailsWebRequest.java:
##########
@@ -426,6 +426,27 @@ public void setRenderView(boolean renderView) {
         this.renderView = renderView;
     }
 
+    /**
+     * Returns {@code true} if the {@code renderView} flag has not been 
explicitly cleared by a
+     * {@code render()} call.  Unlike {@link #isRenderView()}, this method 
does <em>not</em> consult
+     * the response status, the committed state, or the redirect flag — it 
reflects only whether
+     * {@link #setRenderView(boolean) setRenderView(false)} was called (which 
every {@code render()}
+     * variant except {@code render(view:)} does).
+     *
+     * <p>Use this in the handler adapter to decide whether to attempt view 
resolution: returning
+     * {@code null} from {@code handle()} is the correct signal to {@code 
DispatcherServlet} that
+     * the response has already been handled, and that signal must be sent 
whenever any
+     * {@code render()} variant other than {@code render(view:)} was called — 
regardless of whether
+     * the response happens to be committed or carries an error status.</p>
+     *
+     * @return {@code true} if no {@code render()} call has cleared the flag; 
{@code false} if
+     *         {@code render()} (other than {@code render(view:)}) has already 
handled the response
+     * @since 8.0

Review Comment:
   Fixed in 
https://github.com/apache/grails-core/pull/16516/changes/c4cb607c2bde85b90d50410431d321ec60dbe31b



##########
grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/mvc/UrlMappingsInfoHandlerAdapter.groovy:
##########
@@ -161,11 +161,31 @@ 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.
+                    //
+                    // Exception: during a servlet include dispatch the outer 
response is already
+                    // committed, but the include can still append output and 
must still resolve a
+                    // view. Skip the committed check for include dispatches.
+                    if (!webRequest.renderViewRequested

Review Comment:
   Fixed in 
https://github.com/apache/grails-core/pull/16516/changes/c4cb607c2bde85b90d50410431d321ec60dbe31b



-- 
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]

Reply via email to