codeconsole commented on code in PR #15732:
URL: https://github.com/apache/grails-core/pull/15732#discussion_r3408456657


##########
grails-web-core/src/main/groovy/org/grails/web/servlet/HttpServletRequestExtension.groovy:
##########
@@ -251,4 +252,26 @@ class HttpServletRequestExtension {
     static Date date(HttpServletRequest request, String name, 
Collection<String> formats) {
         TypeConverters.toDate(request.getAttribute(name), formats)
     }
+    /**
+     * Null-safe, typed read of an attribute. Returns the attribute when it is 
an
+     * instance of {@code type}; otherwise {@code null}. No coercion is 
attempted —
+     * use the named converters ({@code string}, {@code int}, ...) for type 
conversion.
+     */
+    static <T> T getAttribute(HttpServletRequest request, String name, 
Class<T> type) {
+        if (type == null) {
+            throw new IllegalArgumentException('type must not be null - use 
getAttribute(name) for an untyped read')
+        }
+        Object value = request.getAttribute(name)
+        Class<T> resolvedType = (Class<T>) 
ClassUtils.resolvePrimitiveIfNecessary(type)
+        resolvedType.isInstance(value) ? resolvedType.cast(value) : null

Review Comment:
   `type.isInstance(value)` is true when `value` *is-a* `type`, including when 
`type` is a supertype/interface of the value's concrete class. That's the 
primary use case for these reads:
   
   ```groovy
   // stored value is a concrete DefaultCsrfToken; caller requests the interface
   CsrfToken token = request.getAttribute('_csrf', CsrfToken)
   ```
   
   `value.class.isAssignableFrom(type)` inverts the relationship — it asks "is 
`type` the same as or a *subclass* of the value's class", i.e. 
`DefaultCsrfToken.isAssignableFrom(CsrfToken)`, which is `false` — so it would 
return `null` for every request-by-interface. The supertype-match case is 
covered by the spec (`getAttribute('principal', CharSequence)` for a 
`StringBuilder` value).
   
   The `isAssignableFrom` equivalent of the current check would be 
`type.isAssignableFrom(value.class)` (with a null guard); 
`type.isInstance(value)` just expresses that directly and is null-safe.
   



-- 
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]

Reply via email to