Skip to content

Commit

Permalink
add generic reflect type for collection,map,array json (#12732)
Browse files Browse the repository at this point in the history
  • Loading branch information
suncairong163 authored Jul 17, 2023
1 parent 630e14a commit 2932f09
Show file tree
Hide file tree
Showing 19 changed files with 173 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -39,8 +40,16 @@ public boolean process(Parameter parameter, int parameterIndex, RestMethodMetada
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@


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 {
/**
Expand All @@ -42,6 +43,11 @@ public class ArgInfo {
*/
private Class paramType;

/**
* param actual Type(collection,map,array)
*/
private Type actualType;

/**
* param name
*/
Expand All @@ -64,6 +70,7 @@ public ArgInfo(int index, String name, Class paramType) {

public ArgInfo(int index, Parameter parameter) {
this(index, parameter.getName(), parameter.getType());
this.actualType = parameter.getParameterizedType();
}

public ArgInfo() {
Expand Down Expand Up @@ -152,6 +159,10 @@ public ArgInfo setFormContentType(boolean isFormContentType) {
return this;
}

public Type actualReflectType() {
return actualType;
}

@Override
public String toString() {
return "ArgInfo{" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
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;
Expand Down Expand Up @@ -100,9 +101,10 @@ protected Result doInvoke(Invocation invocation) {
} 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.apache.dubbo.rpc.protocol.rest.util.MediaTypeUtil;



/**
* body param parse
*/
Expand All @@ -43,7 +42,7 @@ protected void doParse(ProviderParseContext parseContext, ArgInfo argInfo) {
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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,22 @@
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 {
private static final Set<HttpMessageCodec> httpMessageCodecs =
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec;

import java.io.OutputStream;
import java.lang.reflect.Type;

/**
* body type is byte array
Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@
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> {
Expand All @@ -39,12 +40,15 @@ public class JsonCodec implements HttpMessageCodec<byte[], OutputStream> {
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

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;
Expand All @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,18 @@

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;
}
Expand All @@ -56,7 +59,7 @@ public MediaType contentType() {
}

@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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import org.apache.dubbo.rpc.protocol.rest.message.HttpMessageCodec;

import java.io.OutputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
Expand All @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.apache.dubbo.rpc.protocol.rest.util.DataParseUtils;

import java.io.OutputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
Expand All @@ -33,7 +34,7 @@
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));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import javax.xml.transform.sax.SAXSource;
import java.io.OutputStream;
import java.io.StringReader;
import java.lang.reflect.Type;

/**
* body content-type is xml
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
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;
Expand Down Expand Up @@ -151,7 +152,7 @@ public static byte[] objectTextConvertToByteArray(Object object) {

}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import javax.ws.rs.core.MultivaluedMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Path("/demoService")
public interface DemoService {
Expand Down Expand Up @@ -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);

}
Loading

0 comments on commit 2932f09

Please sign in to comment.