mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Polish spring-cloud-incubator/spring-cloud-alibaba#348 : Add @PathVariable support
This commit is contained in:
@@ -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 {
|
||||
}
|
||||
|
@@ -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:
|
||||
* <ol>
|
||||
* <li>To remove query string if presents</li>
|
||||
* <li>To remove duplicated slash("/") if exists</li>
|
||||
* </ol>
|
||||
*
|
||||
* @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}
|
||||
*
|
||||
|
@@ -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<String, String> getParams() {
|
||||
|
@@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public abstract class AbstractNamedValueServiceParameterResolver extends AbstractDubboGenericServiceParameterResolver {
|
||||
|
||||
/**
|
||||
* Get the {@link MultiValueMap} of names and values
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
protected abstract MultiValueMap<String, String> getNameAndValuesMap(HttpServerRequest request);
|
||||
|
||||
@Override
|
||||
public Object resolve(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata,
|
||||
HttpServerRequest request) {
|
||||
|
||||
Collection<String> names = getNames(restMethodMetadata, methodParameterMetadata);
|
||||
|
||||
if (isEmpty(names)) { // index can't match
|
||||
return null;
|
||||
}
|
||||
|
||||
MultiValueMap<String, String> 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<String> names = getNames(restMethodMetadata, methodParameterMetadata);
|
||||
|
||||
if (isEmpty(names)) { // index can't match
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer index = null;
|
||||
|
||||
Map<Integer, Collection<String>> clientIndexToName = clientRestMethodMetadata.getIndexToName();
|
||||
|
||||
for (Map.Entry<Integer, Collection<String>> entry : clientIndexToName.entrySet()) {
|
||||
|
||||
Collection<String> clientParamNames = entry.getValue();
|
||||
|
||||
if (CollectionUtils.containsAny(names, clientParamNames)) {
|
||||
index = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index > -1 ? arguments[index] : null;
|
||||
}
|
||||
|
||||
protected Collection<String> getNames(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata) {
|
||||
|
||||
Map<Integer, Collection<String>> indexToName = restMethodMetadata.getIndexToName();
|
||||
|
||||
int index = methodParameterMetadata.getIndex();
|
||||
|
||||
Collection<String> paramNames = indexToName.get(index);
|
||||
|
||||
return paramNames == null ? Collections.emptyList() : paramNames;
|
||||
}
|
||||
|
||||
}
|
@@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class PathVariableServiceParameterResolver extends AbstractNamedValueServiceParameterResolver {
|
||||
|
||||
public static final int DEFAULT_ORDER = 3;
|
||||
|
||||
public PathVariableServiceParameterResolver() {
|
||||
super();
|
||||
setOrder(DEFAULT_ORDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiValueMap<String, String> getNameAndValuesMap(HttpServerRequest request) {
|
||||
return request.getQueryParams();
|
||||
}
|
||||
}
|
@@ -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];
|
||||
}
|
||||
}
|
||||
|
@@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class RequestHeaderServiceParameterResolver extends AbstractNamedValueServiceParameterResolver {
|
||||
|
||||
public static final int DEFAULT_ORDER = 9;
|
||||
|
||||
public RequestHeaderServiceParameterResolver() {
|
||||
super();
|
||||
setOrder(DEFAULT_ORDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiValueMap<String, String> getNameAndValuesMap(HttpServerRequest request) {
|
||||
return request.getHeaders();
|
||||
}
|
||||
}
|
@@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
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<String> paramNames = getParamNames(restMethodMetadata, methodParameterMetadata);
|
||||
|
||||
if (isEmpty(paramNames)) { // index can't match
|
||||
return null;
|
||||
}
|
||||
|
||||
MultiValueMap<String, String> 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<String, String> getNameAndValuesMap(HttpServerRequest request) {
|
||||
return request.getQueryParams();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolve(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata,
|
||||
RestMethodMetadata clientRestMethodMetadata, Object[] arguments) {
|
||||
|
||||
Collection<String> paramNames = getParamNames(restMethodMetadata, methodParameterMetadata);
|
||||
|
||||
if (isEmpty(paramNames)) { // index can't match
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer index = null;
|
||||
|
||||
Map<Integer, Collection<String>> clientIndexToName = clientRestMethodMetadata.getIndexToName();
|
||||
|
||||
for (Map.Entry<Integer, Collection<String>> entry : clientIndexToName.entrySet()) {
|
||||
|
||||
Collection<String> clientParamNames = entry.getValue();
|
||||
|
||||
if (CollectionUtils.containsAny(paramNames, clientParamNames)) {
|
||||
index = entry.getKey();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return index > -1 ? arguments[index] : null;
|
||||
}
|
||||
|
||||
|
||||
private Collection<String> getParamNames(RestMethodMetadata restMethodMetadata, MethodParameterMetadata methodParameterMetadata) {
|
||||
|
||||
Map<Integer, Collection<String>> indexToName = restMethodMetadata.getIndexToName();
|
||||
|
||||
int index = methodParameterMetadata.getIndex();
|
||||
|
||||
Collection<String> paramNames = indexToName.get(index);
|
||||
|
||||
return paramNames == null ? Collections.emptyList() : paramNames;
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user