You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/01/18 03:43:21 UTC

[incubator-servicecomb-java-chassis] branch master updated (ea3e19b -> 7ad8ce2)

This is an automated email from the ASF dual-hosted git repository.

liubao pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git.


    from ea3e19b  SCB-221 update RestBodyHandler license
     new 5454d18  SCB-251 print method source when dynamic create method failed.
     new 39b9903  SCB-251 Object codec as json: byte[], so that protobuf can transfer Object.
     new 5a2eae7  SCB-251 json disable FAIL_ON_EMPTY_BEANS and FAIL_ON_UNKNOWN_PROPERTIES, so that have better compatibility.
     new 4c55a28  SCB-251 swagger generator disable Object restrict.
     new 7ad8ce2  SCB-251 add Object demo

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../common/javassist/JavassistUtils.java           |  13 +-
 .../codec/protobuf/utils/ProtobufSchemaUtils.java  |  46 ++++-
 .../protobuf/utils/TestProtobufSchemaUtils.java    |  16 ++
 .../common/rest/codec/RestObjectMapper.java        |   2 +
 .../jaxrs/client/CodeFirstRestTemplateJaxrs.java   |   6 +-
 .../servicecomb/demo/CodeFirstRestTemplate.java    |  84 +++++----
 .../org/apache/servicecomb/demo/EmptyObject.java   |   6 +-
 .../java/org/apache/servicecomb/demo/TestMgr.java  |   4 +
 .../client/CodeFirstRestTemplateSpringmvc.java     |  44 ++---
 .../springmvc/client/CodeFirstSprigmvcIntf.java    |  18 ++
 .../demo/springmvc/client/TestObject.java          | 196 +++++++++++++++++++++
 .../demo/springmvc/client/TestResponse.java        |  65 +++++++
 .../demo/springmvc/server/CodeFirstSpringmvc.java  |  39 +++-
 .../demo/springmvc/server/TemplateResponse.java    |  31 ----
 .../foundation/common/utils/JsonUtils.java         |  16 +-
 .../swagger/converter/ConverterMgr.java            |   3 +
 .../converter/model/ModelImplConverter.java        |   7 +
 .../ObjectPropertyConverter.java}                  |  13 +-
 .../swagger/extend/ModelResolverExt.java           |  12 --
 19 files changed, 480 insertions(+), 141 deletions(-)
 copy spring-boot-starter/spring-boot-starter-discovery/src/main/java/org/apache/servicecomb/springboot/starter/discovery/package-info.java => demo/demo-schema/src/main/java/org/apache/servicecomb/demo/EmptyObject.java (92%)
 create mode 100644 demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java
 create mode 100644 demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
 delete mode 100644 demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/TemplateResponse.java
 copy swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/{parameter/BodyParameterConverter.java => property/ObjectPropertyConverter.java} (74%)

-- 
To stop receiving notification emails like this one, please contact
['"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>'].

[incubator-servicecomb-java-chassis] 01/05: SCB-251 print method source when dynamic create method failed.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 5454d18f50bbec874f10f9aab6558907d322ec06
Author: wujimin <wu...@huawei.com>
AuthorDate: Thu Jan 18 00:15:46 2018 +0800

    SCB-251 print method source when dynamic create method failed.
---
 .../apache/servicecomb/common/javassist/JavassistUtils.java | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java
index 41cd844..f75247f 100644
--- a/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java
+++ b/common/common-javassist/src/main/java/org/apache/servicecomb/common/javassist/JavassistUtils.java
@@ -172,11 +172,16 @@ public final class JavassistUtils {
       }
 
       for (MethodConfig methodConfig : config.getMethodList()) {
-        CtMethod ctMethod = CtMethod.make(methodConfig.getSource(), ctClass);
-        if (methodConfig.getGenericSignature() != null) {
-          ctMethod.setGenericSignature(methodConfig.getGenericSignature());
+        try {
+          CtMethod ctMethod = CtMethod.make(methodConfig.getSource(), ctClass);
+          if (methodConfig.getGenericSignature() != null) {
+            ctMethod.setGenericSignature(methodConfig.getGenericSignature());
+          }
+          ctClass.addMethod(ctMethod);
+        } catch (CannotCompileException e) {
+          LOGGER.error("Failed to create method, source:\n{}.", methodConfig.getSource());
+          throw e;
         }
-        ctClass.addMethod(ctMethod);
       }
 
       LOGGER.info("generate {} in classLoader {}.", config.getClassName(), classLoader);

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-java-chassis] 02/05: SCB-251 Object codec as json: byte[], so that protobuf can transfer Object.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 39b9903d4a5b2c6105845848b919194e41dcd472
Author: wujimin <wu...@huawei.com>
AuthorDate: Thu Jan 18 00:17:08 2018 +0800

    SCB-251 Object codec as json: byte[], so that protobuf can transfer Object.
---
 .../codec/protobuf/utils/ProtobufSchemaUtils.java  | 46 +++++++++++++++++++++-
 .../protobuf/utils/TestProtobufSchemaUtils.java    | 16 ++++++++
 2 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ProtobufSchemaUtils.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ProtobufSchemaUtils.java
index 9006354..14fb7a3 100644
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ProtobufSchemaUtils.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ProtobufSchemaUtils.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.codec.protobuf.utils;
 
+import java.io.IOException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
 import java.lang.reflect.Type;
@@ -28,22 +29,60 @@ import java.util.concurrent.ConcurrentHashMap;
 import org.apache.servicecomb.codec.protobuf.utils.schema.WrapSchemaFactory;
 import org.apache.servicecomb.common.javassist.JavassistUtils;
 import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.foundation.common.utils.JsonUtils;
 import org.springframework.util.ClassUtils;
 
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
 
+import io.protostuff.Input;
+import io.protostuff.Output;
+import io.protostuff.Pipe;
 import io.protostuff.Schema;
+import io.protostuff.WireFormat.FieldType;
+import io.protostuff.runtime.DefaultIdStrategy;
+import io.protostuff.runtime.Delegate;
 import io.protostuff.runtime.ProtobufCompatibleUtils;
+import io.protostuff.runtime.RuntimeEnv;
 import io.protostuff.runtime.RuntimeSchema;
 
 public final class ProtobufSchemaUtils {
   private static volatile Map<String, WrapSchema> schemaCache = new ConcurrentHashMap<>();
 
   static {
+    initProtobufObjectCodec();
     ProtobufCompatibleUtils.init();
   }
 
+  protected static void initProtobufObjectCodec() {
+    ((DefaultIdStrategy) RuntimeEnv.ID_STRATEGY).registerDelegate(new Delegate<Object>() {
+      @Override
+      public FieldType getFieldType() {
+        return FieldType.BYTES;
+      }
+
+      @Override
+      public Object readFrom(Input input) throws IOException {
+        return JsonUtils.readValue(input.readByteArray(), Object.class);
+      }
+
+      @Override
+      public void writeTo(Output output, int number, Object value, boolean repeated) throws IOException {
+        output.writeByteArray(number, JsonUtils.writeValueAsBytes(value), false);
+      }
+
+      @Override
+      public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) throws IOException {
+        throw new IllegalStateException("not support.");
+      }
+
+      @Override
+      public Class<?> typeClass() {
+        return Object.class;
+      }
+    });
+  }
+
   private interface SchemaCreator {
     WrapSchema create() throws Exception;
   }
@@ -83,12 +122,15 @@ public final class ProtobufSchemaUtils {
   }
 
   private static boolean isNeedWrap(Class<?> cls) {
-    // protobuf不支持原子类型、enum、string、数组、collection等等作为msg,只有Object类型才可以
+    // protobuf不支持原子类型、enum、string、数组、collection等等作为msg
+    // 只有pojo类型才可以
+    // java.lang.Object也不可以,因为这可以是任意类型,结果不确定
     return ClassUtils.isPrimitiveOrWrapper(cls) || cls.isArray() || cls.isEnum()
         || String.class.isAssignableFrom(cls)
         || Collection.class.isAssignableFrom(cls)
         || Map.class.isAssignableFrom(cls)
-        || Date.class.isAssignableFrom(cls);
+        || Date.class.isAssignableFrom(cls)
+        || Object.class.equals(cls);
   }
 
   // 为了支持method args的场景,全部实现ProtobufMessageWrapper接口,有的场景有点浪费,不过无关紧要
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/utils/TestProtobufSchemaUtils.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/utils/TestProtobufSchemaUtils.java
index af9c5c7..883edb0 100644
--- a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/utils/TestProtobufSchemaUtils.java
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/utils/TestProtobufSchemaUtils.java
@@ -22,6 +22,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.servicecomb.common.javassist.FieldConfig;
+import org.hamcrest.Matchers;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -117,4 +118,19 @@ public class TestProtobufSchemaUtils {
 
     return schema.readObject(input);
   }
+
+  @Test
+  public void object() throws Exception {
+    WrapSchema schema = ProtobufSchemaUtils.getOrCreateSchema(Object.class);
+
+    LinkedBuffer linkedBuf = LinkedBuffer.allocate();
+    ProtobufOutput output = new ProtobufOutput(linkedBuf);
+    schema.writeObject(output, 1);
+
+    Input input = new ByteArrayInput(output.toByteArray(), false);
+    Object result = schema.readObject(input);
+
+    Assert.assertEquals(1, result);
+    Assert.assertThat(result, Matchers.instanceOf(Integer.class));
+  }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-java-chassis] 04/05: SCB-251 swagger generator disable Object restrict.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 4c55a28afaabfb0bbbb3b75b382f1820cbc35580
Author: wujimin <wu...@huawei.com>
AuthorDate: Thu Jan 18 00:20:06 2018 +0800

    SCB-251 swagger generator disable Object restrict.
---
 .../swagger/converter/ConverterMgr.java            |  3 ++
 .../converter/model/ModelImplConverter.java        |  7 +++++
 .../property/ObjectPropertyConverter.java          | 32 ++++++++++++++++++++++
 .../swagger/extend/ModelResolverExt.java           | 12 --------
 4 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/ConverterMgr.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/ConverterMgr.java
index c4ed1fb..672693a 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/ConverterMgr.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/ConverterMgr.java
@@ -33,6 +33,7 @@ import org.apache.servicecomb.swagger.converter.parameter.AbstractSerializablePa
 import org.apache.servicecomb.swagger.converter.parameter.BodyParameterConverter;
 import org.apache.servicecomb.swagger.converter.property.ArrayPropertyConverter;
 import org.apache.servicecomb.swagger.converter.property.MapPropertyConverter;
+import org.apache.servicecomb.swagger.converter.property.ObjectPropertyConverter;
 import org.apache.servicecomb.swagger.converter.property.RefPropertyConverter;
 import org.apache.servicecomb.swagger.converter.property.StringPropertyConverter;
 import org.apache.servicecomb.swagger.extend.property.ByteProperty;
@@ -67,6 +68,7 @@ import io.swagger.models.properties.FloatProperty;
 import io.swagger.models.properties.IntegerProperty;
 import io.swagger.models.properties.LongProperty;
 import io.swagger.models.properties.MapProperty;
+import io.swagger.models.properties.ObjectProperty;
 import io.swagger.models.properties.Property;
 import io.swagger.models.properties.RefProperty;
 import io.swagger.models.properties.StringProperty;
@@ -143,6 +145,7 @@ public final class ConverterMgr {
     converterMap.put(ArrayProperty.class, new ArrayPropertyConverter());
     converterMap.put(MapProperty.class, new MapPropertyConverter());
     converterMap.put(StringProperty.class, new StringPropertyConverter());
+    converterMap.put(ObjectProperty.class, new ObjectPropertyConverter());
 
     converterMap.put(ModelImpl.class, new ModelImplConverter());
     converterMap.put(RefModel.class, new RefModelConverter());
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ModelImplConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ModelImplConverter.java
index a0d09d6..60f4234 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ModelImplConverter.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/model/ModelImplConverter.java
@@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
 
 import io.swagger.models.ModelImpl;
 import io.swagger.models.Swagger;
+import io.swagger.models.properties.ObjectProperty;
 
 public class ModelImplConverter extends AbstractModelConverter {
   @Override
@@ -48,6 +49,12 @@ public class ModelImplConverter extends AbstractModelConverter {
           modelImpl.getAdditionalProperties());
     }
 
+    if (ObjectProperty.TYPE.equals(modelImpl.getType())
+        && modelImpl.getProperties() == null
+        && modelImpl.getName() == null) {
+      return TypeFactory.defaultInstance().constructType(Object.class);
+    }
+
     // 根据name、property动态生成class
     if (packageName == null) {
       throw new Error("packageName should not be null");
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ObjectPropertyConverter.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ObjectPropertyConverter.java
new file mode 100644
index 0000000..c35e0f6
--- /dev/null
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/converter/property/ObjectPropertyConverter.java
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.swagger.converter.property;
+
+import org.apache.servicecomb.swagger.converter.Converter;
+
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.type.TypeFactory;
+
+import io.swagger.models.Swagger;
+
+public class ObjectPropertyConverter implements Converter {
+  @Override
+  public JavaType convert(ClassLoader classLoader, String packageName, Swagger swagger, Object def) {
+    return TypeFactory.defaultInstance().constructType(Object.class);
+  }
+
+}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java
index 7748ef0..7f028ae 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/extend/ModelResolverExt.java
@@ -32,8 +32,6 @@ import org.apache.servicecomb.swagger.extend.property.creator.InputStreamPropert
 import org.apache.servicecomb.swagger.extend.property.creator.PartPropertyCreator;
 import org.apache.servicecomb.swagger.extend.property.creator.PropertyCreator;
 import org.apache.servicecomb.swagger.extend.property.creator.ShortPropertyCreator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.springframework.util.StringUtils;
 
 import com.fasterxml.jackson.databind.JavaType;
@@ -48,8 +46,6 @@ import io.swagger.models.properties.StringProperty;
 import io.swagger.util.Json;
 
 public class ModelResolverExt extends ModelResolver {
-  private static final Logger LOGGER = LoggerFactory.getLogger(ModelResolverExt.class);
-
   private Map<Class<?>, PropertyCreator> propertyCreatorMap = new HashMap<>();
 
   public ModelResolverExt() {
@@ -87,14 +83,6 @@ public class ModelResolverExt extends ModelResolver {
     }
 
     String msg = "Must be a concrete type.";
-    if (type.getRawClass().equals(Object.class)) {
-      LOGGER.warn("***********************");
-      LOGGER.warn(type.getRawClass().getName() + " have some potential problems when working with "
-          + "different platforms and transports. It's recommended to change your service definition. "
-          + "This feature will be removed without notice in the future.");
-      LOGGER.warn("***********************");
-    }
-
     if (type.isMapLikeType()) {
       Class<?> keyTypeClass = type.getKeyType().getRawClass();
       if (!String.class.equals(keyTypeClass)) {

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-java-chassis] 05/05: SCB-251 add Object demo

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 7ad8ce25d0462dcabac3bc4a8f7f3044cb8572a7
Author: wujimin <wu...@huawei.com>
AuthorDate: Thu Jan 18 00:23:19 2018 +0800

    SCB-251 add Object demo
---
 .../jaxrs/client/CodeFirstRestTemplateJaxrs.java   |   6 +-
 .../servicecomb/demo/CodeFirstRestTemplate.java    |  84 +++++----
 .../org/apache/servicecomb/demo/EmptyObject.java}  |  14 +-
 .../java/org/apache/servicecomb/demo/TestMgr.java  |   4 +
 .../client/CodeFirstRestTemplateSpringmvc.java     |  44 ++---
 .../springmvc/client/CodeFirstSprigmvcIntf.java    |  18 ++
 .../demo/springmvc/client/TestObject.java          | 196 +++++++++++++++++++++
 .../demo/springmvc/client/TestResponse.java        |  65 +++++++
 .../demo/springmvc/server/CodeFirstSpringmvc.java  |  39 +++-
 9 files changed, 386 insertions(+), 84 deletions(-)

diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
index d58b91e..935ad52 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/CodeFirstRestTemplateJaxrs.java
@@ -23,10 +23,10 @@ import org.springframework.web.client.RestTemplate;
 
 public class CodeFirstRestTemplateJaxrs extends CodeFirstRestTemplate {
   @Override
-  protected void testExtend(RestTemplate template, String cseUrlPrefix) {
-    super.testExtend(template, cseUrlPrefix);
-
+  protected void testAllTransport(String microserviceName, RestTemplate template, String cseUrlPrefix) {
     testDefaultPath(template, cseUrlPrefix);
+
+    super.testAllTransport(microserviceName, template, cseUrlPrefix);
   }
 
   private void testDefaultPath(RestTemplate template, String cseUrlPrefix) {
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
index ac8d82c..4512e59 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
@@ -40,46 +40,58 @@ import org.springframework.web.client.RestTemplate;
 import io.vertx.core.json.JsonObject;
 
 public class CodeFirstRestTemplate {
+  protected void changeTransport(String microserviceName, String transport) {
+    CseContext.getInstance().getConsumerProviderManager().setTransport(microserviceName, transport);
+    TestMgr.setMsg(microserviceName, transport);
+  }
+
   public void testCodeFirst(RestTemplate template, String microserviceName, String basePath) {
+    String cseUrlPrefix = "cse://" + microserviceName + basePath;
+    changeTransport(microserviceName, "highway");
+    testOnlyHighway(template, cseUrlPrefix);
+
+    changeTransport(microserviceName, Const.RESTFUL);
+    testOnlyRest(template, cseUrlPrefix);
+
     for (String transport : DemoConst.transports) {
-      CseContext.getInstance().getConsumerProviderManager().setTransport(microserviceName, transport);
-      TestMgr.setMsg(microserviceName, transport);
-
-      String cseUrlPrefix = "cse://" + microserviceName + basePath;
-
-      testExtend(template, cseUrlPrefix);
-
-      testCodeFirstUserMap(template, cseUrlPrefix);
-      testCodeFirstTextPlain(template, cseUrlPrefix);
-      testCodeFirstBytes(template, cseUrlPrefix);
-      testCseResponse(microserviceName, template, cseUrlPrefix);
-      testCodeFirstAddDate(template, cseUrlPrefix);
-
-      testCodeFirstAdd(template, cseUrlPrefix);
-      testCodeFirstAddString(template, cseUrlPrefix);
-      testCodeFirstIsTrue(template, cseUrlPrefix);
-      testCodeFirstSayHi2(template, cseUrlPrefix);
-      testCodeFirstSayHi(template, cseUrlPrefix);
-      testCodeFirstSaySomething(template, cseUrlPrefix);
-      //            testCodeFirstRawJsonString(template, cseUrlPrefix);
-      testCodeFirstSayHello(template, cseUrlPrefix);
-      testCodeFirstReduce(template, cseUrlPrefix);
-
-      // TODO: highway unsupported until JAV-394 completed
-      if (transport.equals("rest")) {
-        testOnlyRest(template, cseUrlPrefix);
-        // only rest transport will set trace id
-        testTraceIdOnNotSetBefore(template, cseUrlPrefix);
-      }
-
-      testTraceIdOnContextContainsTraceId(template, cseUrlPrefix);
-
-      testRawJson(template, cseUrlPrefix);
+      changeTransport(microserviceName, transport);
+      testAllTransport(microserviceName, template, cseUrlPrefix);
     }
   }
 
+  protected void testAllTransport(String microserviceName, RestTemplate template, String cseUrlPrefix) {
+    testCodeFirstUserMap(template, cseUrlPrefix);
+    testCodeFirstTextPlain(template, cseUrlPrefix);
+    testCodeFirstBytes(template, cseUrlPrefix);
+    testCseResponse(microserviceName, template, cseUrlPrefix);
+    testCodeFirstAddDate(template, cseUrlPrefix);
+
+    testCodeFirstAdd(template, cseUrlPrefix);
+    testCodeFirstAddString(template, cseUrlPrefix);
+    testCodeFirstIsTrue(template, cseUrlPrefix);
+    testCodeFirstSayHi2(template, cseUrlPrefix);
+    testCodeFirstSayHi(template, cseUrlPrefix);
+    testCodeFirstSaySomething(template, cseUrlPrefix);
+    //            testCodeFirstRawJsonString(template, cseUrlPrefix);
+    testCodeFirstSayHello(template, cseUrlPrefix);
+    testCodeFirstReduce(template, cseUrlPrefix);
+
+    testTraceIdOnContextContainsTraceId(template, cseUrlPrefix);
+
+    testRawJson(template, cseUrlPrefix);
+  }
+
+  protected void testOnlyHighway(RestTemplate template, String cseUrlPrefix) {
+
+  }
+
   protected void testOnlyRest(RestTemplate template, String cseUrlPrefix) {
+    // TODO: highway unsupported until JAV-394 completed
     testModelFieldIgnore(template, cseUrlPrefix);
+
+    // only rest transport will set trace id
+    testTraceIdOnNotSetBefore(template, cseUrlPrefix);
+
   }
 
   private void testCodeFirstUserMap(RestTemplate template, String cseUrlPrefix) {
@@ -152,10 +164,6 @@ public class CodeFirstRestTemplate {
     TestMgr.check(new Date(date.getTime() + seconds * 1000), result);
   }
 
-  protected void testExtend(RestTemplate template, String cseUrlPrefix) {
-
-  }
-
   protected void testCodeFirstAddString(RestTemplate template, String cseUrlPrefix) {
     ResponseEntity<String> responseEntity =
         template.exchange(cseUrlPrefix + "addstring?s=a&s=b",
@@ -233,7 +241,7 @@ public class CodeFirstRestTemplate {
   protected void testModelFieldIgnore(RestTemplate template, String cseUrlPrefix) {
     InputModelForTestIgnore input = new InputModelForTestIgnore("input_id_rest", "input_id_content",
         new Person("inputSomeone"), new JsonObject("{\"InputJsonKey\" : \"InputJsonValue\"}"), () -> {
-    });
+        });
     OutputModelForTestIgnore output = template
         .postForObject(cseUrlPrefix + "ignore", input, OutputModelForTestIgnore.class);
 
diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/TemplateResponse.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/EmptyObject.java
similarity index 78%
rename from demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/TemplateResponse.java
rename to demo/demo-schema/src/main/java/org/apache/servicecomb/demo/EmptyObject.java
index cf19bce..2c1baa4 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/TemplateResponse.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/EmptyObject.java
@@ -14,18 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package org.apache.servicecomb.demo;
 
-package org.apache.servicecomb.demo.springmvc.server;
+public class EmptyObject {
 
-public class TemplateResponse<T> {
-  private T value;
-
-  public T getValue() {
-    return value;
-  }
-
-  public void setValue(T value) {
-    this.value = value;
-  }
-  
 }
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java
index 1449ef5..c72bb36 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/TestMgr.java
@@ -40,6 +40,10 @@ public class TestMgr {
   }
 
   public static void check(Object expect, Object real) {
+    if (expect == real) {
+      return;
+    }
+
     String strExpect = String.valueOf(expect);
     String strReal = String.valueOf(real);
 
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
index b3c0053..9076f85 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstRestTemplateSpringmvc.java
@@ -35,10 +35,8 @@ import org.apache.servicecomb.demo.CodeFirstRestTemplate;
 import org.apache.servicecomb.demo.TestMgr;
 import org.apache.servicecomb.foundation.common.part.FilePart;
 import org.apache.servicecomb.provider.pojo.Invoker;
-import org.apache.servicecomb.provider.pojo.RpcReference;
 import org.apache.servicecomb.provider.springmvc.reference.CseHttpEntity;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
-import org.apache.servicecomb.swagger.invocation.Response;
 import org.springframework.core.io.FileSystemResource;
 import org.springframework.core.io.PathResource;
 import org.springframework.core.io.Resource;
@@ -66,8 +64,9 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
   private UploadStreamAndResource uploadStreamAndResource =
       Invoker.createProxy("springmvc", "codeFirst", UploadStreamAndResource.class);
 
-  @RpcReference(microserviceName = "springmvc", schemaId = "codeFirst")
-  private CodeFirstSprigmvcIntf intf;
+  private TestResponse testResponse = new TestResponse();
+
+  private TestObject testObject = new TestObject();
 
   @Override
   protected void testOnlyRest(RestTemplate template, String cseUrlPrefix) {
@@ -77,17 +76,30 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
       throw new IllegalStateException(e);
     }
 
+    testResponse.runRest();
+    testObject.runRest();
+
     super.testOnlyRest(template, cseUrlPrefix);
   }
 
   @Override
-  protected void testExtend(RestTemplate template, String cseUrlPrefix) {
-    super.testExtend(template, cseUrlPrefix);
+  protected void testOnlyHighway(RestTemplate template, String cseUrlPrefix) {
+    testResponse.runHighway();
+    testObject.runHighway();
+
+    super.testOnlyHighway(template, cseUrlPrefix);
+  }
+
+  @Override
+  protected void testAllTransport(String microserviceName, RestTemplate template, String cseUrlPrefix) {
+    testResponse.runAllTransport();
+    testObject.runAllTransport();
 
     testResponseEntity("springmvc", template, cseUrlPrefix);
     testCodeFirstTestForm(template, cseUrlPrefix);
-    testIntf();
     testFallback(template, cseUrlPrefix);
+
+    super.testAllTransport(microserviceName, template, cseUrlPrefix);
   }
 
   private void testUpload(RestTemplate template, String cseUrlPrefix) throws IOException {
@@ -167,24 +179,6 @@ public class CodeFirstRestTemplateSpringmvc extends CodeFirstRestTemplate {
     TestMgr.check(result, "mockedreslut");
   }
 
-  private void testIntf() {
-    Date date = new Date();
-
-    String srcName = RegistryUtils.getMicroservice().getServiceName();
-
-    ResponseEntity<Date> responseEntity = intf.responseEntity(date);
-    TestMgr.check(date, responseEntity.getBody());
-    TestMgr.check("h1v " + srcName, responseEntity.getHeaders().getFirst("h1"));
-    TestMgr.check("h2v " + srcName, responseEntity.getHeaders().getFirst("h2"));
-
-    checkStatusCode("springmvc", 202, responseEntity.getStatusCode());
-
-    Response cseResponse = intf.cseResponse();
-    TestMgr.check("User [name=nameA, age=100, index=0]", cseResponse.getResult());
-    TestMgr.check("h1v " + srcName, cseResponse.getHeaders().getFirst("h1"));
-    TestMgr.check("h2v " + srcName, cseResponse.getHeaders().getFirst("h2"));
-  }
-
   private void testResponseEntity(String microserviceName, RestTemplate template, String cseUrlPrefix) {
     Map<String, Object> body = new HashMap<>();
     Date date = new Date();
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSprigmvcIntf.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSprigmvcIntf.java
index e173873..12b6b54 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSprigmvcIntf.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/CodeFirstSprigmvcIntf.java
@@ -17,7 +17,13 @@
 package org.apache.servicecomb.demo.springmvc.client;
 
 import java.util.Date;
+import java.util.List;
+import java.util.Map;
 
+import javax.xml.ws.Holder;
+
+import org.apache.servicecomb.demo.EmptyObject;
+import org.apache.servicecomb.demo.server.User;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.springframework.http.ResponseEntity;
 
@@ -25,4 +31,16 @@ public interface CodeFirstSprigmvcIntf {
   ResponseEntity<Date> responseEntity(Date date);
 
   Response cseResponse();
+
+  Object testObject(Object input);
+
+  EmptyObject testEmpty(EmptyObject input);
+
+  Map<String, Object> testMapObject(Map<String, Object> input);
+
+  List<Object> testListObject(List<Object> input);
+
+  Holder<Object> testHolderObject(Holder<Object> input);
+
+  Holder<User> testGeneric(Holder<User> input);
 }
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java
new file mode 100644
index 0000000..9082005
--- /dev/null
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestObject.java
@@ -0,0 +1,196 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.demo.springmvc.client;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.ws.Holder;
+
+import org.apache.servicecomb.demo.EmptyObject;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.demo.server.User;
+import org.apache.servicecomb.provider.pojo.Invoker;
+import org.apache.servicecomb.provider.springmvc.reference.CseRestTemplate;
+import org.springframework.web.client.RestTemplate;
+
+public class TestObject {
+  private CodeFirstSprigmvcIntf intf;
+
+  private RestTemplate restTemplate = new CseRestTemplate();
+
+  private String prefix = "cse://springmvc/codeFirstSpringmvc";
+
+  public TestObject() {
+    intf = Invoker.createProxy("springmvc", "codeFirst", CodeFirstSprigmvcIntf.class);
+  }
+
+  public void runRest() {
+    testEmptyObject_rest();
+    testMapObject_rest();
+  }
+
+  public void runHighway() {
+    testEmptyObject_highway();
+    testMapObject_highway();
+  }
+
+  public void runAllTransport() {
+    testObject();
+    testListObject();
+    testHolderObject();
+    testGeneric();
+  }
+
+  @SuppressWarnings("unchecked")
+  private void testGeneric() {
+    Holder<User> holder = new Holder<>(new User());
+    Holder<User> result = intf.testGeneric(holder);
+    TestMgr.check("{name=nameA, age=100, index=0, names=null}", result.value);
+
+    result = restTemplate.postForObject(prefix + "/generic", holder, Holder.class);
+    TestMgr.check("{name=nameA, age=100, index=0, names=null}", result.value);
+  }
+
+  @SuppressWarnings("unchecked")
+  private void testHolderObject() {
+    Holder<Object> holder = new Holder<>("v");
+    Holder<Object> result = intf.testHolderObject(holder);
+    TestMgr.check("v", result.value);
+
+    result = restTemplate.postForObject(prefix + "/holderObject", holder, Holder.class);
+    TestMgr.check("v", result.value);
+  }
+
+  @SuppressWarnings("unchecked")
+  private void testListObject() {
+    List<Object> list = Collections.singletonList("v");
+    List<Object> result = intf.testListObject(list);
+    TestMgr.check("[v]", result);
+    TestMgr.check(ArrayList.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/listObject", list, List.class);
+    TestMgr.check("[v]", result);
+    TestMgr.check(ArrayList.class, result.getClass());
+  }
+
+  @SuppressWarnings("unchecked")
+  private void testMapObject_rest() {
+    Map<String, Object> map = Collections.singletonMap("k", "v");
+    Map<String, Object> result = intf.testMapObject(map);
+    TestMgr.check("{k=v}", result);
+    TestMgr.check(LinkedHashMap.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/mapObject", map, Map.class);
+    TestMgr.check("{k=v}", result);
+    TestMgr.check(LinkedHashMap.class, result.getClass());
+  }
+
+  @SuppressWarnings("unchecked")
+  private void testMapObject_highway() {
+    Map<String, Object> map = Collections.singletonMap("k", "v");
+    Map<String, Object> result = intf.testMapObject(map);
+    TestMgr.check("{k=v}", result);
+    TestMgr.check(HashMap.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/mapObject", map, Map.class);
+    TestMgr.check("{k=v}", result);
+    TestMgr.check(HashMap.class, result.getClass());
+  }
+
+  private void testEmptyObject_highway() {
+    // protobuf can not express empty/null
+    // everything empty will be null
+    EmptyObject result = intf.testEmpty(new EmptyObject());
+    TestMgr.check(null, result);
+
+    result = restTemplate.postForObject(prefix + "/emptyObject", new EmptyObject(), EmptyObject.class);
+    TestMgr.check(null, result);
+  }
+
+  private void testEmptyObject_rest() {
+    EmptyObject result = intf.testEmpty(new EmptyObject());
+    TestMgr.check(EmptyObject.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/emptyObject", new EmptyObject(), EmptyObject.class);
+    TestMgr.check(EmptyObject.class, result.getClass());
+  }
+
+  @SuppressWarnings("unchecked")
+  private void testObject() {
+    // int
+    Object result = intf.testObject(1);
+    TestMgr.check(1, result);
+    TestMgr.check(Integer.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/object", 1, Integer.class);
+    TestMgr.check(1, result);
+    TestMgr.check(Integer.class, result.getClass());
+
+    // string
+    result = intf.testObject("str");
+    TestMgr.check("str", result);
+    TestMgr.check(String.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/object", "str", String.class);
+    TestMgr.check("str", result);
+    TestMgr.check(String.class, result.getClass());
+
+    // emptyObject
+    result = intf.testObject(new EmptyObject());
+    TestMgr.check("{}", result);
+    TestMgr.check(LinkedHashMap.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/object", new EmptyObject(), EmptyObject.class);
+    TestMgr.check("{}", result);
+    TestMgr.check(LinkedHashMap.class, result.getClass());
+
+    // map
+    Map<String, String> map = Collections.singletonMap("k", "v");
+    result = intf.testObject(map);
+    TestMgr.check("{k=v}", result);
+    TestMgr.check(LinkedHashMap.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/object", map, Map.class);
+    TestMgr.check("{k=v}", result);
+    TestMgr.check(LinkedHashMap.class, result.getClass());
+
+    // list
+    List<String> list = Collections.singletonList("v");
+    result = intf.testObject(list);
+    TestMgr.check("[v]", result);
+    TestMgr.check(ArrayList.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/object", list, List.class);
+    TestMgr.check("[v]", result);
+    TestMgr.check(ArrayList.class, result.getClass());
+
+    // generic
+    Holder<String> holder = new Holder<>("v");
+    result = intf.testObject(holder);
+    TestMgr.check("v", ((Map<String, String>) result).get("value"));
+    TestMgr.check(LinkedHashMap.class, result.getClass());
+
+    result = restTemplate.postForObject(prefix + "/object", holder, Holder.class);
+    TestMgr.check("v", ((Map<String, String>) result).get("value"));
+    TestMgr.check(LinkedHashMap.class, result.getClass());
+  }
+}
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
new file mode 100644
index 0000000..4036bed
--- /dev/null
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestResponse.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicecomb.demo.springmvc.client;
+
+import java.util.Date;
+
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.provider.pojo.Invoker;
+import org.apache.servicecomb.serviceregistry.RegistryUtils;
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.springframework.http.ResponseEntity;
+
+public class TestResponse {
+  private CodeFirstSprigmvcIntf intf;
+
+  public TestResponse() {
+    intf = Invoker.createProxy("springmvc", "codeFirst", CodeFirstSprigmvcIntf.class);
+  }
+
+  public void runRest() {
+  }
+
+  public void runHighway() {
+  }
+
+  public void runAllTransport() {
+    testResponseEntity();
+    testCseResponse();
+  }
+
+  private void testCseResponse() {
+    String srcName = RegistryUtils.getMicroservice().getServiceName();
+    Response cseResponse = intf.cseResponse();
+    TestMgr.check("User [name=nameA, age=100, index=0]", cseResponse.getResult());
+    TestMgr.check("h1v " + srcName, cseResponse.getHeaders().getFirst("h1"));
+    TestMgr.check("h2v " + srcName, cseResponse.getHeaders().getFirst("h2"));
+  }
+
+  private void testResponseEntity() {
+    Date date = new Date();
+
+    String srcName = RegistryUtils.getMicroservice().getServiceName();
+
+    ResponseEntity<Date> responseEntity = intf.responseEntity(date);
+    TestMgr.check(date, responseEntity.getBody());
+    TestMgr.check("h1v " + srcName, responseEntity.getHeaders().getFirst("h1"));
+    TestMgr.check("h2v " + srcName, responseEntity.getHeaders().getFirst("h2"));
+
+    TestMgr.check(202, responseEntity.getStatusCode());
+  }
+}
diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
index 7286bf3..aceba90 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/CodeFirstSpringmvc.java
@@ -28,10 +28,12 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.Part;
 import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Response.Status;
+import javax.xml.ws.Holder;
 
 import org.apache.commons.io.IOUtils;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.core.Const;
+import org.apache.servicecomb.demo.EmptyObject;
 import org.apache.servicecomb.demo.compute.Person;
 import org.apache.servicecomb.demo.ignore.InputModelForTestIgnore;
 import org.apache.servicecomb.demo.ignore.OutputModelForTestIgnore;
@@ -161,11 +163,6 @@ public class CodeFirstSpringmvc {
     return userMap;
   }
 
-  @RequestMapping(path = "/testUserMapGeneric", method = RequestMethod.POST)
-  public TemplateResponse<String> testUserMapGeneric(@RequestBody Map<String, User> userMap) {
-    return null;
-  }
-
   @RequestMapping(path = "/textPlain", method = RequestMethod.POST, consumes = MediaType.TEXT_PLAIN_VALUE)
   public String textPlain(@RequestBody String body) {
     return body;
@@ -308,7 +305,7 @@ public class CodeFirstSpringmvc {
     return new OutputModelForTestIgnore("output_id", input.getInputId(), input.getContent(), input.getInputObject(),
         input.getInputJsonObject(), input.getInputIgnoreInterface(),
         new Person("outputSomeone"), new JsonObject("{\"OutputJsonKey\" : \"OutputJsonValue\"}"), () -> {
-    });
+        });
   }
 
   @SuppressWarnings("unchecked")
@@ -364,4 +361,34 @@ public class CodeFirstSpringmvc {
   public String getTraceId() {
     return ContextUtils.getInvocationContext().getContext(Const.TRACE_ID_NAME);
   }
+
+  @PostMapping(path = "/emptyObject")
+  public EmptyObject testEmpty(@RequestBody EmptyObject input) {
+    return input;
+  }
+
+  @PostMapping(path = "/object")
+  public Object testObject(@RequestBody Object input) {
+    return input;
+  }
+
+  @PostMapping(path = "/mapObject")
+  public Map<String, Object> testMapObject(@RequestBody Map<String, Object> input) {
+    return input;
+  }
+
+  @PostMapping(path = "/listObject")
+  public List<Object> testListObject(@RequestBody List<Object> input) {
+    return input;
+  }
+
+  @PostMapping(path = "/holderObject")
+  public Holder<Object> testHolderObject(@RequestBody Holder<Object> input) {
+    return input;
+  }
+
+  @PostMapping(path = "/generic")
+  public Holder<User> testGeneric(@RequestBody Holder<User> input) {
+    return input;
+  }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.

[incubator-servicecomb-java-chassis] 03/05: SCB-251 json disable FAIL_ON_EMPTY_BEANS and FAIL_ON_UNKNOWN_PROPERTIES, so that have better compatibility.

Posted by li...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-java-chassis.git

commit 5a2eae7d6200cab68ced97a1311b3e2330a9effc
Author: wujimin <wu...@huawei.com>
AuthorDate: Thu Jan 18 00:18:51 2018 +0800

    SCB-251 json disable FAIL_ON_EMPTY_BEANS and FAIL_ON_UNKNOWN_PROPERTIES, so that have better compatibility.
---
 .../servicecomb/common/rest/codec/RestObjectMapper.java  |  2 ++
 .../servicecomb/foundation/common/utils/JsonUtils.java   | 16 +++++-----------
 2 files changed, 7 insertions(+), 11 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
index b82e1a5..3e27916 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapper.java
@@ -21,6 +21,7 @@ import com.fasterxml.jackson.core.JsonParser.Feature;
 import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
 import com.fasterxml.jackson.databind.type.TypeFactory;
 import com.fasterxml.jackson.databind.util.ISO8601DateFormat;
 
@@ -36,6 +37,7 @@ public final class RestObjectMapper extends ObjectMapper {
     setDateFormat(new ISO8601DateFormat());
     getFactory().disable(Feature.AUTO_CLOSE_SOURCE);
     disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+    disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
   }
 
   public String convertToString(Object value) throws Exception {
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JsonUtils.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JsonUtils.java
index 087034c..75c7b36 100644
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JsonUtils.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/JsonUtils.java
@@ -21,30 +21,24 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 
-import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonGenerationException;
 import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
 
 public final class JsonUtils {
   public static final ObjectMapper OBJ_MAPPER;
 
   static {
-    //如果待转换的字符串比较随机,这个缓存很容易就填满,会导致同步清空缓存,对性能有影响
-    JsonFactory jsonFactory = new JsonFactory();
-    jsonFactory.configure(JsonFactory.Feature.INTERN_FIELD_NAMES, false);
-    OBJ_MAPPER = new ObjectMapper(jsonFactory);
+    OBJ_MAPPER = new ObjectMapper();
+    OBJ_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
+    OBJ_MAPPER.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
   }
 
-  //    static
-  //    {
-  //        //设置反序列化时忽略json字符串中存在而Java对象实际没有的属性
-  //        om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
-  //    }
-
   private JsonUtils() {
   }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@servicecomb.apache.org" <co...@servicecomb.apache.org>.