1
0
mirror of https://gitee.com/mirrors/Spring-Cloud-Alibaba.git synced 2021-06-26 13:25:11 +08:00
This commit is contained in:
mercyblitz
2019-02-21 18:11:03 +08:00
parent 969dece586
commit a150a0cec6
12 changed files with 384 additions and 139 deletions

View File

@@ -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 {
}

View File

@@ -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}
*

View File

@@ -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() {

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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];
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}