From d8f22bea077da3ff010051283e280524b397ba4c Mon Sep 17 00:00:00 2001 From: Graeme Rocher Date: Tue, 15 Oct 2013 09:56:58 +0200 Subject: [PATCH] fix for GRAILS-10613 "request.exception returns "Method name must not be null" when exception in thrown in UrlFilters" --- .../web/mapping/filter/UrlMappingsFilter.java | 38 +++++-------------- .../web/servlet/ErrorHandlingServlet.java | 16 ++++++-- .../groovy/grails/web/util/WebUtils.java | 36 ++++++++++++++++++ 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/grails-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/filter/UrlMappingsFilter.java b/grails-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/filter/UrlMappingsFilter.java index b9460ae7c2f..29e0757d5e8 100644 --- a/grails-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/filter/UrlMappingsFilter.java +++ b/grails-plugin-url-mappings/src/main/groovy/org/codehaus/groovy/grails/web/mapping/filter/UrlMappingsFilter.java @@ -54,7 +54,6 @@ import org.codehaus.groovy.grails.web.util.WebUtils; import org.springframework.context.ApplicationContext; import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.request.WebRequest; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.multipart.MultipartException; @@ -172,31 +171,13 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse final String viewName; try { info.configure(webRequest); - String action = info.getActionName() == null ? "" : info.getActionName(); - viewName = info.getViewName(); - if (viewName == null && info.getURI() == null) { - final String controllerName = info.getControllerName(); - String pluginName = info.getPluginName(); - String featureUri = WebUtils.SLASH + urlConverter.toUrlElement(controllerName) + WebUtils.SLASH + urlConverter.toUrlElement(action); - - Object featureId = null; - if(pluginName != null) { - Map featureIdMap = new HashMap(); - featureIdMap.put("uri", featureUri); - featureIdMap.put("pluginName", pluginName); - featureId = featureIdMap; - } else { - featureId = featureUri; - } - GrailsClass controller = application.getArtefactForFeature(ControllerArtefactHandler.TYPE, featureId); - if (controller == null) { - continue; - } - - webRequest.setAttribute(GrailsApplicationAttributes.CONTROLLER_NAME_ATTRIBUTE, controller.getLogicalPropertyName(), WebRequest.SCOPE_REQUEST); - webRequest.setAttribute(GrailsApplicationAttributes.GRAILS_CONTROLLER_CLASS, controller, WebRequest.SCOPE_REQUEST); - webRequest.setAttribute(GrailsApplicationAttributes.GRAILS_CONTROLLER_CLASS_AVAILABLE, Boolean.TRUE, WebRequest.SCOPE_REQUEST); - } + UrlConverter urlConverterToUse = urlConverter; + GrailsApplication grailsApplicationToUse = application; + + GrailsClass controller = WebUtils.getConfiguredControllerForUrlMappingInfo(webRequest, info, urlConverterToUse, grailsApplicationToUse); + + if(controller == null) continue; + } catch (Exception e) { if (e instanceof MultipartException) { @@ -215,7 +196,8 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse request = checkMultipart(request); - if (viewName == null || viewName.endsWith(GSP_SUFFIX) || viewName.endsWith(JSP_SUFFIX)) { + String nameOfview = info.getViewName(); + if (nameOfview == null || nameOfview.endsWith(GSP_SUFFIX) || nameOfview.endsWith(JSP_SUFFIX)) { if (info.isParsingRequest()) { webRequest.informParameterCreationListeners(); } @@ -225,7 +207,7 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse } } else { - if (!renderViewForUrlMappingInfo(request, response, info, viewName)) { + if (!renderViewForUrlMappingInfo(request, response, info, nameOfview)) { dispatched = false; } } diff --git a/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/ErrorHandlingServlet.java b/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/ErrorHandlingServlet.java index 67b8b3deec8..b8ad3442a8c 100644 --- a/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/ErrorHandlingServlet.java +++ b/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/ErrorHandlingServlet.java @@ -23,7 +23,9 @@ import javax.servlet.http.HttpServletResponse; import grails.util.GrailsWebUtil; +import grails.web.UrlConverter; import org.codehaus.groovy.grails.commons.GrailsApplication; +import org.codehaus.groovy.grails.commons.GrailsClass; import org.codehaus.groovy.grails.commons.GrailsClassUtils; import org.codehaus.groovy.grails.exceptions.DefaultStackTraceFilterer; import org.codehaus.groovy.grails.exceptions.StackTraceFilterer; @@ -114,13 +116,14 @@ protected void doDispatch(final HttpServletRequest request, final HttpServletRes if (urlMappingInfo != null) { RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes(); boolean restoreOriginalRequestAttributes = false; + final GrailsWebRequest webRequest; if (requestAttributes instanceof GrailsWebRequest) { - final GrailsWebRequest webRequest = (GrailsWebRequest) requestAttributes; + webRequest = (GrailsWebRequest) requestAttributes; urlMappingInfo.configure(webRequest); } else { restoreOriginalRequestAttributes = true; - GrailsWebRequest webRequest = new GrailsWebRequest(request, response, getServletContext()); + webRequest = new GrailsWebRequest(request, response, getServletContext()); RequestContextHolder.setRequestAttributes(webRequest); urlMappingInfo.configure(webRequest); } @@ -131,9 +134,16 @@ protected void doDispatch(final HttpServletRequest request, final HttpServletRes WrappedResponseHolder.setWrappedResponse(response); String viewName = urlMappingInfo.getViewName(); if (viewName == null || viewName.endsWith(GSP_SUFFIX) || viewName.endsWith(JSP_SUFFIX)) { - WebUtils.forwardRequestForUrlMappingInfo(request, response, urlMappingInfo, Collections.EMPTY_MAP); + GrailsClass controller = WebUtils.getConfiguredControllerForUrlMappingInfo(webRequest, urlMappingInfo, + webRequest.getApplicationContext().getBean(UrlConverter.BEAN_NAME, UrlConverter.class), + webRequest.getAttributes().getGrailsApplication()); + if(controller != null) { + WebUtils.forwardRequestForUrlMappingInfo(request, response, urlMappingInfo, Collections.EMPTY_MAP); + } } else { + + ViewResolver viewResolver = WebUtils.lookupViewResolver(getServletContext()); if (viewResolver != null) { View v; diff --git a/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/util/WebUtils.java b/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/util/WebUtils.java index 9f60b0793f3..fba5bab7971 100644 --- a/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/util/WebUtils.java +++ b/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/util/WebUtils.java @@ -37,9 +37,12 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import grails.web.UrlConverter; import groovy.lang.Binding; import org.apache.commons.lang.StringUtils; +import org.codehaus.groovy.grails.commons.ControllerArtefactHandler; import org.codehaus.groovy.grails.commons.GrailsApplication; +import org.codehaus.groovy.grails.commons.GrailsClass; import org.codehaus.groovy.grails.web.mapping.UrlMappingInfo; import org.codehaus.groovy.grails.web.mapping.UrlMappingsHolder; import org.codehaus.groovy.grails.web.mime.MimeType; @@ -55,6 +58,7 @@ import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.WebRequest; import org.springframework.web.context.request.WebRequestInterceptor; import org.springframework.web.context.support.WebApplicationContextUtils; import org.springframework.web.servlet.HandlerInterceptor; @@ -693,4 +697,36 @@ public static String getForwardURI(HttpServletRequest request) { if (StringUtils.isBlank(result)) result = request.getRequestURI(); return result; } + + public static GrailsClass getConfiguredControllerForUrlMappingInfo(GrailsWebRequest webRequest, UrlMappingInfo info, UrlConverter urlConverterToUse, GrailsApplication grailsApplicationToUse) { + String viewName; + String action = info.getActionName() == null ? "" : info.getActionName(); + viewName = info.getViewName(); + + GrailsClass controller = null; + if (viewName == null && info.getURI() == null) { + final String controllerName = info.getControllerName(); + String pluginName = info.getPluginName(); + String featureUri = SLASH + urlConverterToUse.toUrlElement(controllerName) + SLASH + urlConverterToUse.toUrlElement(action); + + Object featureId; + if(pluginName != null) { + Map featureIdMap = new HashMap(); + featureIdMap.put("uri", featureUri); + featureIdMap.put("pluginName", pluginName); + featureId = featureIdMap; + } else { + featureId = featureUri; + } + controller = grailsApplicationToUse.getArtefactForFeature(ControllerArtefactHandler.TYPE, featureId); + if (controller != null) { + + webRequest.setAttribute(GrailsApplicationAttributes.CONTROLLER_NAME_ATTRIBUTE, controller.getLogicalPropertyName(), WebRequest.SCOPE_REQUEST); + webRequest.setAttribute(GrailsApplicationAttributes.GRAILS_CONTROLLER_CLASS, controller, WebRequest.SCOPE_REQUEST); + webRequest.setAttribute(GrailsApplicationAttributes.GRAILS_CONTROLLER_CLASS_AVAILABLE, Boolean.TRUE, WebRequest.SCOPE_REQUEST); + } + + } + return controller; + } }