8.x Add Class-typed getAttribute reads for session, request and servletContext#15732
Merged
codeconsole merged 6 commits intoJun 16, 2026
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 8.0.x #15732 +/- ##
==================================================
+ Coverage 48.3255% 48.4425% +0.1169%
- Complexity 15216 15284 +68
==================================================
Files 1875 1875
Lines 85818 85873 +55
Branches 14969 14978 +9
==================================================
+ Hits 41472 41599 +127
+ Misses 37975 37863 -112
- Partials 6371 6411 +40
🚀 New features to boost your workflow:
|
a5f6083 to
b1fc911
Compare
|
Using grails-web-core/src/main/groovy/org/grails/web/servlet/HttpServletRequestExtension.groovy |
sbglasius
approved these changes
Jun 15, 2026
…ubclass proxies (the CGLIB/Hibernate mechanism)
This comment has been minimized.
This comment has been minimized.
jdaugherty
reviewed
Jun 16, 2026
jdaugherty
approved these changes
Jun 16, 2026
…sm) rather than a JDK proxy + plain subclass
7db9587 to
145bc47
Compare
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-up to #15715. The named converters (
string,int,boolean, …) cover scalar attribute values, but attributes frequently hold richer objects — a security principal, a domain instance, a CSRF token — where today the only statically-compilable read is a cast at every call site:This adds a
Class-typed overload ofgetAttribute(plus a default-value variant) tosession,requestandservletContext:The generic signature (
static <T> T getAttribute(holder, String name, Class<T> type)) lets the static compiler infer the return type from the class literal, so the read compiles under@CompileStatic/@GrailsCompileStaticwith no cast.Design
null(so the default-value overload also applies on a type mismatch). NoTypeConvertersdelegation — the named converters remain the coercing API, theClassoverload is the type-safe retrieval API. Two simple contracts instead of one mixed one.getAttributerather than introducing a new verb. Mirrorsgrails.config.Config.getProperty(String key, Class<T> targetType, T defaultValue)(and Spring'sEnvironment.getProperty(key, type, default)), and shows up in IDE completion right next to the rawgetAttribute(String).flashis skipped — it is aMap, and Groovy's DGMMap.get(key, default)(which inserts the default) makes a two-arg sibling on flash a semantic trap.paramsis skipped — its values are Strings, where a non-coercing typed read is not useful.Tests & docs
HttpSessionExtensionSpec,HttpServletRequestExtensionSpec,ServletContextExtensionSpeceach gain two features: instance-match / supertype-match / absent / wrong-type-reads-as-null semantics, default-value behavior, and a@CompileStaticstatic-resolution guard (the guard fails test compilation without the new extension methods).:grails-web-core:testpasses in full.