Skip to content

Commit

Permalink
Ensure custom 404 pages work
Browse files Browse the repository at this point in the history
  • Loading branch information
graemerocher committed Mar 9, 2015
1 parent 6539bb1 commit 3e8f9af
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import grails.web.mapping.UrlMappingsHolder
import org.grails.web.mapping.UrlMappingsHolderFactoryBean
import org.grails.web.mapping.mvc.UrlMappingsHandlerMapping
import org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter
import org.grails.web.mapping.servlet.UrlMappingsErrorPageCustomizer
import org.springframework.aop.framework.ProxyFactoryBean
import org.springframework.aop.target.HotSwappableTargetSource
import org.springframework.context.ApplicationContext
Expand Down Expand Up @@ -69,6 +70,7 @@ class UrlMappingsGrailsPlugin extends Plugin {

urlMappingsHandlerMapping(UrlMappingsHandlerMapping, ref("grailsUrlMappingsHolder"))
urlMappingsInfoHandlerAdapter(UrlMappingsInfoHandlerAdapter)
urlMappingsErrorPageCustomizer(UrlMappingsErrorPageCustomizer)
grailsLinkGenerator(cacheUrls ? CachingLinkGenerator : DefaultLinkGenerator, serverURL)

if (Environment.isDevelopmentMode() || Environment.current.isReloadEnabled()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,30 @@
*/
package org.grails.web.mapping;

import grails.config.Config;
import grails.core.GrailsApplication;
import grails.core.GrailsClass;
import grails.core.GrailsControllerClass;
import grails.core.GrailsUrlMappingsClass;
import grails.web.mapping.UrlMappings;
import groovy.lang.Script;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;

import grails.core.events.ArtefactAdditionEvent;
import grails.core.support.GrailsApplicationAware;
import grails.plugins.GrailsPluginManager;
import grails.plugins.PluginManagerAware;
import grails.core.support.GrailsApplicationAware;
import grails.web.mapping.UrlMappings;
import groovy.lang.Script;
import org.grails.core.artefact.UrlMappingsArtefactHandler;
import org.grails.web.mapping.mvc.GrailsControllerUrlMappings;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;

import java.util.ArrayList;
import java.util.List;

/**
* Constructs the UrlMappingsHolder from the registered UrlMappings class within a GrailsApplication.
Expand Down Expand Up @@ -103,12 +102,12 @@ public void afterPropertiesSet() throws Exception {

DefaultUrlMappingsHolder defaultUrlMappingsHolder = new DefaultUrlMappingsHolder(urlMappings, excludePatterns, true);

Map flatConfig = grailsApplication.getFlatConfig();
Integer cacheSize = mapGetInteger(flatConfig, URL_MAPPING_CACHE_MAX_SIZE);
Config config = grailsApplication.getConfig();
Integer cacheSize = config.getProperty(URL_MAPPING_CACHE_MAX_SIZE, Integer.class, null);
if (cacheSize != null) {
defaultUrlMappingsHolder.setMaxWeightedCacheCapacity(cacheSize);
}
Integer urlCreatorCacheSize = mapGetInteger(flatConfig, URL_CREATOR_CACHE_MAX_SIZE);
Integer urlCreatorCacheSize = config.getProperty(URL_CREATOR_CACHE_MAX_SIZE, Integer.class, null);
if (urlCreatorCacheSize != null) {
defaultUrlMappingsHolder.setUrlCreatorMaxWeightedCacheCapacity(urlCreatorCacheSize);
}
Expand All @@ -127,25 +126,11 @@ public void onApplicationEvent(ArtefactAdditionEvent event) {
urlMappingsHolder= grailsControllerUrlMappings;
}

// this should possibly be somewhere in utility classes , MapUtils.getInteger doesn't handle GStrings/CharSequence
private static Integer mapGetInteger(Map map, String key) {
Object value = map.get(key);
if (value == null) {
return null;
}
if (value instanceof Integer) {
return (Integer)value;
}
return value instanceof Number ? ((Number)value).intValue() : Integer.valueOf(String.valueOf(value));
}

public void setGrailsApplication(GrailsApplication grailsApplication) {
this.grailsApplication = grailsApplication;
}

public void setServletContext(ServletContext servletContext) {
// not used
}

public void setPluginManager(GrailsPluginManager pluginManager) {
this.pluginManager = pluginManager;
Expand All @@ -169,8 +154,10 @@ public void setPluginManager(GrailsPluginManager pluginManager) {
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
setGrailsApplication(applicationContext.getBean( GrailsApplication.APPLICATION_ID, GrailsApplication.class) );
setServletContext(applicationContext instanceof WebApplicationContext ? ((WebApplicationContext) applicationContext).getServletContext() : null);
setGrailsApplication(applicationContext.getBean(GrailsApplication.APPLICATION_ID, GrailsApplication.class));
setPluginManager( applicationContext.containsBean(GrailsPluginManager.BEAN_NAME) ? applicationContext.getBean(GrailsPluginManager.BEAN_NAME, GrailsPluginManager.class) : null);
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2015 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.grails.web.mapping.servlet

import grails.web.mapping.UrlMapping
import grails.web.mapping.UrlMappings
import groovy.transform.CompileStatic
import org.grails.web.mapping.ResponseCodeMappingData
import org.grails.web.mapping.ResponseCodeUrlMapping
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer
import org.springframework.boot.context.embedded.ErrorPage
import org.springframework.http.HttpStatus


/**
* Customizes the error pages based on UrlMappings
*
* @author Graeme Rocher
* @since 3.0
*/
@CompileStatic
class UrlMappingsErrorPageCustomizer implements EmbeddedServletContainerCustomizer{

@Autowired
UrlMappings urlMappings

@Override
void customize(ConfigurableEmbeddedServletContainer container) {
final UrlMapping[] allMappings = urlMappings.getUrlMappings()

List<ErrorPage> errorPages = []
for (UrlMapping urlMapping : allMappings) {
if(urlMapping instanceof ResponseCodeUrlMapping) {
ResponseCodeUrlMapping responseCodeUrlMapping = (ResponseCodeUrlMapping) urlMapping;
ResponseCodeMappingData data = (ResponseCodeMappingData) responseCodeUrlMapping.urlData
final int code = data.responseCode
errorPages << new ErrorPage(HttpStatus.valueOf(code), "/error")

}
}
container.addErrorPages(errorPages as ErrorPage[])
}
}

0 comments on commit 3e8f9af

Please sign in to comment.