From d5951d9df2c45c9912120d87306103f82989f039 Mon Sep 17 00:00:00 2001
From: bruce <841326226@qq.com>
Date: Sat, 21 Jun 2025 22:09:08 +0800
Subject: [PATCH] fix: issues/1211, support Map parameter FORM request

Signed-off-by: bruce <841326226@qq.com>
---
 .../RequestParamParameterProcessor.java       | 33 +++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/annotation/RequestParamParameterProcessor.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/annotation/RequestParamParameterProcessor.java
index bc4d71688..c774cb323 100644
--- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/annotation/RequestParamParameterProcessor.java
+++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/annotation/RequestParamParameterProcessor.java
@@ -20,10 +20,16 @@
 import java.lang.reflect.Method;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Set;
 
 import feign.MethodMetadata;
 
 import org.springframework.cloud.openfeign.AnnotatedParameterProcessor;
+import org.springframework.cloud.openfeign.encoding.HttpEncoding;
+import org.springframework.core.annotation.AnnotatedElementUtils;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 
 import static feign.Util.checkState;
@@ -53,6 +59,12 @@ public boolean processArgument(AnnotatedParameterContext context, Annotation ann
 
 		if (Map.class.isAssignableFrom(parameterType)) {
 			checkState(data.queryMapIndex() == null, "Query map can only be present once.");
+			if (isPostOrPutForm(method)) {
+				data.bodyIndex(parameterIndex);
+				data.bodyType(parameterType);
+				data.template().header(HttpEncoding.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE);
+				return true;
+			}
 			data.queryMapIndex(parameterIndex);
 
 			return true;
@@ -69,4 +81,25 @@ public boolean processArgument(AnnotatedParameterContext context, Annotation ann
 		return true;
 	}
 
+
+	private boolean isPostOrPutForm(Method method) {
+		Set<RequestMapping> requestMappings = AnnotatedElementUtils.findAllMergedAnnotations(method, RequestMapping.class);
+		for (RequestMapping requestMapping : requestMappings) {
+			if (isPostOrPutFormMapping(requestMapping)) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	// @RequestMapping + @RequestParam + Map, POST 或者 PUT 默认为FORM请求
+	private boolean isPostOrPutFormMapping(RequestMapping requestMapping) {
+		for (RequestMethod httpMethod : requestMapping.method()) {
+			if (httpMethod == RequestMethod.POST || httpMethod == RequestMethod.PUT) {
+				return true;
+			}
+		}
+		return false;
+	}
+
 }