-
Notifications
You must be signed in to change notification settings - Fork 950
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '7.0.x' into renovate/jackson.version
- Loading branch information
Showing
32 changed files
with
651 additions
and
365 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Common 7.0 Upgrade Gotchas - DRAFT - | ||
|
||
Experienced while upgrading modules for Grails 7 | ||
|
||
- h2 2.x is stricter about reserved words | ||
- https://github.com/grails/gorm-hibernate5/pull/910/commits/c8de45df204966ccc228b46b94beeb2142ae0f59 | ||
- [GROOVY-10621](https://issues.apache.org/jira/browse/GROOVY-10621) | ||
- Primitive booleans will no longer generate the form of isProperty & getProperty. They will only generate isProperty() | ||
- Jar artifacts produced by Grails Plugins will no longer have the suffix `-plain` | ||
- https://github.com/grails/grails-gradle-plugin/pull/347 | ||
- [GROOVY-5169](https://issues.apache.org/jira/browse/GROOVY-5169) [GROOVY-10449](https://issues.apache.org/jira/browse/GROOVY-10449) | ||
- Fields with a public modifier were not returned with MetaClassImpl#getProperties() in groovy 3, but are now. | ||
|
||
## NOTE: This document is a draft and the explanations are only highlights and will be expanded further prior to release of 7.0. | ||
|
||
### Cool New Features | ||
- You can now @Scaffold Controllers and Services and virtually eliminate any boiler plate code. | ||
- Hello Exterminator, Good by bugs! Lot's of things started working... and working well! For instance, use of controller namespaces now work seemlessly. | ||
- Bootstrap 5.3.3 support. Saffolding and Fields tags now optionally support boostrap classes. | ||
- Priortization of AutoConfiguration over bean overriding. | ||
- Lightweight, Removal of numerous dependencies. | ||
- grails-bom overhaul for keeping depedencies up to date and in sync. | ||
- g:form now automatically provides csrf protection when Spring Security CSRF is enabled. | ||
- Massive decoupling of dependencies and cleanup between modules. SiteMesh dependencies are no longer compiled into controllers fused between numerous modules. SiteMesh isn't even required to use Grails! | ||
- SiteMesh ahs been upgrade to SiteMesh 3! | ||
- Completely up to date modern stack that has been optimized for easier future transitions. | ||
- GSP can now be used OUTSIDE of Grails! see grails-boot | ||
- Works with Spring Security 6 out of the box. No plugin needed! | ||
- Tested and works with Java [17-23](https://github.com/grails/grails-core/blob/0549617f27aeb5b90b64797fa4147dde40fc9c86/.github/workflows/gradle.yml#L18) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
182 changes: 182 additions & 0 deletions
182
...lers/src/main/groovy/org/grails/plugins/web/controllers/ControllersAutoConfiguration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
package org.grails.plugins.web.controllers; | ||
|
||
import grails.config.Settings; | ||
import grails.core.GrailsApplication; | ||
import jakarta.servlet.DispatcherType; | ||
import jakarta.servlet.Filter; | ||
import jakarta.servlet.MultipartConfigElement; | ||
import org.grails.web.config.http.GrailsFilters; | ||
import org.grails.web.filters.HiddenHttpMethodFilter; | ||
import org.grails.web.servlet.mvc.GrailsDispatcherServlet; | ||
import org.grails.web.servlet.mvc.GrailsWebRequestFilter; | ||
import org.springframework.beans.factory.annotation.Value; | ||
import org.springframework.boot.autoconfigure.AutoConfiguration; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | ||
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; | ||
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletRegistrationBean; | ||
import org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration; | ||
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; | ||
import org.springframework.boot.web.servlet.FilterRegistrationBean; | ||
import org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter; | ||
import org.springframework.context.ApplicationContext; | ||
import org.springframework.context.annotation.Bean; | ||
import org.springframework.util.ClassUtils; | ||
import org.springframework.web.filter.CharacterEncodingFilter; | ||
import org.springframework.web.servlet.DispatcherServlet; | ||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
import java.util.EnumSet; | ||
|
||
@AutoConfiguration(before = { HttpEncodingAutoConfiguration.class, WebMvcAutoConfiguration.class }) | ||
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET) | ||
public class ControllersAutoConfiguration { | ||
|
||
@Value("${" + Settings.FILTER_ENCODING + ":utf-8}") | ||
private String filtersEncoding; | ||
|
||
@Value("${" + Settings.FILTER_FORCE_ENCODING + ":false}") | ||
private boolean filtersForceEncoding; | ||
|
||
@Value("${" + Settings.RESOURCES_CACHE_PERIOD + ":0}") | ||
private int resourcesCachePeriod; | ||
|
||
@Value("${" + Settings.RESOURCES_ENABLED + ":true}") | ||
private boolean resourcesEnabled; | ||
|
||
@Value("${" + Settings.RESOURCES_PATTERN + ":" + Settings.DEFAULT_RESOURCE_PATTERN + "}") | ||
private String resourcesPattern; | ||
|
||
@Value("${" + Settings.CONTROLLERS_UPLOAD_LOCATION + ":#{null}}") | ||
private String uploadTmpDir; | ||
|
||
@Value("${" + Settings.CONTROLLERS_UPLOAD_MAX_FILE_SIZE + ":128000}") | ||
private long maxFileSize; | ||
|
||
@Value("${" + Settings.CONTROLLERS_UPLOAD_MAX_REQUEST_SIZE + ":128000}") | ||
private long maxRequestSize; | ||
|
||
@Value("${" + Settings.CONTROLLERS_UPLOAD_FILE_SIZE_THRESHOLD + ":0}") | ||
private int fileSizeThreshold; | ||
|
||
@Value("${" + Settings.WEB_SERVLET_PATH + ":#{null}}") | ||
String grailsServletPath; | ||
|
||
@Bean | ||
@ConditionalOnMissingBean(CharacterEncodingFilter.class) | ||
public CharacterEncodingFilter characterEncodingFilter() { | ||
FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>(); | ||
OrderedCharacterEncodingFilter characterEncodingFilter = new OrderedCharacterEncodingFilter(); | ||
characterEncodingFilter.setEncoding(filtersEncoding); | ||
characterEncodingFilter.setForceEncoding(filtersForceEncoding); | ||
characterEncodingFilter.setOrder(GrailsFilters.CHARACTER_ENCODING_FILTER.getOrder()); | ||
return characterEncodingFilter; | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class) | ||
public FilterRegistrationBean<Filter> hiddenHttpMethodFilter() { | ||
FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>(); | ||
registrationBean.setFilter(new HiddenHttpMethodFilter()); | ||
registrationBean.addUrlPatterns(Settings.DEFAULT_WEB_SERVLET_PATH); | ||
registrationBean.setOrder(GrailsFilters.HIDDEN_HTTP_METHOD_FILTER.getOrder()); | ||
return registrationBean; | ||
} | ||
|
||
@Bean | ||
@ConditionalOnMissingBean(GrailsWebRequestFilter.class) | ||
public FilterRegistrationBean<Filter> grailsWebRequestFilter(ApplicationContext applicationContext) { | ||
FilterRegistrationBean<Filter> registrationBean = new FilterRegistrationBean<>(); | ||
GrailsWebRequestFilter grailsWebRequestFilter = new GrailsWebRequestFilter(); | ||
grailsWebRequestFilter.setApplicationContext(applicationContext); | ||
registrationBean.setFilter(grailsWebRequestFilter); | ||
registrationBean.setDispatcherTypes(EnumSet.of( | ||
DispatcherType.FORWARD, | ||
DispatcherType.INCLUDE, | ||
DispatcherType.REQUEST) | ||
); | ||
registrationBean.addUrlPatterns(Settings.DEFAULT_WEB_SERVLET_PATH); | ||
registrationBean.setOrder(GrailsFilters.GRAILS_WEB_REQUEST_FILTER.getOrder()); | ||
return registrationBean; | ||
} | ||
|
||
@Bean | ||
public MultipartConfigElement multipartConfigElement() { | ||
if (uploadTmpDir == null) { | ||
uploadTmpDir = System.getProperty("java.io.tmpdir"); | ||
} | ||
return new MultipartConfigElement(uploadTmpDir, maxFileSize, maxRequestSize, fileSizeThreshold); | ||
} | ||
|
||
@Bean | ||
public DispatcherServlet dispatcherServlet() { | ||
return new GrailsDispatcherServlet(); | ||
} | ||
|
||
@Bean | ||
public DispatcherServletRegistrationBean dispatcherServletRegistration(GrailsApplication application, DispatcherServlet dispatcherServlet, MultipartConfigElement multipartConfigElement) { | ||
if (grailsServletPath == null) { | ||
boolean isTomcat = ClassUtils.isPresent("org.apache.catalina.startup.Tomcat", application.getClassLoader()); | ||
grailsServletPath = isTomcat ? Settings.DEFAULT_TOMCAT_SERVLET_PATH : Settings.DEFAULT_WEB_SERVLET_PATH; | ||
} | ||
DispatcherServletRegistrationBean dispatcherServletRegistration = new DispatcherServletRegistrationBean(dispatcherServlet, grailsServletPath); | ||
dispatcherServletRegistration.setLoadOnStartup(2); | ||
dispatcherServletRegistration.setAsyncSupported(true); | ||
dispatcherServletRegistration.setMultipartConfig(multipartConfigElement); | ||
return dispatcherServletRegistration; | ||
} | ||
|
||
@Bean | ||
public GrailsWebMvcConfigurer webMvcConfig() { | ||
return new GrailsWebMvcConfigurer(resourcesCachePeriod, resourcesEnabled, resourcesPattern); | ||
} | ||
|
||
static class GrailsWebMvcConfigurer implements WebMvcConfigurer { | ||
|
||
private static final String[] SERVLET_RESOURCE_LOCATIONS = new String[] { "/" }; | ||
|
||
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[] { | ||
"classpath:/META-INF/resources/", "classpath:/resources/", | ||
"classpath:/static/", "classpath:/public/" | ||
}; | ||
|
||
private static final String[] RESOURCE_LOCATIONS; | ||
|
||
static { | ||
RESOURCE_LOCATIONS = new String[CLASSPATH_RESOURCE_LOCATIONS.length | ||
+ SERVLET_RESOURCE_LOCATIONS.length]; | ||
System.arraycopy(SERVLET_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS, 0, | ||
SERVLET_RESOURCE_LOCATIONS.length); | ||
System.arraycopy(CLASSPATH_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS, | ||
SERVLET_RESOURCE_LOCATIONS.length, CLASSPATH_RESOURCE_LOCATIONS.length); | ||
} | ||
|
||
boolean addMappings; | ||
Integer cachePeriod; | ||
String resourcesPattern; | ||
|
||
GrailsWebMvcConfigurer(Integer cachePeriod, Boolean addMappings, String resourcesPattern) { | ||
this.addMappings = addMappings; | ||
this.cachePeriod = cachePeriod; | ||
this.resourcesPattern = resourcesPattern; | ||
} | ||
|
||
@Override | ||
public void addResourceHandlers(ResourceHandlerRegistry registry) { | ||
if (!addMappings) { | ||
return; | ||
} | ||
|
||
if (!registry.hasMappingForPattern("/webjars/**")) { | ||
registry.addResourceHandler("/webjars/**") | ||
.addResourceLocations("classpath:/META-INF/resources/webjars/") | ||
.setCachePeriod(cachePeriod); | ||
} | ||
if (!registry.hasMappingForPattern(resourcesPattern)) { | ||
registry.addResourceHandler(resourcesPattern) | ||
.addResourceLocations(RESOURCE_LOCATIONS) | ||
.setCachePeriod(cachePeriod); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.