Skip to content

Commit fdbc6aa

Browse files
committed
Fixes #9455 - Use link generator to generate forward links, allowing same args as redirect
1 parent 0432f2d commit fdbc6aa

File tree

4 files changed

+42
-15
lines changed

4 files changed

+42
-15
lines changed

grails-plugin-controllers/src/main/groovy/grails/artefact/controller/support/RequestForwarder.groovy

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,23 @@ package grails.artefact.controller.support
1717

1818
import grails.web.UrlConverter
1919
import grails.web.api.WebAttributes
20+
import grails.web.mapping.LinkGenerator
2021
import grails.web.servlet.mvc.GrailsParameterMap
2122
import groovy.transform.CompileStatic
2223
import org.grails.plugins.web.controllers.metaclass.ForwardMethod
2324
import org.grails.web.mapping.ForwardUrlMappingInfo
2425
import org.grails.web.mapping.UrlMappingUtils
26+
import org.grails.web.mapping.mvc.UrlMappingsHandlerMapping
2527
import org.grails.web.servlet.mvc.GrailsWebRequest
2628
import org.grails.web.util.GrailsApplicationAttributes
29+
import org.grails.web.util.WebUtils
2730
import org.springframework.beans.MutablePropertyValues
2831
import org.springframework.beans.factory.annotation.Autowired
2932
import org.springframework.validation.DataBinder
33+
import org.springframework.web.context.request.WebRequest
34+
import org.springframework.web.filter.OncePerRequestFilter
35+
36+
import javax.servlet.RequestDispatcher
3037

3138
/**
3239
* A Trait for classes that forward the request
@@ -37,22 +44,27 @@ import org.springframework.validation.DataBinder
3744
@CompileStatic
3845
trait RequestForwarder implements WebAttributes {
3946
private UrlConverter urlConverter
47+
private LinkGenerator linkGenerator
4048

4149
@Autowired(required=false)
4250
void setUrlConverter(UrlConverter urlConverter) {
4351
this.urlConverter = urlConverter
4452
}
4553

54+
private LinkGenerator lookupLinkGenerator() {
55+
if(this.linkGenerator == null) {
56+
this.linkGenerator = webRequest.getApplicationContext().getBean(LinkGenerator)
57+
}
58+
return this.linkGenerator
59+
}
60+
4661
/**
4762
* Forwards a request for the given parameters using the RequestDispatchers forward method
4863
*
4964
* @param params The parameters
5065
* @return The forwarded URL
5166
*/
5267
String forward(Map params) {
53-
def urlInfo = new ForwardUrlMappingInfo()
54-
DataBinder binder = new DataBinder(urlInfo)
55-
binder.bind(new MutablePropertyValues(params))
5668

5769
GrailsWebRequest webRequest = getWebRequest()
5870

@@ -68,18 +80,18 @@ trait RequestForwarder implements WebAttributes {
6880
def convertedControllerName = convert(controllerName.toString())
6981
webRequest.controllerName = convertedControllerName
7082
}
71-
urlInfo.controllerName = webRequest.controllerName
83+
params.controller = webRequest.controllerName
7284

7385
if(params.action) {
74-
urlInfo.actionName = convert(params.action.toString())
86+
params.action = convert(params.action.toString())
7587
}
7688

7789
if(params.namespace) {
78-
urlInfo.namespace = params.namespace
90+
params.namespace = params.namespace
7991
}
8092

8193
if(params.plugin) {
82-
urlInfo.pluginName = params.plugin
94+
params.plugin = params.plugin
8395
}
8496
}
8597

@@ -88,14 +100,21 @@ trait RequestForwarder implements WebAttributes {
88100
def request = webRequest.currentRequest
89101
def response = webRequest.currentResponse
90102

91-
request.setAttribute(GrailsApplicationAttributes.FORWARD_IN_PROGRESS, true)
103+
WebUtils.exposeRequestAttributes(request, (Map)model);
92104

93-
if(params.params instanceof Map) {
94-
urlInfo.parameters.putAll((Map)params.params)
95-
}
105+
request.setAttribute(GrailsApplicationAttributes.FORWARD_IN_PROGRESS, true)
96106
request.setAttribute(GrailsApplicationAttributes.FORWARD_ISSUED, true)
97-
String uri = UrlMappingUtils.forwardRequestForUrlMappingInfo(request, response, urlInfo, (Map)model, true)
98-
return uri
107+
108+
def fowardURI = lookupLinkGenerator().link(params)
109+
110+
111+
RequestDispatcher dispatcher = request.getRequestDispatcher(fowardURI)
112+
webRequest.removeAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW, 0);
113+
webRequest.removeAttribute(GrailsApplicationAttributes.GRAILS_CONTROLLER_CLASS_AVAILABLE, WebRequest.SCOPE_REQUEST);
114+
webRequest.removeAttribute(UrlMappingsHandlerMapping.MATCHED_REQUEST, WebRequest.SCOPE_REQUEST);
115+
webRequest.removeAttribute("grailsWebRequestFilter" + OncePerRequestFilter.ALREADY_FILTERED_SUFFIX, WebRequest.SCOPE_REQUEST);
116+
dispatcher.forward(request, response);
117+
return fowardURI
99118
}
100119

101120

grails-test-suite-uber/src/test/groovy/org/grails/web/metaclass/ForwardMethodTests.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ForwardMethodTests extends AbstractGrailsControllerTests {
2121
webRequest.controllerName = "fowarding"
2222
assertEquals "/fowarding/two",testController.one()
2323
assertEquals "/next/go",testController.three()
24-
assertEquals "/next/go?id=10",testController.four()
24+
assertEquals "/next/go/10",testController.four()
2525
assertEquals "bar", request.foo
2626
}
2727
}

grails-test-suite-uber/src/test/groovy/org/grails/web/metaclass/ForwardMethodspec.groovy

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.grails.web.metaclass
22

33
import grails.artefact.Controller
4+
import grails.web.mapping.LinkGenerator
45
import org.springframework.web.context.request.RequestContextHolder
56

67
import javax.servlet.RequestDispatcher
@@ -36,6 +37,13 @@ class ForwardMethodSpec extends Specification {
3637
response = Mock(HttpServletResponse)
3738
dispatcher = Mock(RequestDispatcher)
3839
urlConverter = Mock(UrlConverter)
40+
41+
def linkGenerator = Mock(LinkGenerator)
42+
linkGenerator.link(_) >> { args ->
43+
def map = args[0]
44+
"/$map.controller/$map.action"
45+
}
46+
appContext.getBean(LinkGenerator) >> linkGenerator
3947

4048
webRequest = new GrailsWebRequest(request, response, servletContext, appContext)
4149
RequestContextHolder.setRequestAttributes(webRequest)

grails-web-url-mappings/src/main/groovy/org/grails/web/mapping/UrlMappingUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,10 @@ public static String forwardRequestForUrlMappingInfo(HttpServletRequest request,
162162
@SuppressWarnings({ "unchecked", "rawtypes" })
163163
public static String forwardRequestForUrlMappingInfo(HttpServletRequest request,
164164
HttpServletResponse response, UrlMappingInfo info, Map model, boolean includeParams) throws ServletException, IOException {
165-
org.springframework.web.util.WebUtils.exposeRequestAttributes(request, model);
166165

167166
String forwardUrl = buildDispatchUrlForMapping(info, includeParams);
168167

168+
org.springframework.web.util.WebUtils.exposeRequestAttributes(request, model);
169169
//populateParamsForMapping(info);
170170
RequestDispatcher dispatcher = request.getRequestDispatcher(forwardUrl);
171171

0 commit comments

Comments
 (0)