From 2932f09b28dabfc5aa13baa109dfbd212915eec3 Mon Sep 17 00:00:00 2001 From: suncairong163 <105478245+suncairong163@users.noreply.github.com> Date: Mon, 17 Jul 2023 13:28:59 +0800 Subject: [PATCH] add generic reflect type for collection,map,array json (#12732) --- ...AbstractNoAnnotatedParameterProcessor.java | 13 ++++- .../apache/dubbo/metadata/rest/ArgInfo.java | 13 ++++- .../dubbo/rpc/protocol/rest/RestInvoker.java | 6 ++- .../provider/BodyProviderParamParser.java | 3 +- .../rest/message/HttpMessageCodecManager.java | 5 +- .../rest/message/HttpMessageDecode.java | 7 ++- .../rest/message/codec/ByteArrayCodec.java | 3 +- .../rest/message/codec/JsonCodec.java | 14 +++-- .../rest/message/codec/MultiValueCodec.java | 4 +- .../message/codec/ResteasyResponseCodec.java | 9 ++-- .../rest/message/codec/StringCodec.java | 3 +- .../rest/message/codec/TextCodec.java | 3 +- .../protocol/rest/message/codec/XMLCodec.java | 3 +- .../protocol/rest/util/DataParseUtils.java | 3 +- .../dubbo/rpc/protocol/rest/DemoService.java | 21 ++++++++ .../rpc/protocol/rest/DemoServiceImpl.java | 34 ++++++++++-- .../rest/HttpMessageCodecManagerTest.java | 2 +- .../protocol/rest/JaxrsRestProtocolTest.java | 53 +++++++++++++++---- .../apache/dubbo/rpc/protocol/rest/User.java | 14 +++++ 19 files changed, 173 insertions(+), 40 deletions(-) diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java index 4541e52761..b4975dc0c6 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/AbstractNoAnnotatedParameterProcessor.java +++ b/dubbo-metadata/dubbo-metadata-api/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 consumes = restMethodMetadata.getRequest().getConsumes(); diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java index e4f9693083..9c8a96550c 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ArgInfo.java @@ -18,9 +18,10 @@ package org.apache.dubbo.metadata.rest; import java.lang.reflect.Parameter; +import java.lang.reflect.Type; /** - * description of service method args info + * description of service method args info */ public class ArgInfo { /** @@ -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/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 9adacf7a97..fe3a8e9f09 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 extends AbstractInvoker { } 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/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 294de98fcb..da4897e1ab 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/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{ +import java.lang.reflect.Type; + +public interface HttpMessageDecode { + + 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 { @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..2c295e2ce3 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 { @@ -39,12 +40,15 @@ public class JsonCodec implements HttpMessageCodec { static { unSupportClasses.add(byte[].class); unSupportClasses.add(String.class); - unSupportClasses.add(Response.class); + } + + public static void addUnSupportClass(Class unSupportClass) { + unSupportClasses.add(unSupportClass); } @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 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 { @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 { 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 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 { @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 { @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 { @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/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 list(List users); + + @POST + @Path("/set") + Set set(Set users); + + @POST + @Path("/array") + User[] array(User[] users); + + @POST + @Path("/stringMap") + Map stringMap(Map userMap); + + @POST + @Path("/map") + Map userMap(Map 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 testMapForm(MultivaluedMap params) { + public List testMapForm(MultivaluedMap 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 getAttachments() { return context; } + + + @Override + public List list(List users) { + return users; + } + + @Override + public Set set(Set users) { + return users; + } + + @Override + public User[] array(User[] users) { + return users; + } + + @Override + public Map stringMap(Map userMap) { + return userMap; + } + + @Override + public Map userMap(Map 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/JaxrsRestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java index fb4f32c64e..eed6639cd1 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/JaxrsRestProtocolTest.java @@ -59,8 +59,10 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import static org.apache.dubbo.remoting.Constants.SERVER_KEY; @@ -616,23 +618,23 @@ class JaxrsRestProtocolTest { @Test void testGetInvoker() { - Assertions.assertDoesNotThrow(()->{ - URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + "/rest?interface=org.apache.dubbo.rpc.protocol.rest.rest.TestGetInvokerService"); + Assertions.assertDoesNotThrow(() -> { + URL exportUrl = URL.valueOf("rest://127.0.0.1:" + availablePort + "/rest?interface=org.apache.dubbo.rpc.protocol.rest.rest.TestGetInvokerService"); - TestGetInvokerService server = new TestGetInvokerServiceImpl(); + TestGetInvokerService server = new TestGetInvokerServiceImpl(); - URL url = this.registerProvider(exportUrl, server, DemoService.class); + URL url = this.registerProvider(exportUrl, server, DemoService.class); - Exporter exporter = protocol.export(proxy.getInvoker(server, TestGetInvokerService.class, url)); + Exporter exporter = protocol.export(proxy.getInvoker(server, TestGetInvokerService.class, url)); - TestGetInvokerService invokerService = this.proxy.getProxy(protocol.refer(TestGetInvokerService.class, url)); + TestGetInvokerService invokerService = this.proxy.getProxy(protocol.refer(TestGetInvokerService.class, url)); - String invoker = invokerService.getInvoker(); - Assertions.assertEquals("success", invoker); + String invoker = invokerService.getInvoker(); + Assertions.assertEquals("success", invoker); - exporter.unexport(); - }); + exporter.unexport(); + }); } @Test @@ -689,6 +691,37 @@ class JaxrsRestProtocolTest { exporter.unexport(); } + @Test + void testCollectionResult() { + DemoService server = new DemoServiceImpl(); + + URL url = this.registerProvider(exportUrl, server, DemoService.class); + + URL nettyUrl = url.addParameter(SERVER_KEY, "netty"); + + Exporter exporter = protocol.export(proxy.getInvoker(server, DemoService.class, nettyUrl)); + + DemoService demoService = this.proxy.getProxy(protocol.refer(DemoService.class, nettyUrl)); + + + Assertions.assertEquals(User.getInstance(), demoService.list(Arrays.asList(User.getInstance())).get(0)); + + HashSet objects = new HashSet<>(); + objects.add(User.getInstance()); + Assertions.assertEquals(User.getInstance(), new ArrayList<>(demoService.set(objects)).get(0)); + + Assertions.assertEquals(User.getInstance(), demoService.array(objects.toArray(new User[0]))[0]); + + Map map = new HashMap<>(); + map.put("map", User.getInstance()); + Assertions.assertEquals(User.getInstance(), demoService.stringMap(map).get("map")); + + Map maps = new HashMap<>(); + maps.put(User.getInstance(), User.getInstance()); + Assertions.assertEquals(User.getInstance(), demoService.userMap(maps).get(User.getInstance())); + exporter.unexport(); + } + private URL registerProvider(URL url, Object impl, Class interfaceClass) { ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass); ProviderModel providerModel = new ProviderModel( 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 + '}';