You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2023/07/17 05:29:16 UTC
[dubbo] branch 3.3 updated: add rest provider body multipart json that JsonUtils supports ut (#12716)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.3 by this push:
new f78b4f5dea add rest provider body multipart json that JsonUtils supports ut (#12716)
f78b4f5dea is described below
commit f78b4f5deaea9405430bb3b895aaf31dd8d0cb30
Author: suncairong163 <10...@users.noreply.github.com>
AuthorDate: Mon Jul 17 13:29:10 2023 +0800
add rest provider body multipart json that JsonUtils supports ut (#12716)
---
.../AbstractNoAnnotatedParameterProcessor.java | 13 +++++++--
.../org/apache/dubbo/metadata/rest/ArgInfo.java | 11 +++++++
dubbo-rpc/dubbo-rpc-rest/pom.xml | 6 ++++
.../dubbo/rpc/protocol/rest/RestInvoker.java | 6 ++--
.../rest/annotation/ParamParserManager.java | 17 +++++------
.../consumer/inercept/RequestHeaderIntercept.java | 2 +-
.../parse/provider/BodyProviderParamParser.java | 3 +-
.../parse/provider/HeaderProviderParamParser.java | 1 -
.../NoAnnotationParamProviderParamParser.java | 14 ++++-----
.../rest/message/HttpMessageCodecManager.java | 5 ++--
.../protocol/rest/message/HttpMessageDecode.java | 7 +++--
.../rest/message/codec/ByteArrayCodec.java | 3 +-
.../rpc/protocol/rest/message/codec/JsonCodec.java | 15 ++++++----
.../rest/message/codec/MultiValueCodec.java | 4 +--
.../rest/message/codec/ResteasyResponseCodec.java | 9 ++++--
.../protocol/rest/message/codec/StringCodec.java | 3 +-
.../rpc/protocol/rest/message/codec/TextCodec.java | 3 +-
.../rpc/protocol/rest/message/codec/XMLCodec.java | 3 +-
.../rpc/protocol/rest/util/DataParseUtils.java | 3 +-
.../rest/util/NoAnnotationBodyParseUtil.java | 2 +-
.../rpc/protocol/rest/DataParseUtilsTest.java | 4 +--
.../dubbo/rpc/protocol/rest/DemoService.java | 21 +++++++++++++
.../dubbo/rpc/protocol/rest/DemoServiceImpl.java | 34 ++++++++++++++++++++--
.../protocol/rest/HttpMessageCodecManagerTest.java | 2 +-
.../rest/NoAnnotationRestProtocolTest.java | 25 +++++++++++++---
.../org/apache/dubbo/rpc/protocol/rest/User.java | 14 +++++++++
.../rest/noannotation/NoAnnotationDemoService.java | 6 +++-
.../noannotation/NoAnnotationDemoServiceImpl.java | 9 +++++-
28 files changed, 187 insertions(+), 58 deletions(-)
diff --git a/dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java b/dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java
index 4541e52761..b4975dc0c6 100644
--- a/dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java
+++ b/dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java
@@ -16,6 +16,7 @@
*/
package org.apache.dubbo.metadata.rest;
+import org.apache.dubbo.metadata.rest.jaxrs.JAXRSServiceRestMetadataResolver;
import org.apache.dubbo.metadata.rest.media.MediaType;
import java.lang.reflect.Parameter;
@@ -39,8 +40,16 @@ public abstract class AbstractNoAnnotatedParameterProcessor implements NoAnnotat
private boolean contentTypeSupport(RestMethodMetadata restMethodMetadata, MediaType mediaType, Class paramType) {
// @RequestParam String,number param
- if (mediaType.equals(MediaType.ALL_VALUE) && (String.class == paramType || paramType.isPrimitive() || Number.class.isAssignableFrom(paramType))) {
- return true;
+ if (mediaType.equals(MediaType.ALL_VALUE)) {
+ // jaxrs no annotation param is from http body
+ if (JAXRSServiceRestMetadataResolver.class.equals(restMethodMetadata.getCodeStyle())) {
+ return true;
+ }
+
+ // spring mvc no annotation param only is used by text data(string,number)
+ if (String.class == paramType || paramType.isPrimitive() || Number.class.isAssignableFrom(paramType)) {
+ return true;
+ }
}
Set<String> consumes = restMethodMetadata.getRequest().getConsumes();
diff --git a/dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java b/dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java
index a93b2e90e8..9c8a96550c 100644
--- a/dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java
+++ b/dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.metadata.rest;
import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
/**
* description of service method args info
@@ -42,6 +43,11 @@ public class ArgInfo {
*/
private Class paramType;
+ /**
+ * param actual Type(collection,map,array)
+ */
+ private Type actualType;
+
/**
* param name
*/
@@ -64,6 +70,7 @@ public class ArgInfo {
public ArgInfo(int index, Parameter parameter) {
this(index, parameter.getName(), parameter.getType());
+ this.actualType = parameter.getParameterizedType();
}
public ArgInfo() {
@@ -152,6 +159,10 @@ public class ArgInfo {
return this;
}
+ public Type actualReflectType() {
+ return actualType;
+ }
+
@Override
public String toString() {
return "ArgInfo{" +
diff --git a/dubbo-rpc/dubbo-rpc-rest/pom.xml b/dubbo-rpc/dubbo-rpc-rest/pom.xml
index e9fdd48a5b..62016fe4d7 100644
--- a/dubbo-rpc/dubbo-rpc-rest/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-rest/pom.xml
@@ -150,6 +150,12 @@
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-openfeign-core</artifactId>
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestInvoker.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestInvoker.java
index 09266c950a..a012dd8e44 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestInvoker.java
@@ -40,6 +40,7 @@ import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodecManager;
import org.apache.dubbo.rpc.protocol.rest.util.HttpHeaderUtil;
import org.apache.dubbo.rpc.protocol.rest.util.MediaTypeUtil;
+import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -100,9 +101,10 @@ public class RestInvoker<T> extends AbstractInvoker<T> {
} else if (responseCode >= 500) {
responseFuture.completeExceptionally(new RemoteServerInternalException(r.getMessage()));
} else if (responseCode < 400) {
- mediaType = MediaTypeUtil.convertMediaType(restMethodMetadata.getReflectMethod().getReturnType(), r.getContentType());
+ Method reflectMethod = restMethodMetadata.getReflectMethod();
+ mediaType = MediaTypeUtil.convertMediaType(reflectMethod.getReturnType(), r.getContentType());
Object value = HttpMessageCodecManager.httpMessageDecode(r.getBody(),
- restMethodMetadata.getReflectMethod().getReturnType(), mediaType);
+ reflectMethod.getReturnType(), reflectMethod.getGenericReturnType(), mediaType);
appResponse.setValue(value);
// resolve response attribute & attachment
HttpHeaderUtil.parseResponseHeader(appResponse, r);
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParserManager.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParserManager.java
index 90bea5b9ee..7f2ac44ec3 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParserManager.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/ParamParserManager.java
@@ -25,16 +25,15 @@ import org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.provider.BasePr
import org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.provider.ProviderParseContext;
import java.util.List;
-import java.util.Set;
public class ParamParserManager {
- private static final Set<BaseConsumerParamParser> consumerParamParsers =
- FrameworkModel.defaultModel().getExtensionLoader(BaseConsumerParamParser.class).getSupportedExtensionInstances();
+ private static final List<BaseConsumerParamParser> consumerParamParsers =
+ FrameworkModel.defaultModel().getExtensionLoader(BaseConsumerParamParser.class).getActivateExtensions();
- private static final Set<BaseProviderParamParser> providerParamParsers =
- FrameworkModel.defaultModel().getExtensionLoader(BaseProviderParamParser.class).getSupportedExtensionInstances();
+ private static final List<BaseProviderParamParser> providerParamParsers =
+ FrameworkModel.defaultModel().getExtensionLoader(BaseProviderParamParser.class).getActivateExtensions();
/**
* provider Design Description:
@@ -53,11 +52,11 @@ public class ParamParserManager {
for (int i = 0; i < args.size(); i++) {
for (BaseProviderParamParser paramParser : providerParamParsers) {
- if (!paramParser.matchParseType(args.get(i).getParamAnnotationType())) {
- continue;
+ if (paramParser.matchParseType(args.get(i).getParamAnnotationType())) {
+ paramParser.parse(parseContext, args.get(i));
+ // one arg only can be parsed by one parser
+ break;
}
-
- paramParser.parse(parseContext, args.get(i));
}
}
// TODO add param require or default & body arg size pre judge
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/RequestHeaderIntercept.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/RequestHeaderIntercept.java
index a2c1ce5abc..3ec4bbbaa8 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/RequestHeaderIntercept.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/consumer/inercept/RequestHeaderIntercept.java
@@ -49,7 +49,7 @@ public class RequestHeaderIntercept implements HttpConnectionPreBuildIntercept {
if (produces == null || produces.isEmpty()) {
requestTemplate.addHeader(RestHeaderEnum.ACCEPT.getHeader(), RestConstant.DEFAULT_ACCEPT);
} else {
- requestTemplate.addHeader(RestHeaderEnum.ACCEPT.getHeader(), produces);
+ requestTemplate.addHeaders(RestHeaderEnum.ACCEPT.getHeader(), produces);
}
// URL url = connectionCreateContext.getUrl();
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/BodyProviderParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/BodyProviderParamParser.java
index 9da9d428ea..a92d5cf51f 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/BodyProviderParamParser.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/BodyProviderParamParser.java
@@ -28,7 +28,6 @@ import org.apache.dubbo.rpc.protocol.rest.request.RequestFacade;
import org.apache.dubbo.rpc.protocol.rest.util.MediaTypeUtil;
-
/**
* body param parse
*/
@@ -43,7 +42,7 @@ public class BodyProviderParamParser extends ProviderParamParser {
try {
String contentType = parseContext.getRequestFacade().getHeader(RestHeaderEnum.CONTENT_TYPE.getHeader());
MediaType mediaType = MediaTypeUtil.convertMediaType(argInfo.getParamType(), contentType);
- Object param = HttpMessageCodecManager.httpMessageDecode(request.getInputStream(), argInfo.getParamType(), mediaType);
+ Object param = HttpMessageCodecManager.httpMessageDecode(request.getInputStream(), argInfo.getParamType(), argInfo.actualReflectType(), mediaType);
parseContext.setValueByIndex(argInfo.getIndex(), param);
} catch (Throwable e) {
throw new ParamParseException("dubbo rest protocol provider body param parser error: " + e.getMessage());
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/HeaderProviderParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/HeaderProviderParamParser.java
index 88d0abf4c3..43990a2d84 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/HeaderProviderParamParser.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/HeaderProviderParamParser.java
@@ -33,7 +33,6 @@ public class HeaderProviderParamParser extends ProviderParamParser {
@Override
protected void doParse(ProviderParseContext parseContext, ArgInfo argInfo) {
- //TODO MAP<String,String> convert
RequestFacade request = parseContext.getRequestFacade();
if (Map.class.isAssignableFrom(argInfo.getParamType())) {
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/NoAnnotationParamProviderParamParser.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/NoAnnotationParamProviderParamParser.java
index 7553ec5ba1..0970232d6b 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/NoAnnotationParamProviderParamParser.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/annotation/param/parse/provider/NoAnnotationParamProviderParamParser.java
@@ -21,13 +21,15 @@ import org.apache.dubbo.common.utils.JsonUtils;
import org.apache.dubbo.metadata.rest.ArgInfo;
import org.apache.dubbo.metadata.rest.ParamType;
import org.apache.dubbo.rpc.protocol.rest.constans.RestConstant;
-import org.apache.dubbo.rpc.protocol.rest.util.DataParseUtils;
/**
* body param parse
+ * users can custom NoAnnotationParamProviderParamParser
+ * and getParamType must return ParamType.PROVIDER_NO_ANNOTATION
+ * and order is smaller than NoAnnotationParamProviderParamParser`s order
*/
-@Activate(value = RestConstant.PROVIDER_NO_ANNOTATION)
+@Activate(value = RestConstant.PROVIDER_NO_ANNOTATION, order = Integer.MAX_VALUE)
public class NoAnnotationParamProviderParamParser extends ProviderParamParser {
@Override
@@ -39,13 +41,7 @@ public class NoAnnotationParamProviderParamParser extends ProviderParamParser {
Object arg = arrayArgs[index];
- Object convertArg = null;
-
- if (DataParseUtils.isTextType(argInfo.getParamType())) {
- convertArg = DataParseUtils.stringTypeConvert(argInfo.getParamType(), String.valueOf(arg));
- } else {
- convertArg = JsonUtils.toJavaObject(arg.toString(), argInfo.getParamType());
- }
+ Object convertArg = JsonUtils.toJavaObject(JsonUtils.toJson(arg), argInfo.actualReflectType());
parseContext.setValueByIndex(index, convertArg);
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodecManager.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodecManager.java
index 27b6ef57e7..eb34605eda 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodecManager.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageCodecManager.java
@@ -23,6 +23,7 @@ import org.apache.dubbo.rpc.protocol.rest.exception.UnSupportContentTypeExceptio
import org.apache.dubbo.rpc.protocol.rest.pair.MessageCodecResultPair;
import java.io.OutputStream;
+import java.lang.reflect.Type;
import java.util.Set;
public class HttpMessageCodecManager {
@@ -30,14 +31,14 @@ public class HttpMessageCodecManager {
FrameworkModel.defaultModel().getExtensionLoader(HttpMessageCodec.class).getSupportedExtensionInstances();
- public static Object httpMessageDecode(byte[] body, Class<?> type, MediaType mediaType) throws Exception {
+ public static Object httpMessageDecode(byte[] body, Class<?> type, Type actualType, MediaType mediaType) throws Exception {
if (body == null || body.length == 0) {
return null;
}
for (HttpMessageCodec httpMessageCodec : httpMessageCodecs) {
if (httpMessageCodec.contentTypeSupport(mediaType, type) || typeJudge(mediaType, type, httpMessageCodec)) {
- return httpMessageCodec.decode(body, type);
+ return httpMessageCodec.decode(body, type,actualType);
}
}
throw new UnSupportContentTypeException("UnSupport content-type :" + mediaType.value);
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageDecode.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageDecode.java
index cf3b639b33..b072a8a9c2 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageDecode.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/HttpMessageDecode.java
@@ -17,8 +17,11 @@
package org.apache.dubbo.rpc.protocol.rest.message;
-public interface HttpMessageDecode<InputStream>{
+import java.lang.reflect.Type;
+
+public interface HttpMessageDecode<InputStream> {
+
+ Object decode(InputStream body, Class<?> targetType,Type actualTYpe) throws Exception;
- Object decode(InputStream body, Class<?> targetType) throws Exception;
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ByteArrayCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ByteArrayCodec.java
index 85dea16e00..ff15fc5663 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ByteArrayCodec.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ByteArrayCodec.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.metadata.rest.media.MediaType;
import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec;
import java.io.OutputStream;
+import java.lang.reflect.Type;
/**
* body type is byte array
@@ -31,7 +32,7 @@ public class ByteArrayCodec implements HttpMessageCodec<byte[], OutputStream> {
@Override
- public Object decode(byte[] body, Class<?> targetType) throws Exception {
+ public Object decode(byte[] body, Class<?> targetType, Type type) throws Exception {
return body;
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java
index 8ff5f2b60f..96fde0a09a 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java
@@ -23,14 +23,15 @@ import org.apache.dubbo.metadata.rest.media.MediaType;
import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec;
import org.apache.dubbo.rpc.protocol.rest.message.MediaTypeMatcher;
import org.apache.dubbo.rpc.protocol.rest.util.DataParseUtils;
-import javax.ws.rs.core.Response;
+
import java.io.OutputStream;
+import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.Set;
/**
- * body is json
+ * body is json
*/
@Activate("json")
public class JsonCodec implements HttpMessageCodec<byte[], OutputStream> {
@@ -39,12 +40,11 @@ public class JsonCodec implements HttpMessageCodec<byte[], OutputStream> {
static {
unSupportClasses.add(byte[].class);
unSupportClasses.add(String.class);
- unSupportClasses.add(Response.class);
}
@Override
- public Object decode(byte[] body, Class<?> targetType) throws Exception {
- return DataParseUtils.jsonConvert(targetType, body);
+ public Object decode(byte[] body, Class<?> targetType, Type actualType) throws Exception {
+ return DataParseUtils.jsonConvert(actualType, body);
}
@Override
@@ -67,4 +67,9 @@ public class JsonCodec implements HttpMessageCodec<byte[], OutputStream> {
public void encode(OutputStream outputStream, Object unSerializedBody, URL url) throws Exception {
outputStream.write(JsonUtils.toJson(unSerializedBody).getBytes(StandardCharsets.UTF_8));
}
+
+
+ public static final void addUnSupportClass(Class<?> unSupportClass) {
+ unSupportClasses.add(unSupportClass);
+ }
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/MultiValueCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/MultiValueCodec.java
index b41955e8e9..ee11bb5954 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/MultiValueCodec.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/MultiValueCodec.java
@@ -26,6 +26,7 @@ import org.apache.dubbo.rpc.protocol.rest.util.DataParseUtils;
import java.io.OutputStream;
import java.lang.reflect.Field;
+import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -39,8 +40,7 @@ public class MultiValueCodec implements HttpMessageCodec<byte[], OutputStream> {
@Override
- public Object decode(byte[] body, Class<?> targetType) throws Exception {
- // TODO java bean get set convert
+ public Object decode(byte[] body, Class<?> targetType, Type type) throws Exception {
Object map = DataParseUtils.multipartFormConvert(body,targetType);
Map valuesMap = (Map) map;
if (Map.class.isAssignableFrom(targetType)) {
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ResteasyResponseCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ResteasyResponseCodec.java
index 31fe9e2db9..9717df88d7 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ResteasyResponseCodec.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/ResteasyResponseCodec.java
@@ -26,15 +26,18 @@ import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec;
import java.io.OutputStream;
import java.lang.reflect.Method;
+import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
-@Activate(onClass="javax.ws.rs.core.Response")
+@Activate(onClass = "javax.ws.rs.core.Response")
public class ResteasyResponseCodec implements HttpMessageCodec<byte[], OutputStream> {
private Class<?> responseClass;
- public ResteasyResponseCodec(){
+
+ public ResteasyResponseCodec() {
try {
responseClass = ClassUtils.forName("javax.ws.rs.core.Response");
+ JsonCodec.addUnSupportClass(responseClass);
} catch (Exception exception) {
responseClass = null;
}
@@ -56,7 +59,7 @@ public class ResteasyResponseCodec implements HttpMessageCodec<byte[], OutputStr
}
@Override
- public Object decode(byte[] body, Class<?> targetType) throws Exception {
+ public Object decode(byte[] body, Class<?> targetType, Type type) throws Exception {
if (null == body || body.length == 0) {
return null;
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/StringCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/StringCodec.java
index d30b2e5a11..726c007f67 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/StringCodec.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/StringCodec.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.metadata.rest.media.MediaType;
import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec;
import java.io.OutputStream;
+import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
/**
@@ -32,7 +33,7 @@ public class StringCodec implements HttpMessageCodec<byte[], OutputStream> {
@Override
- public Object decode(byte[] body, Class<?> targetType) throws Exception {
+ public Object decode(byte[] body, Class<?> targetType, Type type) throws Exception {
if (body == null || body.length == 0) {
return null;
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/TextCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/TextCodec.java
index 63c06876f8..69c4eaa35a 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/TextCodec.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/TextCodec.java
@@ -24,6 +24,7 @@ import org.apache.dubbo.rpc.protocol.rest.message.MediaTypeMatcher;
import org.apache.dubbo.rpc.protocol.rest.util.DataParseUtils;
import java.io.OutputStream;
+import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
/**
@@ -33,7 +34,7 @@ import java.nio.charset.StandardCharsets;
public class TextCodec implements HttpMessageCodec<byte[], OutputStream> {
@Override
- public Object decode(byte[] body, Class<?> targetType) throws Exception {
+ public Object decode(byte[] body, Class<?> targetType, Type type) throws Exception {
return DataParseUtils.stringTypeConvert(targetType, new String(body, StandardCharsets.UTF_8));
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/XMLCodec.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/XMLCodec.java
index d58fd9e8de..d24d27a85f 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/XMLCodec.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/XMLCodec.java
@@ -32,6 +32,7 @@ import javax.xml.transform.Source;
import javax.xml.transform.sax.SAXSource;
import java.io.OutputStream;
import java.io.StringReader;
+import java.lang.reflect.Type;
/**
* body content-type is xml
@@ -41,7 +42,7 @@ public class XMLCodec implements HttpMessageCodec<byte[], OutputStream> {
@Override
- public Object decode(byte[] body, Class<?> targetType) throws Exception {
+ public Object decode(byte[] body, Class<?> targetType, Type type) throws Exception {
SAXParserFactory spf = SAXParserFactory.newInstance();
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/DataParseUtils.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/DataParseUtils.java
index 4501c7972d..9737c152c4 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/DataParseUtils.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/DataParseUtils.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.utils.StringUtils;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Type;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;
@@ -151,7 +152,7 @@ public class DataParseUtils {
}
- public static Object jsonConvert(Class targetType, byte[] body) throws Exception {
+ public static Object jsonConvert(Type targetType, byte[] body) throws Exception {
return JsonUtils.toJavaObject(new String(body, StandardCharsets.UTF_8), targetType);
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/NoAnnotationBodyParseUtil.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/NoAnnotationBodyParseUtil.java
index c6abf12fef..11ecc4fc95 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/NoAnnotationBodyParseUtil.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/util/NoAnnotationBodyParseUtil.java
@@ -30,7 +30,7 @@ public class NoAnnotationBodyParseUtil {
try {
Class<?> objectArraysType = Object[].class;
MediaType mediaType = MediaTypeUtil.convertMediaType(objectArraysType, MediaType.APPLICATION_JSON_VALUE.value);
- Object[] params = (Object[]) HttpMessageCodecManager.httpMessageDecode(request.getInputStream(), objectArraysType, mediaType);
+ Object[] params = (Object[]) HttpMessageCodecManager.httpMessageDecode(request.getInputStream(), objectArraysType, objectArraysType, mediaType);
return params;
} catch (Throwable e) {
throw new ParamParseException("dubbo rest protocol provider body param parser error: " + e.getMessage());
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DataParseUtilsTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DataParseUtilsTest.java
index ae29327019..93b8ed9585 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DataParseUtilsTest.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DataParseUtilsTest.java
@@ -29,8 +29,8 @@ public class DataParseUtilsTest {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
DataParseUtils.writeJsonContent(User.getInstance(), byteArrayOutputStream);
- Assertions.assertEquals("{\"age\":18,\"id\":404,\"name\":\"dubbo\"}",
- new String(byteArrayOutputStream.toByteArray()));
+ Assertions.assertEquals("{\"age\":18,\"id\":404,\"name\":\"dubbo\"}".getBytes().length,
+ byteArrayOutputStream.toByteArray().length);
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java
index 85e61837d8..5ffa788828 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoService.java
@@ -31,6 +31,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
@Path("/demoService")
public interface DemoService {
@@ -128,4 +129,24 @@ public interface DemoService {
@Consumes({MediaType.APPLICATION_JSON})
User noBodyArg(User user);
+ @POST
+ @Path("/list")
+ List<User> list(List<User> users);
+
+ @POST
+ @Path("/set")
+ Set<User> set(Set<User> users);
+
+ @POST
+ @Path("/array")
+ User[] array(User[] users);
+
+ @POST
+ @Path("/stringMap")
+ Map<String, User> stringMap(Map<String,User> userMap);
+
+ @POST
+ @Path("/map")
+ Map<User, User> userMap(Map<User,User> userMap);
+
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java
index f5e7c2369a..ea385a9283 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/DemoServiceImpl.java
@@ -30,6 +30,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
@Path("/demoService")
public class DemoServiceImpl implements DemoService {
@@ -91,7 +92,7 @@ public class DemoServiceImpl implements DemoService {
}
@Override
- public List<String> testMapForm(MultivaluedMap<String,String> params) {
+ public List<String> testMapForm(MultivaluedMap<String, String> params) {
return params.get("form");
}
@@ -120,7 +121,7 @@ public class DemoServiceImpl implements DemoService {
@Path("/noIntHeader")
@Consumes({javax.ws.rs.core.MediaType.TEXT_PLAIN})
@Override
- public int noIntHeader(@HeaderParam("header")int header) {
+ public int noIntHeader(@HeaderParam("header") int header) {
return header;
}
@@ -128,7 +129,7 @@ public class DemoServiceImpl implements DemoService {
@Path("/noIntParam")
@Consumes({javax.ws.rs.core.MediaType.TEXT_PLAIN})
@Override
- public int noIntParam(@QueryParam("header")int header) {
+ public int noIntParam(@QueryParam("header") int header) {
return header;
}
@@ -156,4 +157,31 @@ public class DemoServiceImpl implements DemoService {
public static Map<String, Object> getAttachments() {
return context;
}
+
+
+ @Override
+ public List<User> list(List<User> users) {
+ return users;
+ }
+
+ @Override
+ public Set<User> set(Set<User> users) {
+ return users;
+ }
+
+ @Override
+ public User[] array(User[] users) {
+ return users;
+ }
+
+ @Override
+ public Map<String, User> stringMap(Map<String, User> userMap) {
+ return userMap;
+ }
+
+ @Override
+ public Map<User, User> userMap(Map<User, User> userMap) {
+ return userMap;
+ }
+
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/HttpMessageCodecManagerTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/HttpMessageCodecManagerTest.java
index 1f514ba8e5..b0f368e74b 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/HttpMessageCodecManagerTest.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/HttpMessageCodecManagerTest.java
@@ -37,7 +37,7 @@ public class HttpMessageCodecManagerTest {
HttpMessageCodecManager.httpMessageEncode(byteArrayOutputStream,
registrationResult, null, MediaType.TEXT_XML, null);
- Object o = HttpMessageCodecManager.httpMessageDecode(byteArrayOutputStream.toByteArray(), RegistrationResult.class, MediaType.TEXT_XML);
+ Object o = HttpMessageCodecManager.httpMessageDecode(byteArrayOutputStream.toByteArray(), RegistrationResult.class, RegistrationResult.class, MediaType.TEXT_XML);
Assertions.assertEquals(registrationResult, o);
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/NoAnnotationRestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/NoAnnotationRestProtocolTest.java
index 1d40f2c612..3d8ad1b2fe 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/NoAnnotationRestProtocolTest.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/NoAnnotationRestProtocolTest.java
@@ -17,7 +17,9 @@
package org.apache.dubbo.rpc.protocol.rest;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.utils.JsonUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.rpc.Exporter;
@@ -38,14 +40,14 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.util.Arrays;
+import java.util.List;
+
class NoAnnotationRestProtocolTest {
private final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension("rest");
private final ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
- private final int availablePort = NetUtils.getAvailablePort();
- private final URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + "/rest?interface=org.apache.dubbo.rpc.protocol.rest.noannotation.NoAnnotationDemoService");
private final ModuleServiceRepository repository = ApplicationModel.defaultModel().getDefaultModule().getServiceRepository();
- private static final String SERVER = "netty4";
@AfterEach
public void tearDown() {
@@ -54,6 +56,19 @@ class NoAnnotationRestProtocolTest {
}
@Test
+ void testJson() {
+ List<String> jsons = Arrays.asList("fastjson", "fastjson2", "jackson", "gson");
+ for (String json : jsons) {
+ new JsonUtils() {
+ public void clearJson() {
+ setJson(null);
+ }
+ }.clearJson();
+ System.setProperty(CommonConstants.PREFER_JSON_FRAMEWORK_NAME, json);
+ testRestProtocol();
+ }
+ }
+
void testRestProtocol() {
URL url = URL.valueOf("rest://127.0.0.1:" + NetUtils.getAvailablePort() + "/?version=1.0.0&interface=org.apache.dubbo.rpc.protocol.rest.noannotation.NoAnnotationDemoService");
@@ -72,9 +87,11 @@ class NoAnnotationRestProtocolTest {
result = client.hello(1, 2);
Assertions.assertEquals(3, result);
- User user = client.noBodyArg(User.getInstance());
+ User user = client.user(User.getInstance());
Assertions.assertEquals("invoked", user.getName());
+ Assertions.assertEquals(User.getInstance(),client.userList(Arrays.asList(User.getInstance())).get(0));
+
invoker.destroy();
exporter.unexport();
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/User.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/User.java
index bb16caea7d..b877e2072c 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/User.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/User.java
@@ -17,6 +17,7 @@
package org.apache.dubbo.rpc.protocol.rest;
import java.io.Serializable;
+import java.util.Objects;
/**
* User Entity
@@ -63,6 +64,19 @@ public class User implements Serializable {
return user;
}
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ User user = (User) o;
+ return Objects.equals(id, user.id) && Objects.equals(name, user.name) && Objects.equals(age, user.age);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(id, name, age);
+ }
+
@Override
public String toString() {
return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}';
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/noannotation/NoAnnotationDemoService.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/noannotation/NoAnnotationDemoService.java
index 5811819a27..8970ebaf2a 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/noannotation/NoAnnotationDemoService.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/noannotation/NoAnnotationDemoService.java
@@ -19,6 +19,8 @@ package org.apache.dubbo.rpc.protocol.rest.noannotation;
import org.apache.dubbo.rpc.protocol.rest.User;
+import java.util.List;
+
public interface NoAnnotationDemoService {
Integer hello(Integer a, Integer b);
@@ -27,6 +29,8 @@ public interface NoAnnotationDemoService {
String sayHello(String name);
- User noBodyArg(User user);
+ User user(User user);
+
+ List<User> userList(List<User> users);
}
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/noannotation/NoAnnotationDemoServiceImpl.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/noannotation/NoAnnotationDemoServiceImpl.java
index 77e63cef65..4160e51575 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/noannotation/NoAnnotationDemoServiceImpl.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/noannotation/NoAnnotationDemoServiceImpl.java
@@ -19,6 +19,8 @@ package org.apache.dubbo.rpc.protocol.rest.noannotation;
import org.apache.dubbo.rpc.protocol.rest.User;
+import java.util.List;
+
public class NoAnnotationDemoServiceImpl implements NoAnnotationDemoService {
@@ -39,8 +41,13 @@ public class NoAnnotationDemoServiceImpl implements NoAnnotationDemoService {
}
@Override
- public User noBodyArg(User user) {
+ public User user(User user) {
user.setName("invoked");
return user;
}
+
+ @Override
+ public List<User> userList(List<User> users) {
+ return users;
+ }
}