Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic param support #14471

Merged
merged 3 commits into from
Jul 29, 2024
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 @@ -462,4 +462,19 @@ static long invokeAndReturnLong(Method method, Object targetObj) {
return -1;
}
}

static String toShortString(Method method) {
StringBuilder sb = new StringBuilder(64);
sb.append(method.getDeclaringClass().getName());
sb.append('.').append(method.getName()).append('(');
Class<?>[] parameterTypes = method.getParameterTypes();
for (int i = 0, len = parameterTypes.length; i < len; i++) {
if (i > 0) {
sb.append(", ");
}
sb.append(parameterTypes[i].getSimpleName());
}
sb.append(')');
return sb.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,6 @@ public Object resolve(
throw new RestException(e);
}
}
return RequestUtils.decodeBody(request, type);
return RequestUtils.decodeBody(request, parameter.getActualGenericType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ protected NamedValueMeta createNamedValueMeta(ParameterMeta param) {

@Override
protected Object resolveValue(NamedValueMeta meta, HttpRequest request, HttpResponse response) {
Object value = RequestUtils.decodeBody(request, meta.type());
Object value = RequestUtils.decodeBody(request, meta.genericType());
if (value != null) {
return value;
}
Expand All @@ -65,7 +65,7 @@ protected Object resolveCollectionValue(NamedValueMeta meta, HttpRequest request
throw new RestException(e);
}
}
Object value = RequestUtils.decodeBody(request, meta.type());
Object value = RequestUtils.decodeBody(request, meta.genericType());
if (value != null) {
return value;
}
Expand All @@ -77,7 +77,7 @@ protected Object resolveCollectionValue(NamedValueMeta meta, HttpRequest request

@Override
protected Object resolveMapValue(NamedValueMeta meta, HttpRequest request, HttpResponse response) {
Object value = RequestUtils.decodeBody(request, meta.type());
Object value = RequestUtils.decodeBody(request, meta.genericType());
if (value != null) {
return value;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping.Builder;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.condition.ServiceVersionCondition;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.meta.AnnotationMeta;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.meta.AnnotationSupport;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.meta.CorsMeta;
Expand Down Expand Up @@ -76,7 +75,7 @@ public RequestMapping resolve(MethodMeta methodMeta) {
return builder(methodMeta, path, httpMethod)
.name(methodMeta.getMethod().getName())
.contextPath(methodMeta.getServiceMeta().getContextPath())
.custom(new ServiceVersionCondition(serviceMeta.getServiceGroup(), serviceMeta.getServiceVersion()))
.service(serviceMeta.getServiceGroup(), serviceMeta.getServiceVersion())
.cors(globalCorsMeta)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public Object convert(Object value, ParameterMeta parameter) {
}

ParamConverter converter = paramConverterFactory.getParamConverter(
parameter.getType(), parameter.getGenericType(), parameter.getRealAnnotations());
parameter.getType(), parameter.getGenericType(), parameter.getRawAnnotations());
if (converter != null) {
return value instanceof String ? converter.fromString((String) value) : converter.toString(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public void removeProperty(String name) {

@Override
public Annotation[] getAnnotations() {
return getHandler().getMethod().getRealAnnotations();
return getHandler().getMethod().getRawAnnotations();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ private static class MatrixNamedValueMeta extends NamedValueMeta {

private final String pathVar;

public MatrixNamedValueMeta(String name, boolean required, String defaultValue, String pathVar) {
MatrixNamedValueMeta(String name, boolean required, String defaultValue, String pathVar) {
super(name, required, defaultValue);
this.pathVar = pathVar;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected Object resolveValue(NamedValueMeta meta, HttpRequest request, HttpResp
}
return meta.parameterMeta().bind(request, response);
}
return RequestUtils.decodeBody(request, meta.type());
return RequestUtils.decodeBody(request, meta.genericType());
}

@Override
Expand All @@ -66,14 +66,14 @@ protected Object resolveCollectionValue(NamedValueMeta meta, HttpRequest request
if (RequestUtils.isFormOrMultiPart(request)) {
return request.formParameterValues(meta.name());
}
return RequestUtils.decodeBody(request, meta.type());
return RequestUtils.decodeBody(request, meta.genericType());
}

@Override
protected Object resolveMapValue(NamedValueMeta meta, HttpRequest request, HttpResponse response) {
if (RequestUtils.isFormOrMultiPart(request)) {
return RequestUtils.getFormParametersMap(request);
}
return RequestUtils.decodeBody(request, meta.type());
return RequestUtils.decodeBody(request, meta.genericType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMapping.Builder;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.RequestMappingResolver;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.condition.ServiceVersionCondition;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.meta.AnnotationMeta;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.meta.CorsMeta;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.meta.MethodMeta;
Expand Down Expand Up @@ -70,9 +69,11 @@ public RequestMapping resolve(ServiceMeta serviceMeta) {
String[] methods = requestMapping == null
? httpExchange.getStringArray("method")
: requestMapping.getStringArray("method");
String[] paths = requestMapping == null ? httpExchange.getValueArray() : requestMapping.getValueArray();
return builder(requestMapping, httpExchange, serviceMeta.findMergedAnnotation(Annotations.ResponseStatus))
.method(methods)
.name(serviceMeta.getType().getSimpleName())
.path(paths)
.contextPath(serviceMeta.getContextPath())
.cors(buildCorsMeta(serviceMeta.findMergedAnnotation(Annotations.CrossOrigin), methods))
.build();
Expand All @@ -92,14 +93,20 @@ public RequestMapping resolve(MethodMeta methodMeta) {
}

ServiceMeta serviceMeta = methodMeta.getServiceMeta();
String name = methodMeta.getMethod().getName();
String[] methods = requestMapping == null
? httpExchange.getStringArray("method")
: requestMapping.getStringArray("method");
String[] paths = requestMapping == null ? httpExchange.getValueArray() : requestMapping.getValueArray();
if (paths.length == 0) {
paths = new String[] {'/' + name};
}
return builder(requestMapping, httpExchange, methodMeta.findMergedAnnotation(Annotations.ResponseStatus))
.method(methods)
.name(methodMeta.getMethod().getName())
.name(name)
.path(paths)
.contextPath(serviceMeta.getContextPath())
.custom(new ServiceVersionCondition(serviceMeta.getServiceGroup(), serviceMeta.getServiceVersion()))
.service(serviceMeta.getServiceGroup(), serviceMeta.getServiceVersion())
.cors(buildCorsMeta(methodMeta.findMergedAnnotation(Annotations.CrossOrigin), methods))
.build();
}
Expand All @@ -116,12 +123,10 @@ private Builder builder(
}
}
if (requestMapping == null) {
return builder.path(httpExchange.getValueArray())
.consume(httpExchange.getStringArray("contentType"))
return builder.consume(httpExchange.getStringArray("contentType"))
.produce(httpExchange.getStringArray("accept"));
}
return builder.path(requestMapping.getValueArray())
.param(requestMapping.getStringArray("params"))
return builder.param(requestMapping.getStringArray("params"))
.header(requestMapping.getStringArray("headers"))
.consume(requestMapping.getStringArray("consumes"))
.produce(requestMapping.getStringArray("produces"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@
*/
package org.apache.dubbo.rpc.protocol.tri.rest.support.spring;

import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.spring.extension.SpringExtensionInjector;
import org.apache.dubbo.remoting.http12.HttpRequest;
import org.apache.dubbo.remoting.http12.HttpResponse;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.apache.dubbo.rpc.protocol.tri.rest.Messages;
import org.apache.dubbo.rpc.protocol.tri.rest.RestConstants;
import org.apache.dubbo.rpc.protocol.tri.rest.RestException;
import org.apache.dubbo.rpc.protocol.tri.rest.argument.GeneralTypeConverter;
import org.apache.dubbo.rpc.protocol.tri.rest.argument.TypeConverter;
import org.apache.dubbo.rpc.protocol.tri.rest.mapping.meta.MethodParameterMeta;
Expand Down Expand Up @@ -49,6 +54,9 @@

final class SpringRestToolKit implements RestToolKit {

private static final Logger LOGGER = LoggerFactory.getLogger(SpringRestToolKit.class);

private final Map<MethodParameterMeta, TypeDescriptor> cache = CollectionUtils.newConcurrentHashMap();
private final ConfigurableBeanFactory beanFactory;
private final PropertyPlaceholderHelper placeholderHelper;
private final ConfigurationWrapper configuration;
Expand Down Expand Up @@ -98,23 +106,42 @@ public String resolvePlaceholders(String text) {

@Override
public Object convert(Object value, ParameterMeta parameter) {
if (value instanceof Collection) {
boolean tried = false;
if (value instanceof Collection || value instanceof Map) {
tried = true;
Object target = typeConverter.convert(value, parameter.getGenericType());
if (target != null) {
return target;
}
}
TypeDescriptor targetType = (TypeDescriptor) parameter.getTypeDescriptor();
if (targetType == null) {
MethodParameterMeta meta = (MethodParameterMeta) parameter;
targetType = new TypeDescriptor(new MethodParameter(meta.getMethod(), meta.getIndex()));
parameter.setTypeDescriptor(targetType);
if (parameter instanceof MethodParameterMeta) {
TypeDescriptor targetType = cache.computeIfAbsent(
(MethodParameterMeta) parameter,
k -> new TypeDescriptor(new MethodParameter(k.getMethod(), k.getIndex())));
TypeDescriptor sourceType = TypeDescriptor.forObject(value);
if (conversionService.canConvert(sourceType, targetType)) {
try {
return conversionService.convert(value, sourceType, targetType);
} catch (Throwable t) {
LOGGER.debug(
"Spring convert value '{}' from type [{}] to type [{}] failed",
value,
value.getClass(),
parameter.getGenericType(),
t);
}
}
}
TypeDescriptor sourceType = TypeDescriptor.forObject(value);
if (conversionService.canConvert(sourceType, targetType)) {
return conversionService.convert(value, sourceType, targetType);
Object target = tried ? null : typeConverter.convert(value, parameter.getGenericType());
if (target == null && value != null) {
throw new RestException(
Messages.ARGUMENT_CONVERT_ERROR,
parameter.getName(),
value,
value.getClass(),
parameter.getGenericType());
}
return typeConverter.convert(value, parameter.getGenericType());
return target;
}

@Override
Expand Down
Loading
Loading