Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import feign.MethodMetadata;

import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.RequestHeader;

import static feign.Util.checkState;
Expand Down Expand Up @@ -51,7 +52,7 @@ public boolean processArgument(AnnotatedParameterContext context, Annotation ann
Class<?> parameterType = method.getParameterTypes()[parameterIndex];
MethodMetadata data = context.getMethodMetadata();

if (Map.class.isAssignableFrom(parameterType)) {
if (Map.class.isAssignableFrom(parameterType) || HttpHeaders.class.isAssignableFrom(parameterType)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we then need the Map.class.isAssignableFrom(parameterType) check here anymore then since from this point forward we are only compatible with Spring Boot 4 so no need for backward compatibility

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Map.class.isAssignableFrom(parameterType) check is necessary for backward compatibility and to support MultiValueMap usage.

SpringMvcContractTests.java#L635

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But we don't need to support Boot versions prior to 4.0.x on the main branch, the 4.3.x branch and the 4.2.x branches of Spring Cloud OpenFeign will support the prior Boot versions. That is why I think we can remove the check for Map.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you think it’s safe to remove the check, I’m open to it. That said, I’d prefer to keep it — a lot of tests fail when it’s removed, and users may (or probably) rely on MultiValueMap as a workaround instead of HttpHeaders. Keeping it feels like the safer option to avoid subtle breakages. What do you think?

checkState(data.headerMapIndex() == null, "Header map can only be present once.");
data.headerMapIndex(parameterIndex);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.number.NumberStyleFormatter;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.MultiValueMap;
Expand Down Expand Up @@ -642,6 +643,17 @@ void testProcessHeaderMap() throws Exception {
assertThat(headers.get("aHeader").iterator().next()).isEqualTo("{aHeader}");
}

@Test
void testProcessHttpHeaders() throws Exception {
Method method = TestTemplate_HeaderMap.class.getDeclaredMethod("httpHeaders", HttpHeaders.class);
MethodMetadata data = contract.parseAndValidateMetadata(method.getDeclaringClass(), method);

assertThat(data.template().url()).isEqualTo("/httpHeaders");
assertThat(data.template().method()).isEqualTo("GET");
assertThat(data.headerMapIndex()).isNotNull();
assertThat(data.headerMapIndex().intValue()).isEqualTo(0);
}

@Test
void testProcessHeaderMapMoreThanOnce() throws Exception {
Method method = TestTemplate_HeaderMap.class.getDeclaredMethod("headerMapMoreThanOnce", MultiValueMap.class,
Expand Down Expand Up @@ -913,6 +925,9 @@ public interface TestTemplate_HeaderMap {
String headerMap(@RequestHeader MultiValueMap<String, String> headerMap,
@RequestHeader(name = "aHeader") String aHeader);

@GetMapping("/httpHeaders")
String httpHeaders(@RequestHeader HttpHeaders headers);

@GetMapping("/headerMapMoreThanOnce")
String headerMapMoreThanOnce(@RequestHeader MultiValueMap<String, String> headerMap1,
@RequestHeader MultiValueMap<String, String> headerMap2);
Expand Down