Skip to content

Commit

Permalink
Generic param support
Browse files Browse the repository at this point in the history
  • Loading branch information
oxsean committed Jul 25, 2024
1 parent e9d829c commit b5bd138
Show file tree
Hide file tree
Showing 42 changed files with 722 additions and 218 deletions.
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

0 comments on commit b5bd138

Please sign in to comment.