@@ -297,6 +297,12 @@ public static String forwardRequestForUrlMappingInfo(HttpServletRequest request,
297297 //populateParamsForMapping(info);
298298 RequestDispatcher dispatcher = request .getRequestDispatcher (forwardUrl );
299299
300+ // Clear the request attributes that affect view rendering. Otherwise
301+ // whatever we forward to may render the wrong thing! Note that we
302+ // don't care about the return value because we're delegating
303+ // responsibility for rendering the response.
304+ saveAndResetWebRequest (request , info );
305+
300306 exposeForwardRequestAttributes (request );
301307 exposeRequestAttributes (request , model );
302308 dispatcher .forward (request , response );
@@ -318,42 +324,82 @@ public static IncludedContent includeForUrlMappingInfo(HttpServletRequest reques
318324 String includeUrl = buildDispatchUrlForMapping (info , true );
319325
320326 final GrailsWebRequest webRequest = GrailsWebRequest .lookup (request );
321-
322- String currentController = null ;
323- String currentAction = null ;
324- String currentId = null ;
325- ModelAndView currentMv = null ;
326- Map currentParams = null ;
327- if (webRequest !=null ) {
328- currentController = webRequest .getControllerName ();
329- currentAction = webRequest .getActionName ();
330- currentId = webRequest .getId ();
331- currentParams = new HashMap ();
332- currentParams .putAll (webRequest .getParameterMap ());
333- currentMv = (ModelAndView )webRequest .getAttribute (GrailsApplicationAttributes .MODEL_AND_VIEW , 0 );
334- }
327+ InternalSavedRequest savedRequest = null ;
328+
335329 try {
336- if (webRequest !=null ) {
337- webRequest .getParameterMap ().clear ();
338- info .configure (webRequest );
339- webRequest .getParameterMap ().putAll (info .getParameters ());
340- webRequest .removeAttribute (GrailsApplicationAttributes .MODEL_AND_VIEW , 0 );
341- }
330+ savedRequest = saveAndResetWebRequest (request , info );
342331 return includeForUrl (includeUrl , request , response , model );
343332 }
344333 finally {
345- if (webRequest != null ) {
334+ if (savedRequest != null ) {
346335 webRequest .getParameterMap ().clear ();
347- webRequest .getParameterMap ().putAll (currentParams );
348- webRequest .setId (currentId );
349- webRequest .setControllerName (currentController );
350- webRequest .setActionName (currentAction );
351- if ( currentMv != null ) {
352- webRequest .setAttribute (GrailsApplicationAttributes .MODEL_AND_VIEW , currentMv , 0 );
336+ webRequest .getParameterMap ().putAll (savedRequest . getParameterMap () );
337+ webRequest .setId (savedRequest . getId () );
338+ webRequest .setControllerName (savedRequest . getController () );
339+ webRequest .setActionName (savedRequest . getAction () );
340+ if ( savedRequest . getModelAndView () != null ) {
341+ webRequest .setAttribute (GrailsApplicationAttributes .MODEL_AND_VIEW , savedRequest . getModelAndView () , 0 );
353342 }
354343 }
355344 }
356345 }
346+
347+ /**
348+ * Saves the details of the current web request in an {@link InternalSavedRequest}
349+ * instance, clears information related to view rendering from the request
350+ * attributes, and returns the saved request.
351+ * @param request The underlying HTTP request to process.
352+ * @param info The URL mapping that should be applied to the request after
353+ * the attributes have been cleared.
354+ * @return The saved web request details.
355+ */
356+ public static InternalSavedRequest saveAndResetWebRequest (HttpServletRequest request , UrlMappingInfo info ) {
357+ final GrailsWebRequest webRequest = GrailsWebRequest .lookup (request );
358+ InternalSavedRequest savedRequest = null ;
359+ if (webRequest != null ) {
360+ savedRequest = new InternalSavedRequest (
361+ webRequest .getControllerName (),
362+ webRequest .getActionName (),
363+ webRequest .getId (),
364+ webRequest .getParameterMap (),
365+ (ModelAndView ) webRequest .getAttribute (GrailsApplicationAttributes .MODEL_AND_VIEW , 0 ));
366+ webRequest .getParameterMap ().clear ();
367+ info .configure (webRequest );
368+ webRequest .getParameterMap ().putAll (info .getParameters ());
369+ webRequest .removeAttribute (GrailsApplicationAttributes .MODEL_AND_VIEW , 0 );
370+ }
371+
372+ return savedRequest ;
373+ }
374+
375+ /**
376+ * Simple class that stores a subset of information about a request, including
377+ * the target controller and action, and the request parameters. Also stores
378+ * information about any current ModelAndView that will be used to render the
379+ * response.
380+ */
381+ private static class InternalSavedRequest {
382+ private String controller ;
383+ private String action ;
384+ private String id ;
385+ private HashMap parameters ;
386+ private ModelAndView modelAndView ;
387+
388+ public InternalSavedRequest (String controllerName , String actionName , String id , Map parameterMap , ModelAndView mv ) {
389+ this .controller = controllerName ;
390+ this .action = actionName ;
391+ this .id = id ;
392+ this .parameters = new HashMap (parameterMap );
393+ this .modelAndView = mv ;
394+ }
395+
396+ public String getController () { return controller ; }
397+ public String getAction () { return action ; }
398+ public String getId () { return id ; }
399+ public Map getParameterMap () { return parameters ; }
400+ public ModelAndView getModelAndView () { return modelAndView ; }
401+ }
402+
357403
358404 /**
359405 * Includes the given URL returning the resulting content as a String
0 commit comments