diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java index f3f9a81f..dc1ad286 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java @@ -19,7 +19,9 @@ package org.springframework.cloud.alibaba.dubbo.autoconfigure; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory; +import org.springframework.cloud.alibaba.dubbo.service.parameter.PathVariableServiceParameterResolver; import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestBodyServiceParameterResolver; +import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestHeaderServiceParameterResolver; import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestParamServiceParameterResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -44,6 +46,8 @@ public class DubboServiceAutoConfiguration { DubboGenericServiceExecutionContextFactory.class, RequestParamServiceParameterResolver.class, RequestBodyServiceParameterResolver.class, + RequestHeaderServiceParameterResolver.class, + PathVariableServiceParameterResolver.class }) static class ParameterResolversConfiguration { } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/http/util/HttpUtils.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/http/util/HttpUtils.java index 81722ccc..a48e130c 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/http/util/HttpUtils.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/http/util/HttpUtils.java @@ -36,6 +36,7 @@ import java.util.Set; import static org.springframework.http.HttpHeaders.COOKIE; import static org.springframework.util.CollectionUtils.unmodifiableMultiValueMap; import static org.springframework.util.StringUtils.delimitedListToStringArray; +import static org.springframework.util.StringUtils.hasText; import static org.springframework.util.StringUtils.trimAllWhitespace; import static org.springframework.util.StringUtils.trimWhitespace; @@ -54,11 +55,36 @@ public abstract class HttpUtils { private static final String SEMICOLON = ";"; + private static final String QUESTION_MASK = "?"; + /** * The empty value */ private static final String EMPTY_VALUE = ""; + /** + * Normalize path: + *
    + *
  1. To remove query string if presents
  2. + *
  3. To remove duplicated slash("/") if exists
  4. + *
+ * + * @param path path to be normalized + * @return a normalized path if required + */ + public static String normalizePath(String path) { + if (!hasText(path)) { + return path; + } + String normalizedPath = path; + int index = normalizedPath.indexOf(QUESTION_MASK); + if (index > -1) { + normalizedPath = normalizedPath.substring(0, index); + } + return StringUtils.replace(normalizedPath, "//", "/"); + } + + /** * Get Parameters from the specified {@link HttpRequest request} * diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RequestMetadata.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RequestMetadata.java index 4b3b1794..35d9cee1 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RequestMetadata.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/metadata/RequestMetadata.java @@ -37,6 +37,7 @@ import java.util.Objects; import java.util.Set; import java.util.SortedMap; +import static org.springframework.cloud.alibaba.dubbo.http.util.HttpUtils.normalizePath; import static org.springframework.http.MediaType.parseMediaTypes; /** @@ -83,7 +84,7 @@ public class RequestMetadata { } public void setPath(String path) { - this.path = path; + this.path = normalizePath(path); } public MultiValueMap getParams() { diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/AbstractNamedValueServiceParameterResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/AbstractNamedValueServiceParameterResolver.java new file mode 100644 index 00000000..3654b1bd --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/AbstractNamedValueServiceParameterResolver.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.alibaba.dubbo.service.parameter; + +import org.springframework.cloud.alibaba.dubbo.http.HttpServerRequest; +import org.springframework.cloud.alibaba.dubbo.metadata.MethodParameterMetadata; +import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata; +import org.springframework.util.CollectionUtils; +import org.springframework.util.MultiValueMap; + +import java.util.Collection; +import java.util.Collections; +import java.util.Map; + +import static org.springframework.util.ObjectUtils.isEmpty; + +/** + * Abstract HTTP Names Value {@link DubboGenericServiceParameterResolver Dubbo GenericService Parameter Resolver} + * + * @author Mercy + */ +public abstract class AbstractNamedValueServiceParameterResolver extends AbstractDubboGenericServiceParameterResolver { + + /** + * Get the {@link MultiValueMap} of names and values + * + * @param request + * @return + */ + protected abstract MultiValueMap getNameAndValuesMap(HttpServerRequest request); + + @Override + public Object resolve(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata, + HttpServerRequest request) { + + Collection names = getNames(restMethodMetadata, methodParameterMetadata); + + if (isEmpty(names)) { // index can't match + return null; + } + + MultiValueMap nameAndValues = getNameAndValuesMap(request); + + String targetName = null; + + for (String name : names) { + if (nameAndValues.containsKey(name)) { + targetName = name; + break; + } + } + + if (targetName == null) { // request parameter is abstract + return null; + } + + Class parameterType = resolveClass(methodParameterMetadata.getType()); + + Object paramValue = null; + + if (parameterType.isArray()) { // Array type + paramValue = nameAndValues.get(targetName); + } else { + paramValue = nameAndValues.getFirst(targetName); + } + + return resolveValue(paramValue, parameterType); + } + + @Override + public Object resolve(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata, + RestMethodMetadata clientRestMethodMetadata, Object[] arguments) { + + Collection names = getNames(restMethodMetadata, methodParameterMetadata); + + if (isEmpty(names)) { // index can't match + return null; + } + + Integer index = null; + + Map> clientIndexToName = clientRestMethodMetadata.getIndexToName(); + + for (Map.Entry> entry : clientIndexToName.entrySet()) { + + Collection clientParamNames = entry.getValue(); + + if (CollectionUtils.containsAny(names, clientParamNames)) { + index = entry.getKey(); + break; + } + } + + return index > -1 ? arguments[index] : null; + } + + protected Collection getNames(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata) { + + Map> indexToName = restMethodMetadata.getIndexToName(); + + int index = methodParameterMetadata.getIndex(); + + Collection paramNames = indexToName.get(index); + + return paramNames == null ? Collections.emptyList() : paramNames; + } + +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/PathVariableServiceParameterResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/PathVariableServiceParameterResolver.java new file mode 100644 index 00000000..81a40f3c --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/PathVariableServiceParameterResolver.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.alibaba.dubbo.service.parameter; + +import org.springframework.cloud.alibaba.dubbo.http.HttpServerRequest; +import org.springframework.util.MultiValueMap; + +/** + * HTTP Request Path Variable {@link DubboGenericServiceParameterResolver Dubbo GenericService Parameter Resolver} + * + * @author Mercy + */ +public class PathVariableServiceParameterResolver extends AbstractNamedValueServiceParameterResolver { + + public static final int DEFAULT_ORDER = 3; + + public PathVariableServiceParameterResolver() { + super(); + setOrder(DEFAULT_ORDER); + } + + @Override + protected MultiValueMap getNameAndValuesMap(HttpServerRequest request) { + return request.getQueryParams(); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestBodyServiceParameterResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestBodyServiceParameterResolver.java index cf48dd9a..e4f35cae 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestBodyServiceParameterResolver.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestBodyServiceParameterResolver.java @@ -106,6 +106,12 @@ public class RequestBodyServiceParameterResolver extends AbstractDubboGenericSer @Override public Object resolve(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata, RestMethodMetadata clientRestMethodMetadata, Object[] arguments) { - return null; + + if (!supportParameter(restMethodMetadata, methodParameterMetadata)) { + return null; + } + + Integer clientBodyIndex = clientRestMethodMetadata.getBodyIndex(); + return arguments[clientBodyIndex]; } } diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestHeaderServiceParameterResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestHeaderServiceParameterResolver.java new file mode 100644 index 00000000..fc0e1c01 --- /dev/null +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestHeaderServiceParameterResolver.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.alibaba.dubbo.service.parameter; + +import org.springframework.cloud.alibaba.dubbo.http.HttpServerRequest; +import org.springframework.util.MultiValueMap; + +/** + * HTTP Request Header {@link DubboGenericServiceParameterResolver Dubbo GenericService Parameter Resolver} + * + * @author Mercy + */ +public class RequestHeaderServiceParameterResolver extends AbstractNamedValueServiceParameterResolver { + + public static final int DEFAULT_ORDER = 9; + + public RequestHeaderServiceParameterResolver() { + super(); + setOrder(DEFAULT_ORDER); + } + + @Override + protected MultiValueMap getNameAndValuesMap(HttpServerRequest request) { + return request.getHeaders(); + } +} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestParamServiceParameterResolver.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestParamServiceParameterResolver.java index 12010da8..4801d1ba 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestParamServiceParameterResolver.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/parameter/RequestParamServiceParameterResolver.java @@ -17,23 +17,14 @@ package org.springframework.cloud.alibaba.dubbo.service.parameter; import org.springframework.cloud.alibaba.dubbo.http.HttpServerRequest; -import org.springframework.cloud.alibaba.dubbo.metadata.MethodParameterMetadata; -import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata; -import org.springframework.util.CollectionUtils; import org.springframework.util.MultiValueMap; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; - -import static org.springframework.util.ObjectUtils.isEmpty; - /** * HTTP Request Parameter {@link DubboGenericServiceParameterResolver Dubbo GenericService Parameter Resolver} * * @author Mercy */ -public class RequestParamServiceParameterResolver extends AbstractDubboGenericServiceParameterResolver { +public class RequestParamServiceParameterResolver extends AbstractNamedValueServiceParameterResolver { public static final int DEFAULT_ORDER = 1; @@ -43,80 +34,7 @@ public class RequestParamServiceParameterResolver extends AbstractDubboGenericSe } @Override - public Object resolve(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata, - HttpServerRequest request) { - - Collection paramNames = getParamNames(restMethodMetadata, methodParameterMetadata); - - if (isEmpty(paramNames)) { // index can't match - return null; - } - - MultiValueMap queryParams = request.getQueryParams(); - - String targetParamName = null; - - for (String paramName : paramNames) { - if (queryParams.containsKey(paramName)) { - targetParamName = paramName; - break; - } - } - - if (targetParamName == null) { // request parameter is abstract - return null; - } - - Class parameterType = resolveClass(methodParameterMetadata.getType()); - - Object paramValue = null; - - if (parameterType.isArray()) { // Array type - paramValue = queryParams.get(targetParamName); - } else { - paramValue = queryParams.getFirst(targetParamName); - } - - return resolveValue(paramValue, parameterType); + protected MultiValueMap getNameAndValuesMap(HttpServerRequest request) { + return request.getQueryParams(); } - - @Override - public Object resolve(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata, - RestMethodMetadata clientRestMethodMetadata, Object[] arguments) { - - Collection paramNames = getParamNames(restMethodMetadata, methodParameterMetadata); - - if (isEmpty(paramNames)) { // index can't match - return null; - } - - Integer index = null; - - Map> clientIndexToName = clientRestMethodMetadata.getIndexToName(); - - for (Map.Entry> entry : clientIndexToName.entrySet()) { - - Collection clientParamNames = entry.getValue(); - - if (CollectionUtils.containsAny(paramNames, clientParamNames)) { - index = entry.getKey(); - break; - } - } - - return index > -1 ? arguments[index] : null; - } - - - private Collection getParamNames(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata) { - - Map> indexToName = restMethodMetadata.getIndexToName(); - - int index = methodParameterMetadata.getIndex(); - - Collection paramNames = indexToName.get(index); - - return paramNames == null ? Collections.emptyList() : paramNames; - } - } diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java index b6aaf379..25845681 100644 --- a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudBootstrap.java @@ -33,14 +33,21 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Lazy; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; +import javax.ws.rs.GET; +import javax.ws.rs.Path; import java.util.HashMap; import java.util.Map; +import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE; + /** * Dubbo Spring Cloud Bootstrap */ @@ -65,21 +72,6 @@ public class DubboSpringCloudBootstrap { @LoadBalanced private RestTemplate restTemplate; - @GetMapping(value = "/dubbo/call/echo") - public String dubboEcho(@RequestParam("message") String message) { - return restService.param(message); - } - - @GetMapping(value = "/feign/call/echo") - public String feignEcho(@RequestParam("message") String message) { - return feignRestService.param(message); - } - - @GetMapping(value = "/feign-dubbo/call/echo") - public String feignDubboEcho(@RequestParam("message") String message) { - return dubboFeignRestService.param(message); - } - @FeignClient("spring-cloud-alibaba-dubbo") public interface FeignRestService { @@ -89,6 +81,20 @@ public class DubboSpringCloudBootstrap { @PostMapping("/params") public String params(@RequestParam("b") String b, @RequestParam("a") int a); + @PostMapping(value = "/request/body/map", produces = APPLICATION_JSON_UTF8_VALUE) + User requestBody(@RequestParam("param") String param, @RequestBody Map data); + + @GetMapping("/headers") + @Path("/headers") + @GET + public String headers(@RequestHeader("h2") String header2, + @RequestHeader("h") String header, + @RequestParam("v") Integer value); + + @GetMapping("/path-variables/{p1}/{p2}") + public String pathVariables(@PathVariable("p2") String path2, + @PathVariable("p1") String path1, + @RequestParam("v") String param); } @FeignClient("spring-cloud-alibaba-dubbo") @@ -99,7 +105,22 @@ public class DubboSpringCloudBootstrap { String param(@RequestParam("param") String param); @PostMapping("/params") - public String params(@RequestParam("b") String paramB, @RequestParam("a") int paramA); + String params(@RequestParam("b") String paramB, @RequestParam("a") int paramA); + + @PostMapping(value = "/request/body/map", produces = APPLICATION_JSON_UTF8_VALUE) + User requestBody(@RequestParam("param") String param, @RequestBody Map data); + + @GetMapping("/headers") + @Path("/headers") + @GET + public String headers(@RequestHeader("h2") String header2, + @RequestParam("v") Integer value, + @RequestHeader("h") String header); + + @GetMapping("/path-variables/{p1}/{p2}") + public String pathVariables(@RequestParam("v") String param, + @PathVariable("p2") String path2, + @PathVariable("p1") String path1); } @@ -107,24 +128,76 @@ public class DubboSpringCloudBootstrap { public ApplicationRunner paramRunner() { return arguments -> { + // To call /path-variables + callPathVariables(); + + // To call /headers + callHeaders(); + // To call /param - // Dubbo Service call - System.out.println(restService.param("mercyblitz")); - // Spring Cloud Open Feign REST Call (Dubbo Transported) - System.out.println(dubboFeignRestService.param("mercyblitz")); - // Spring Cloud Open Feign REST Call - System.out.println(feignRestService.param("mercyblitz")); + callParam(); // To call /params - // Dubbo Service call - System.out.println(restService.params(1, "1")); - // Spring Cloud Open Feign REST Call (Dubbo Transported) - System.out.println(dubboFeignRestService.params("1", 1)); - // Spring Cloud Open Feign REST Call - System.out.println(feignRestService.params("1", 1)); + callParams(); + + // To call /request/body/map + callRequestBodyMap(); + }; } + private void callPathVariables() { + // Dubbo Service call + System.out.println(restService.pathVariables("a", "b", "c")); + // Spring Cloud Open Feign REST Call (Dubbo Transported) + System.out.println(dubboFeignRestService.pathVariables("c", "b", "a")); + // Spring Cloud Open Feign REST Call + System.out.println(feignRestService.pathVariables("b", "a", "c")); + } + + private void callHeaders() { + // Dubbo Service call + System.out.println(restService.headers("a", "b", 10)); + // Spring Cloud Open Feign REST Call (Dubbo Transported) + System.out.println(dubboFeignRestService.headers("b", 10, "a")); + // Spring Cloud Open Feign REST Call + System.out.println(feignRestService.headers("b", "a", 10)); + } + + private void callParam() { + // Dubbo Service call + System.out.println(restService.param("mercyblitz")); + // Spring Cloud Open Feign REST Call (Dubbo Transported) + System.out.println(dubboFeignRestService.param("mercyblitz")); + // Spring Cloud Open Feign REST Call + System.out.println(feignRestService.param("mercyblitz")); + } + + private void callParams() { + // Dubbo Service call + System.out.println(restService.params(1, "1")); + // Spring Cloud Open Feign REST Call (Dubbo Transported) + System.out.println(dubboFeignRestService.params("1", 1)); + // Spring Cloud Open Feign REST Call + System.out.println(feignRestService.params("1", 1)); + } + + private void callRequestBodyMap() { + + Map data = new HashMap<>(); + data.put("id", 1); + data.put("name", "小马哥"); + data.put("age", 33); + + // Dubbo Service call + System.out.println(restService.requestBody(data, "Hello,World")); + // Spring Cloud Open Feign REST Call (Dubbo Transported) + System.out.println(dubboFeignRestService.requestBody("Hello,World", data)); + // Spring Cloud Open Feign REST Call + System.out.println(feignRestService.requestBody("Hello,World", data)); + } + + @Bean public ApplicationRunner restTemplateRunner() { return arguments -> { @@ -136,11 +209,11 @@ public class DubboSpringCloudBootstrap { data.put("id", 1); data.put("name", "小马哥"); data.put("age", 33); - User user = restTemplate.postForObject("http://spring-cloud-alibaba-dubbo/request/setBody/map", data, User.class); + User user = restTemplate.postForObject("http://spring-cloud-alibaba-dubbo/request/body/map", data, User.class); - System.out.println(restTemplate.postForObject("http://spring-cloud-alibaba-dubbo/request/setBody/map", data, String.class)); + System.out.println(restTemplate.postForObject("http://spring-cloud-alibaba-dubbo/request/body/map", data, String.class)); - Map map = restTemplate.postForObject("http://spring-cloud-alibaba-dubbo/request/setBody/user", user, Map.class); + Map map = restTemplate.postForObject("http://spring-cloud-alibaba-dubbo/request/body/user", user, Map.class); System.out.println(map); }; } diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/RestService.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/RestService.java index e0bc2c2d..396372e1 100644 --- a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/RestService.java +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/RestService.java @@ -25,17 +25,18 @@ import java.util.Map; */ public interface RestService { - String param(String message); + String param(String param); String params(int a, String b); - User requestBody(Map data); + String headers(String header, String header2, Integer param); - Map requestBody(User user); - - String header(String header); + String pathVariables(String path1, String path2, String param); String form(String form); - String cookie(String userAgent); + User requestBody(Map data, String param); + + Map requestBody(User user); + } diff --git a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/StandardRestService.java b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/StandardRestService.java index decc8168..3ac3ca39 100644 --- a/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/StandardRestService.java +++ b/spring-cloud-alibaba-dubbo/src/test/java/org/springframework/cloud/alibaba/dubbo/service/StandardRestService.java @@ -20,8 +20,8 @@ import com.alibaba.dubbo.rpc.RpcContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; @@ -29,12 +29,12 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.ws.rs.Consumes; -import javax.ws.rs.CookieParam; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import java.util.HashMap; @@ -74,13 +74,32 @@ public class StandardRestService implements RestService { } @Override - @GetMapping("/header") - @Path("/header") + @GetMapping("/headers") + @Path("/headers") @GET - public String header(@RequestHeader("h") @HeaderParam("h") String header) { - return String.valueOf(header); + public String headers(@RequestHeader("h") @HeaderParam("h") String header, + @RequestHeader("h2") @HeaderParam("h2") String header2, + @RequestParam("v") @QueryParam("v") Integer param) { + String result = header + " , " + header2 + " , " + param; + log("/headers", result); + return result; } + @Override + @GetMapping("/path-variables/{p1}/{p2}") + @Path("/path-variables/{p1}/{p2}") + @GET + public String pathVariables(@PathVariable("p1") @PathParam("p1") String path1, + @PathVariable("p2") @PathParam("p2") String path2, + @RequestParam("v") @QueryParam("v") String param) { + String result = path1 + " , " + path2 + " , " + param; + log("/path-variables", result); + return result; + } + + // @CookieParam does not support : https://github.com/OpenFeign/feign/issues/913 + // @CookieValue also does not support + @Override @PostMapping("/form") @Path("/form") @@ -94,11 +113,12 @@ public class StandardRestService implements RestService { @Path("/request/setBody/map") @POST @Produces(APPLICATION_JSON_VALUE) - public User requestBody(@RequestBody Map data) { + public User requestBody(@RequestBody Map data, @RequestParam("param") @QueryParam("param") String param) { User user = new User(); user.setId(((Integer) data.get("id")).longValue()); user.setName((String) data.get("name")); user.setAge((Integer) data.get("age")); + log("/request/body/map", param); return user; } @@ -115,14 +135,6 @@ public class StandardRestService implements RestService { return map; } - @Override - @GetMapping("/cookie") - @Path("/cookie") - @GET - public String cookie(@CookieParam("User-Agent") @CookieValue("User-Agent") String userAgent) { - return userAgent; - } - private void log(String url, Object result) { String message = String.format("The client[%s] uses '%s' protocol to call %s : %s", RpcContext.getContext().getRemoteHostName(), diff --git a/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml b/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml index c3799608..e21e07da 100644 --- a/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml +++ b/spring-cloud-alibaba-dubbo/src/test/resources/bootstrap.yaml @@ -7,6 +7,8 @@ spring: server-addr: 127.0.0.1:8848 config: server-addr: 127.0.0.1:8848 + main: + allow-bean-definition-overriding: true eureka: client: