Skip to content

Commit b61ba90

Browse files
authored
Merge pull request #10631 from grails/3.2.x-issue-10623
Params not being passed to UrlMappings capturing errors
2 parents 0692ad0 + 016cee5 commit b61ba90

File tree

7 files changed

+110
-8
lines changed

7 files changed

+110
-8
lines changed

grails-web-mvc/src/main/groovy/org/grails/web/errors/GrailsExceptionResolver.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@
2020
import grails.util.Environment;
2121

2222
import java.io.IOException;
23-
import java.util.Collections;
24-
import java.util.Enumeration;
25-
import java.util.List;
26-
import java.util.Map;
23+
import java.util.*;
2724

2825
import javax.servlet.ServletContext;
2926
import javax.servlet.ServletException;
@@ -34,13 +31,13 @@
3431
import org.apache.commons.logging.LogFactory;
3532
import org.codehaus.groovy.control.CompilationFailedException;
3633
import grails.core.GrailsApplication;
37-
import grails.util.GrailsClassUtils;
3834
import org.grails.exceptions.reporting.DefaultStackTraceFilterer;
3935
import org.grails.core.exceptions.GrailsRuntimeException;
4036
import org.grails.exceptions.reporting.StackTraceFilterer;
4137
import grails.core.support.GrailsApplicationAware;
4238
import grails.web.mapping.UrlMappingInfo;
4339
import org.grails.exceptions.ExceptionUtils;
40+
import org.grails.web.mapping.DefaultUrlMappingInfo;
4441
import org.grails.web.mapping.UrlMappingUtils;
4542
import grails.web.mapping.UrlMappingsHolder;
4643
import org.grails.web.util.GrailsApplicationAttributes;
@@ -162,6 +159,18 @@ protected ModelAndView resolveViewOrForward(Exception ex, UrlMappingsHolder urlM
162159
HttpServletResponse response, ModelAndView mv) {
163160

164161
UrlMappingInfo info = matchStatusCode(ex, urlMappings);
162+
163+
if ( info != null ) {
164+
UrlMappingInfo requestInfo = urlMappings.match(request.getRequestURI());
165+
166+
if ( requestInfo != null ) {
167+
Map params = new HashMap();
168+
params.putAll(UrlMappingUtils.findAllParamsNotInUrlMappingKeywords(requestInfo.getParameters()));
169+
params.putAll(info.getParameters());
170+
info = new DefaultUrlMappingInfo(info, params, grailsApplication);
171+
}
172+
}
173+
165174
try {
166175
if (info != null && info.getViewName() != null) {
167176
resolveView(request, info, mv);
@@ -190,7 +199,7 @@ protected void forwardRequest(UrlMappingInfo info, HttpServletRequest request, H
190199
ModelAndView mv, String uri) throws ServletException, IOException {
191200
info.configure(WebUtils.retrieveGrailsWebRequest());
192201
String forwardUrl = UrlMappingUtils.forwardRequestForUrlMappingInfo(
193-
request, response, info, mv.getModel());
202+
request, response, info, mv.getModel(), true);
194203
if (LOG.isDebugEnabled()) {
195204
LOG.debug("Matched URI [" + uri + "] to URL mapping [" + info +
196205
"], forwarding to [" + forwardUrl + "] with response [" + response.getClass() + "]");

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
import grails.validation.ConstrainedProperty;
1919

20+
import java.util.Arrays;
21+
import java.util.List;
2022
import java.util.Map;
2123

2224
/**
@@ -89,6 +91,33 @@ public interface UrlMapping extends Comparable, UrlCreator {
8991
*/
9092
String NAMESPACE = "namespace";
9193

94+
95+
String VIEW = "view";
96+
97+
String RESOURCES = "resources";
98+
99+
String EXCLUDES = "excludes";
100+
101+
String INCLUDES = "includes";
102+
103+
String PERMANENT = "permanent";
104+
105+
String EXCEPTION = "exception";
106+
107+
List<String> KEYWORDS = Arrays.asList(CONTROLLER,
108+
ACTION,
109+
HTTP_METHOD,
110+
REDIRECT_INFO,
111+
VERSION,
112+
URI,
113+
PLUGIN,
114+
NAMESPACE,
115+
VIEW,
116+
RESOURCES,
117+
INCLUDES,
118+
PERMANENT,
119+
EXCEPTION);
120+
92121
/**
93122
* Matches the given URI and returns an instance of the UrlMappingInfo interface or null
94123
* if a match couldn't be established

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,4 +121,11 @@ public interface UrlMappingInfo {
121121
* @return redirect information for this url mapping, null if no redirect is specified
122122
*/
123123
Object getRedirectInfo();
124+
125+
/**
126+
* Retrieves the UrlMappingData (information about a parsed URL) if any
127+
*
128+
* @return The UrlMappingData instance
129+
*/
130+
UrlMappingData getUrlData();
124131
}

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

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import grails.web.mapping.UrlMapping;
3131
import grails.web.mapping.UrlMappingData;
3232
import grails.core.GrailsApplication;
33+
import grails.web.mapping.UrlMappingInfo;
3334
import grails.web.mapping.exceptions.UrlMappingException;
3435
import org.grails.web.servlet.mvc.GrailsWebRequest;
3536
import org.grails.web.util.WebUtils;
@@ -124,7 +125,6 @@ public DefaultUrlMappingInfo(Object viewName, Map params, UrlMappingData urlData
124125
this(params, urlData, grailsApplication);
125126
this.viewName = viewName;
126127
Assert.notNull(viewName, "Argument [viewName] cannot be null or blank");
127-
128128
}
129129

130130
public DefaultUrlMappingInfo(Object uri, UrlMappingData data, GrailsApplication grailsApplication) {
@@ -140,6 +140,17 @@ public DefaultUrlMappingInfo(Object uri,String httpMethod, UrlMappingData data,
140140
Assert.notNull(uri, "Argument [uri] cannot be null or blank");
141141
}
142142

143+
public DefaultUrlMappingInfo(UrlMappingInfo info, Map params, GrailsApplication grailsApplication) {
144+
this(params, info.getUrlData(), grailsApplication);
145+
this.redirectInfo = info.getRedirectInfo();
146+
this.controllerName = info.getControllerName();
147+
this.actionName = info.getActionName();
148+
this.namespace = info.getNamespace();
149+
this.pluginName = info.getPluginName();
150+
this.viewName = info.getViewName();
151+
}
152+
153+
143154
@Override
144155
public String getHttpMethod() {
145156
return httpMethod;
@@ -268,6 +279,11 @@ public Object getRedirectInfo() {
268279
return redirectInfo;
269280
}
270281

282+
@Override
283+
public UrlMappingData getUrlData() {
284+
return null;
285+
}
286+
271287
@Override
272288
public boolean equals(Object o) {
273289
if (this == o) return true;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.grails.web.mapping
1717

18+
import grails.web.mapping.UrlMappingData
1819
import groovy.transform.CompileStatic
1920

2021
/**
@@ -64,4 +65,9 @@ class ForwardUrlMappingInfo extends AbstractUrlMappingInfo {
6465
boolean isParsingRequest() {
6566
return false
6667
}
68+
69+
@Override
70+
UrlMappingData getUrlData() {
71+
null
72+
}
6773
}

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import grails.util.GrailsStringUtils;
1919
import grails.web.CamelCaseUrlConverter;
2020
import grails.web.UrlConverter;
21+
import grails.web.mapping.UrlMapping;
2122
import grails.web.mapping.UrlMappingInfo;
2223
import grails.web.mapping.UrlMappingsHolder;
2324
import groovy.lang.Binding;
@@ -59,6 +60,22 @@ public class UrlMappingUtils {
5960
private UrlMappingUtils() {
6061
}
6162

63+
/**
64+
*
65+
* @return a Map without entries whose key belongs to UrlMapping#KEYWORDS
66+
*/
67+
public static Map<String, Object> findAllParamsNotInUrlMappingKeywords(Map<String, Object> params) {
68+
Map<String, Object> urlParams = new HashMap<>();
69+
if ( params != null ) {
70+
for (String key : params.keySet()) {
71+
if (!UrlMapping.KEYWORDS.contains(key)) {
72+
urlParams.put(key, params.get(key));
73+
}
74+
}
75+
}
76+
return urlParams;
77+
}
78+
6279
/**
6380
* Looks up the UrlMappingsHolder instance
6481
*
@@ -120,7 +137,7 @@ private static String buildDispatchUrlForMapping(UrlMappingInfo info, boolean in
120137
}
121138
}
122139

123-
final Map parameters = info.getParameters();
140+
final Map parameters = findAllParamsNotInUrlMappingKeywords(info.getParameters());
124141
if (parameters != null && !parameters.isEmpty() && includeParams) {
125142
try {
126143
forwardUrl.append(WebUtils.toQueryString(parameters));
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.grails.web.mapping
2+
3+
import spock.lang.Specification
4+
import spock.lang.Unroll
5+
6+
class UrlMappingUtilsSpec extends Specification {
7+
8+
@Unroll
9+
def "test buildDispatchUrlForMapping"() {
10+
expect:
11+
expected == UrlMappingUtils.findAllParamsNotInUrlMappingKeywords(params)
12+
13+
where:
14+
params | expected
15+
[id: 1, controller: 'home'] | [id: 1]
16+
[id: 1, format: 'json'] | [id: 1, format: 'json']
17+
}
18+
}

0 commit comments

Comments
 (0)