Skip to content

Commit 52c187b

Browse files
committed
Merge branch '6.2.x'
2 parents db3c2b3 + a6b6d19 commit 52c187b

File tree

6 files changed

+54
-11
lines changed

6 files changed

+54
-11
lines changed

spring-context/src/main/java/org/springframework/validation/DataBinder.java

+3
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,9 @@ public interface ValueResolver {
13791379

13801380
/**
13811381
* Return the names of all property values.
1382+
* <p>Useful for proactive checks whether there are property values nested
1383+
* further below the path for a constructor arg. If not then the
1384+
* constructor arg can be considered missing and not to be instantiated.
13821385
* @since 6.1.2
13831386
*/
13841387
Set<String> getNames();

spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java

+10-6
Original file line numberDiff line numberDiff line change
@@ -309,15 +309,19 @@ public HandlerMethod createWithValidateFlags() {
309309
}
310310

311311
/**
312-
* If the provided instance contains a bean name rather than an object instance,
313-
* the bean name is resolved before a {@link HandlerMethod} is created and returned.
312+
* If the {@link #getBean() handler} is a bean name rather than the actual
313+
* handler instance, resolve the bean name through Spring configuration
314+
* (e.g. for prototype beans), and return a new {@link HandlerMethod}
315+
* instance with the resolved handler.
316+
* <p>If the {@link #getBean() handler} is not String, return the same instance.
314317
*/
315318
public HandlerMethod createWithResolvedBean() {
316-
Object handler = this.bean;
317-
if (this.bean instanceof String beanName) {
318-
Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory");
319-
handler = this.beanFactory.getBean(beanName);
319+
if (!(this.bean instanceof String beanName)) {
320+
return this;
320321
}
322+
323+
Assert.state(this.beanFactory != null, "Cannot resolve bean name without BeanFactory");
324+
Object handler = this.beanFactory.getBean(beanName);
321325
Assert.notNull(handler, "No handler instance");
322326
return new HandlerMethod(this, handler, false);
323327
}

spring-web/src/test/java/org/springframework/web/method/HandlerMethodTests.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,6 +72,13 @@ void classLevelValidatedAnnotation() {
7272
testValidateReturnValue(target, List.of("getPerson"), false);
7373
}
7474

75+
@Test // gh-34277
76+
void createWithResolvedBeanSameInstance() {
77+
MyClass target = new MyClass();
78+
HandlerMethod handlerMethod = getHandlerMethod(target, "addPerson");
79+
assertThat(handlerMethod.createWithResolvedBean()).isSameAs(handlerMethod);
80+
}
81+
7582
private static void testValidateArgs(Object target, List<String> methodNames, boolean expected) {
7683
for (String methodName : methodNames) {
7784
assertThat(getHandlerMethod(target, methodName).shouldValidateArguments()).isEqualTo(expected);

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinder.java

+9-3
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ protected void addBindValues(MutablePropertyValues mpvs, ServletRequest request)
125125
String name = names.nextElement();
126126
Object value = getHeaderValue(httpRequest, name);
127127
if (value != null) {
128-
name = StringUtils.uncapitalize(name.replace("-", ""));
128+
name = normalizeHeaderName(name);
129129
addValueIfNotPresent(mpvs, "Header", name, value);
130130
}
131131
}
@@ -171,6 +171,10 @@ private static void addValueIfNotPresent(MutablePropertyValues mpvs, String labe
171171
return values;
172172
}
173173

174+
private static String normalizeHeaderName(String name) {
175+
return StringUtils.uncapitalize(name.replace("-", ""));
176+
}
177+
174178

175179
/**
176180
* Resolver of values that looks up URI path variables.
@@ -206,8 +210,10 @@ protected Set<String> initParameterNames(ServletRequest request) {
206210
if (request instanceof HttpServletRequest httpServletRequest) {
207211
Enumeration<String> enumeration = httpServletRequest.getHeaderNames();
208212
while (enumeration.hasMoreElements()) {
209-
String headerName = enumeration.nextElement();
210-
set.add(headerName.replaceAll("-", ""));
213+
String name = enumeration.nextElement();
214+
if (headerPredicate.test(name)) {
215+
set.add(normalizeHeaderName(name));
216+
}
211217
}
212218
}
213219
return set;

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ExtendedServletRequestDataBinderTests.java

+17
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,23 @@ void filteredHeaders(String headerName) {
119119
assertThat(mpvs).isEmpty();
120120
}
121121

122+
@Test
123+
void headerPredicateWithConstructorArgs() {
124+
ExtendedServletRequestDataBinder binder = new ExtendedServletRequestDataBinder(null);
125+
binder.addHeaderPredicate(name -> !name.equalsIgnoreCase("Some-Int-Array"));
126+
binder.setTargetType(ResolvableType.forClass(DataBean.class));
127+
binder.setNameResolver(new BindParamNameResolver());
128+
129+
request.addHeader("Some-Int-Array", "1");
130+
request.addHeader("Some-Int-Array", "2");
131+
132+
binder.construct(request);
133+
134+
DataBean bean = (DataBean) binder.getTarget();
135+
136+
assertThat(bean.someIntArray()).isNull();
137+
}
138+
122139
@Test
123140
void headerPredicate() {
124141
TestBinder binder = new TestBinder();

spring-websocket/src/main/java/org/springframework/web/socket/WebSocketSession.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2022 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -72,6 +72,12 @@ public interface WebSocketSession extends Closeable {
7272

7373
/**
7474
* Return the address on which the request was received.
75+
* <p><strong>Note:</strong> The localAddress is not always possible to access,
76+
* which is the case with the Standard WebSocket client. In 6.2.x
77+
* {@link org.springframework.web.socket.client.standard.StandardWebSocketClient}
78+
* returns an address based on the local host and the port of the target
79+
* address (not the same as the local port). In 7.0, the same will return
80+
* {@code null} instead.
7581
*/
7682
@Nullable InetSocketAddress getLocalAddress();
7783

0 commit comments

Comments
 (0)