Merge branch '6.2.x'

This commit is contained in:
rstoyanchev
2025-05-28 11:10:06 +01:00
4 changed files with 37 additions and 13 deletions

View File

@@ -19,7 +19,7 @@ Java::
private String name;
private MultipartFile file;
private FilePart file;
// ...
@@ -42,7 +42,7 @@ Kotlin::
----
class MyForm(
val name: String,
val file: MultipartFile)
val file: FilePart)
@Controller
class FileUploadController {

View File

@@ -839,7 +839,7 @@ public interface WebClient {
<T> Flux<T> bodyToFlux(Class<T> elementClass);
/**
* Variant of {@link #bodyToMono(Class)} with a {@link ParameterizedTypeReference}.
* Variant of {@link #bodyToFlux(Class)} with a {@link ParameterizedTypeReference}.
* @param elementTypeRef the type of element to decode to
* @param <T> the body element type
* @return the decoded body
@@ -859,7 +859,7 @@ public interface WebClient {
<T> Mono<ResponseEntity<T>> toEntity(Class<T> bodyClass);
/**
* Variant of {@link #bodyToMono(Class)} with a {@link ParameterizedTypeReference}.
* Variant of {@link #toEntity(Class)} with a {@link ParameterizedTypeReference}.
* @param bodyTypeReference the expected response body type
* @param <T> the response body type
* @return the {@code ResponseEntity} with the decoded body
@@ -881,7 +881,7 @@ public interface WebClient {
<T> Mono<ResponseEntity<List<T>>> toEntityList(Class<T> elementClass);
/**
* Variant of {@link #toEntity(Class)} with a {@link ParameterizedTypeReference}.
* Variant of {@link #toEntityList(Class)} with a {@link ParameterizedTypeReference}.
* @param elementTypeRef the type of element to decode the target Flux to
* @param <T> the body element type
* @return the {@code ResponseEntity}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -104,6 +104,8 @@ public class HandlerMappingIntrospector
private static final String CACHED_RESULT_ATTRIBUTE =
HandlerMappingIntrospector.class.getName() + ".CachedResult";
private static final int DEFAULT_CACHE_LIMIT = 2048;
private @Nullable ApplicationContext applicationContext;
@@ -111,9 +113,30 @@ public class HandlerMappingIntrospector
private Map<HandlerMapping, PathPatternMatchableHandlerMapping> pathPatternMappings = Collections.emptyMap();
private int patternCacheLimit = DEFAULT_CACHE_LIMIT;
private final CacheResultLogHelper cacheLogHelper = new CacheResultLogHelper();
/**
* Set a limit on the maximum number of security patterns passed into
* {@link MatchableHandlerMapping#match} at runtime to cache.
* <p>By default, this is set to 2048.
* @param patternCacheLimit the limit to use
* @since 6.2.8
*/
public void setPatternCacheLimit(int patternCacheLimit) {
this.patternCacheLimit = patternCacheLimit;
}
/**
* Return the configured limit on security patterns to cache.
* @since 6.2.8
*/
public int getPatternCacheLimit() {
return this.patternCacheLimit;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
@@ -127,8 +150,9 @@ public class HandlerMappingIntrospector
this.pathPatternMappings = this.handlerMappings.stream()
.filter(m -> m instanceof MatchableHandlerMapping hm && hm.getPatternParser() != null)
.map(mapping -> (MatchableHandlerMapping) mapping)
.collect(Collectors.toMap(mapping -> mapping, PathPatternMatchableHandlerMapping::new));
.map(hm -> (MatchableHandlerMapping) hm)
.collect(Collectors.toMap(hm -> hm, (MatchableHandlerMapping delegate) ->
new PathPatternMatchableHandlerMapping(delegate, getPatternCacheLimit())));
}
}

View File

@@ -42,21 +42,21 @@ import org.springframework.web.util.pattern.PathPatternParser;
@Deprecated(since = "7.0", forRemoval = true)
class PathPatternMatchableHandlerMapping implements MatchableHandlerMapping {
private static final int MAX_PATTERNS = 1024;
private final MatchableHandlerMapping delegate;
private final PathPatternParser parser;
private final Map<String, PathPattern> pathPatternCache = new ConcurrentHashMap<>();
private final int cacheLimit;
public PathPatternMatchableHandlerMapping(MatchableHandlerMapping delegate) {
public PathPatternMatchableHandlerMapping(MatchableHandlerMapping delegate, int cacheLimit) {
Assert.notNull(delegate, "HandlerMapping to delegate to is required.");
Assert.notNull(delegate.getPatternParser(), "Expected HandlerMapping configured to use PatternParser.");
this.delegate = delegate;
this.parser = delegate.getPatternParser();
this.cacheLimit = cacheLimit;
}
@SuppressWarnings("removal")
@@ -64,7 +64,7 @@ class PathPatternMatchableHandlerMapping implements MatchableHandlerMapping {
@Override
public @Nullable RequestMatchResult match(HttpServletRequest request, String pattern) {
PathPattern pathPattern = this.pathPatternCache.computeIfAbsent(pattern, value -> {
Assert.state(this.pathPatternCache.size() < MAX_PATTERNS, "Max size for pattern cache exceeded.");
Assert.state(this.pathPatternCache.size() < this.cacheLimit, "Max size for pattern cache exceeded.");
return this.parser.parse(pattern);
});
PathContainer path = ServletRequestPathUtils.getParsedRequestPath(request).pathWithinApplication();