jdaugherty commented on code in PR #13863:
URL: https://github.com/apache/grails-core/pull/13863#discussion_r3552114469
##########
grails-doc/src/en/guide/i18n/changingLocales.adoc:
##########
@@ -28,7 +28,19 @@ Grails will automatically switch the user's locale and
subsequent requests will
By default, Grails uses
{springapi}org/springframework/web/servlet/i18n/SessionLocaleResolver.html[SessionLocaleResolver]
as the `localeResolver` bean.
-You can change the default locale easily:
+You can select a different resolver strategy with the
`grails.i18n.localeResolver` configuration property, without declaring a bean:
+
+[source,yaml]
+.grails-app/conf/application.yml
+----
+grails:
+ i18n:
+ localeResolver: acceptHeader # session (default), cookie, acceptHeader
or fixed
+----
+
+`session` and `cookie` are mutable, so the `?lang=` switch works with them.
`acceptHeader` (the locale follows the incoming `Accept-Language` header) and
`fixed` are read-only, so the `?lang=` switch has no effect and is silently
ignored. The `fixed` resolver uses `grails.i18n.default.locale`, falling back
to the JVM default locale.
Review Comment:
So the url will override the header now with your changes? or vice versa?
##########
grails-core/src/main/groovy/grails/config/Settings.groovy:
##########
@@ -270,6 +270,13 @@ interface Settings {
*/
String WEB_REMOVE_DEFAULT_VIEW_RESOLVER_BEAN =
'grails.web.removeDefaultViewResolverBean'
+ /**
+ * Whether to remove Spring Boot's welcome-page handler mappings so
Grails' own URL mappings
+ * own the root path ('/') rather than a static {@code index.html} being
served for it.
+ * Defaults to true
+ */
+ String WEB_REMOVE_WELCOME_PAGE_MAPPING =
'grails.web.removeWelcomePageMapping'
Review Comment:
the spring-config-metadata json file needs updated for this new setting &
any others that were added.
##########
grails-test-examples/enable-mvc-check/README.md:
##########
@@ -0,0 +1,62 @@
+<!--
+SPDX-License-Identifier: Apache-2.0
+
+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
+
+ https://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.
+-->
+
+# enable-mvc-check
+
+A dedicated Grails functional test application that pins down the behavior of
Review Comment:
We should probably remove this file now. It was just here to help you
understand the test.
##########
grails-web-common/src/test/groovy/grails/web/servlet/mvc/GrailsParameterMapTests.groovy:
##########
@@ -92,82 +97,47 @@ class GrailsParameterMapTests {
}
@Test
- void testParseRequestBodyForPutRequest() {
- def request = new MockHttpServletRequest()
- request.content = 'foo=bar&one=two'.bytes
- request.method = 'PUT'
- request.contentType = "application/x-www-form-urlencoded"
-
- def params = new GrailsParameterMap(request)
+ void testFormEncodedPutBodyIsExposedAsParams() {
+ def params = new GrailsParameterMap(formFilteredRequest('PUT',
'foo=bar&one=two', 'application/x-www-form-urlencoded'))
assert 'bar' == params.foo
assert 'two' == params.one
-
- params = new GrailsParameterMap(request)
- assert params.foo == null // should be null, request can't be parsed
twice
-
- request = new MockHttpServletRequest()
- request.method = 'PUT'
- request.content = 'foo='.bytes
- request.contentType = "application/x-www-form-urlencoded"
- request.removeAttribute(GrailsParameterMap.REQUEST_BODY_PARSED)
-
- params = new GrailsParameterMap(request)
-
- assert '' == params.foo
}
@Test
- void testParseRequestBodyForPutRequestWithCharset() {
- def request = new MockHttpServletRequest()
- request.content = 'foo=bar&one=two'.bytes
- request.method = 'PUT'
- request.contentType = "application/x-www-form-urlencoded;
charset=UTF-8"
-
- def params = new GrailsParameterMap(request)
+ void testFormEncodedPutBodyWithCharsetIsExposedAsParams() {
+ def params = new GrailsParameterMap(formFilteredRequest('PUT',
'foo=bar&one=two', 'application/x-www-form-urlencoded; charset=UTF-8'))
assert 'bar' == params.foo
assert 'two' == params.one
-
- params = new GrailsParameterMap(request)
- assert params.foo == null // should be null, request can't be parsed
twice
-
- request = new MockHttpServletRequest()
- request.method = 'PUT'
- request.contentType = "application/x-www-form-urlencoded;
charset=UTF-8"
- request.content = 'foo='.bytes
- request.removeAttribute(GrailsParameterMap.REQUEST_BODY_PARSED)
-
- params = new GrailsParameterMap(request)
-
- assert '' == params.foo
}
@Test
- void testParseRequestBodyForPatchRequest() {
- def request = new MockHttpServletRequest()
- request.content = 'foo=bar&one=two'.bytes
- request.method = 'PATCH'
- request.contentType = "application/x-www-form-urlencoded"
-
- def params = new GrailsParameterMap(request)
+ void testFormEncodedPatchBodyIsExposedAsParams() {
+ def params = new GrailsParameterMap(formFilteredRequest('PATCH',
'foo=bar&one=two', 'application/x-www-form-urlencoded'))
assert 'bar' == params.foo
assert 'two' == params.one
+ }
- params = new GrailsParameterMap(request)
- assert params.foo == null // should be null, request can't be parsed
twice
-
- request = new MockHttpServletRequest()
Review Comment:
Since you're relying on the form filter now, you should add a functioanl
test to cover these removed scenarios
##########
grails-doc/src/en/guide/upgrading/upgrading80x.adoc:
##########
@@ -1396,6 +1396,31 @@ Grails 8 registers its request-binding filter as a
`RequestContextFilter` bean s
This is handled internally and requires no configuration changes.
Applications that defined their own `GrailsWebRequestFilter` bean, or their
own `grailsWebRequestFilter` filter-registration bean, continue to override the
Grails-provided ones.
+===== 31.3 Other Boot MVC features now active
+
+Because Boot's `WebMvcAutoConfiguration` is now active, a handful of its
features that `@EnableWebMvc` previously suppressed take effect for Grails
servlet web applications.
+None require action for a typical application, but they are behavioral
differences worth knowing about when you upgrade:
+
+* **Form-content filter for `PUT` / `PATCH` / `DELETE`.** A
`FormContentFilter` parses `application/x-www-form-urlencoded` bodies of `PUT`,
`PATCH` and `DELETE` requests so their fields are visible through the standard
`request.getParameter(...)` API (and therefore in `params`). Boot's
`OrderedFormContentFilter` provides it for a default application; for an
application that declares `@EnableWebMvc` — where Boot's MVC auto-configuration
backs off — Grails contributes an equivalent filter itself, so form parameters
behave the same either way. In Grails 7 only `PUT` and `PATCH` bodies were
parsed (by `GrailsParameterMap`) and `DELETE` was not; all three are now
handled uniformly by the filter. It is enabled by default via
`spring.mvc.formcontent.filter.enabled`; setting that to `false` disables `PUT`
/ `PATCH` / `DELETE` form-parameter parsing entirely. An application that reads
those bodies itself can disable it:
++
+[source,yaml]
+.application.yml
+----
+spring:
+ mvc:
+ formcontent:
+ filter:
+ enabled: false
+----
+
+* **`spring.mvc.*` and `spring.web.*` properties now apply.** Properties such
as `spring.web.locale`, `spring.mvc.format.date` / `time` / `date-time`, and
`spring.web.resources.*` were inert before and now take effect. Review any of
these you may have set inadvertently (for example copied from Boot
documentation).
+
+* **Boot static-resource handling and welcome page.** Boot adds a catch-all
resource handler (`classpath:/META-INF/resources/`, `/resources/`, `/static/`,
`/public/`) and a `WelcomePageHandlerMapping` for a static `index.html`,
alongside Grails' own resource handling. A request that previously fell through
to Grails' URL-mapping error handling may now be served as a static resource or
welcome page — worth checking in applications with catch-all URL mappings or
custom 404 handling. Set `spring.web.resources.add-mappings: false` to disable
the static-resource handler.
Review Comment:
This file is out of date.
##########
grails-controllers/src/main/groovy/org/grails/plugins/web/controllers/GrailsFormContentFilterAutoConfiguration.java:
##########
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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
+ *
+ * https://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.plugins.web.controllers;
+
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import
org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
+import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import
org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.servlet.filter.OrderedFormContentFilter;
+import org.springframework.boot.webmvc.autoconfigure.WebMvcAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.web.filter.FormContentFilter;
+
+/**
+ * Guarantees a {@link FormContentFilter} for every Grails servlet web
application, so form-encoded
+ * {@code PUT}, {@code PATCH} and {@code DELETE} bodies are parsed into
request parameters and are
Review Comment:
The part I did not understand was this is supposed to only apply for
`application/x-www-form-urlencoded` request bodies, so I am ok with the
changes. But we should update the documentation so this is clear.
##########
grails-web-common/src/test/groovy/grails/web/servlet/mvc/GrailsParameterMapTests.groovy:
##########
@@ -92,82 +97,47 @@ class GrailsParameterMapTests {
}
@Test
- void testParseRequestBodyForPutRequest() {
- def request = new MockHttpServletRequest()
- request.content = 'foo=bar&one=two'.bytes
- request.method = 'PUT'
- request.contentType = "application/x-www-form-urlencoded"
-
- def params = new GrailsParameterMap(request)
+ void testFormEncodedPutBodyIsExposedAsParams() {
+ def params = new GrailsParameterMap(formFilteredRequest('PUT',
'foo=bar&one=two', 'application/x-www-form-urlencoded'))
assert 'bar' == params.foo
assert 'two' == params.one
-
- params = new GrailsParameterMap(request)
- assert params.foo == null // should be null, request can't be parsed
twice
-
- request = new MockHttpServletRequest()
- request.method = 'PUT'
- request.content = 'foo='.bytes
- request.contentType = "application/x-www-form-urlencoded"
- request.removeAttribute(GrailsParameterMap.REQUEST_BODY_PARSED)
-
- params = new GrailsParameterMap(request)
-
- assert '' == params.foo
}
@Test
- void testParseRequestBodyForPutRequestWithCharset() {
- def request = new MockHttpServletRequest()
- request.content = 'foo=bar&one=two'.bytes
- request.method = 'PUT'
- request.contentType = "application/x-www-form-urlencoded;
charset=UTF-8"
-
- def params = new GrailsParameterMap(request)
+ void testFormEncodedPutBodyWithCharsetIsExposedAsParams() {
+ def params = new GrailsParameterMap(formFilteredRequest('PUT',
'foo=bar&one=two', 'application/x-www-form-urlencoded; charset=UTF-8'))
assert 'bar' == params.foo
assert 'two' == params.one
-
- params = new GrailsParameterMap(request)
- assert params.foo == null // should be null, request can't be parsed
twice
-
- request = new MockHttpServletRequest()
- request.method = 'PUT'
- request.contentType = "application/x-www-form-urlencoded;
charset=UTF-8"
- request.content = 'foo='.bytes
- request.removeAttribute(GrailsParameterMap.REQUEST_BODY_PARSED)
Review Comment:
Since you're relying on the form filter now, you should add a functioanl
test to cover these removed scenarios
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]