codeconsole opened a new pull request, #15715:
URL: https://github.com/apache/grails-core/pull/15715
## Summary
Adds null-safe, typed conversion methods to the `session`, `request`,
`flash` and `servletContext` objects, mirroring the existing `params.int('id',
1)` API. Also adds a missing `string`/`getString` converter to
`TypeConvertingMap` itself.
```groovy
Integer page = request.int('page', 1)
String tz = session.string('userTimeZoneId', 'America/Los_Angeles')
Boolean active = session.boolean('active', false)
String notice = flash.string('notice')
int uploads = servletContext.int('maxUploads', 10)
```
The full converter set is available — `string`, `byte`, `char`, `short`,
`int`, `long`, `double`, `float`, `boolean`, `list`, `date` — each with an
optional default-value overload, exactly as on `params`.
## Motivation
Under `@CompileStatic` / `@GrailsCompileStatic`, dynamic attribute access
such as `session.userTimeZoneId` does not compile, and the explicit form
requires a cast at every call site:
```groovy
String tz = (session.getAttribute('userTimeZoneId') as String) ?:
'America/Los_Angeles'
```
These converters give the same null-safe, typed, default-aware ergonomics as
`params`, and they compile under static compilation. They are equally useful in
dynamic code for the parsing/defaulting behaviour (just like `params.int(...)`).
## Design
- Conversion logic is extracted into an internal helper,
`org.grails.util.TypeConverters`, which converts a raw `Object` value to the
target type (with an optional default). Both `TypeConvertingMap`'s instance
`getX` methods and the new attribute extensions delegate to it, so the logic
lives in a single place and no new conversion methods are added to the public
`TypeConvertingMap` API.
- The extensions call the converters directly on the attribute value,
avoiding any per-access allocation.
- The instance `getX(name, default)` semantics are preserved, so `params`
behaviour is unchanged (verified by `GrailsParameterMapBindingSpec`).
- The one deliberate exception is the `boolean` default: "is the value
present" differs by holder (map `containsKey` vs. attribute set), which cannot
be expressed from a value alone, so it stays per-site and is documented inline.
- The `string` converter returns the first element when the attribute is an
array, mirroring the single-value semantics of the other converters; use `list`
for all values.
## Tests & docs
- Unit tests for the internal converters (incl. default-value coercion) and
for `getString`/`string`.
- A Spock spec per holder (`HttpSessionExtensionSpec`,
`HttpServletRequestExtensionSpec`, `ServletContextExtensionSpec`,
`FlashScopeExtensionSpec`) covering conversion, null-safety, defaults, and a
`@CompileStatic` static-resolution guard.
- `GrailsParameterMapBindingSpec` passes unchanged (regression guard for the
core refactor).
- New "Type Conversion of Attributes" section in the controllers guide.
--
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]