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/08/17 02:23:49 UTC

[incubator-servicecomb-java-chassis] branch master updated (e698efa -> 1f5b661)

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 e698efa  [SCB-846] optimize code
     new 8e8a3ec  [SCB-847]Provide a way to decode user's custom error data
     new a0131f0  [SCB-847]fix test errors and deal with error code override
     new fa9ff76  [SCB-847]fix container error code handling logic
     new e66da4a  [SCB-847]fix integration test error
     new 8b9ea35  [SCB-847]fix default value feature for primitive bugs.
     new 44cd5bc  [SCB-847]support client not write null value and server write null value.
     new a23edf2  [SCB-847]fix it fail
     new 9f18a56  [SCB-847]add validation related test case
     new 9e99226  [SCB-847]change mapper to two categories
     new 1f5b661  [SCB-847]fix compile fail

The 10 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/rest/codec/RestObjectMapperFactory.java | 10 +++
 .../rest/codec/param/BodyProcessorCreator.java     |  7 +-
 .../rest/codec/param/CookieProcessorCreator.java   |  3 +-
 .../rest/codec/param/HeaderProcessorCreator.java   |  3 +-
 .../rest/codec/param/ParamValueProcessor.java      |  3 +-
 .../rest/codec/produce/ProduceJsonProcessor.java   |  3 +-
 .../error/CustomExceptionToResponseConverter.java  | 24 ++++---
 .../demo/edge/business/error/ErrorData.java}       | 22 +++----
 .../demo/edge/business/error/ErrorService.java}    | 33 ++++++----
 .../business/error/IllegalStateErrorData.java}     | 32 ++++-----
 ...vocation.exception.ExceptionToResponseConverter |  5 +-
 .../servicecomb/demo/edge/consumer/Consumer.java   | 29 ++++++++
 .../edge/service/CustomResponseMetaMapper.java     | 31 +++++----
 .../demo/edge/service/IllegalStateErrorData.java}  | 32 ++++-----
 ...swagger.invocation.response.ResponseMetaMapper} |  3 +-
 .../servicecomb/demo/jaxrs/client/JaxrsClient.java | 38 ++++++++---
 .../jaxrs/client/pojoDefault/DefaultModel.java     | 14 ++--
 .../pojoDefault/DefaultModelServiceClient.java     | 46 +++++++++++++
 .../client/validation/ValidationServiceClient.java | 77 ++++++++++++++++++++++
 .../server/pojoDefault/DefaultResponseModel.java}  | 53 +++++++++------
 .../demo/jaxrs/server/JaxRSDefaultValues.java      | 22 +++++++
 .../servicecomb/demo/jaxrs/server/JaxrsServer.java |  5 +-
 .../server/pojoDefault/DefaultModelService.java    | 24 ++++---
 .../server/pojoDefault/DefaultRequestModel.java}   | 53 +++++++++------
 .../server/pojoDefault/DefaultResponseModel.java}  | 53 +++++++++------
 .../jaxrs/server/validation/ValidationService.java | 31 ++++-----
 ...tObjectMapperWithStringMapperNotWriteNull.java} | 26 ++------
 .../server/validation/ValidationModel.java}        | 43 ++++++------
 .../resources/microservices/jaxrs/compute.yaml     |  1 +
 .../main/resources/microservices/pojo/server.yaml  |  1 +
 .../springboot/jaxrs/client/JaxrsClient.java       |  5 +-
 .../springboot/jaxrs/server/JaxrsServer.java       |  4 +-
 .../main/resources/microservices/pojo/server.yaml  |  1 +
 .../demo/springmvc/client/SpringmvcClient.java     |  8 ++-
 .../springmvc/server/SpringMvcDefaultValues.java   | 34 ++++++++--
 .../swagger/generator/core/OperationGenerator.java | 34 ++++------
 .../invocation/response/ResponseMetaMapper.java    |  8 ++-
 .../swagger/invocation/response/ResponsesMeta.java | 34 ++++++++--
 .../invocation/response/TestResponsesMeta.java     | 11 ++--
 .../rest/client/http/DefaultHttpClientFilter.java  |  8 ++-
 .../client/http/TestDefaultHttpClientFilter.java   | 25 +++++--
 41 files changed, 609 insertions(+), 290 deletions(-)
 copy swagger/swagger-invocation/invocation-validator/src/main/java/org/apache/servicecomb/swagger/invocation/validator/ConstraintViolationExceptionToResponseConverter.java => demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/CustomExceptionToResponseConverter.java (64%)
 copy demo/{demo-schema/src/main/java/org/apache/servicecomb/demo/multiErrorCode/MultiRequest.java => demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorData.java} (83%)
 copy demo/{demo-spring-boot-discovery/demo-spring-boot-discovery-server/src/main/java/org/apache/servicecomb/demo/discovery/server/GreetingController.java => demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorService.java} (57%)
 copy demo/{demo-schema/src/main/java/org/apache/servicecomb/demo/multiErrorCode/MultiResponse500.java => demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/IllegalStateErrorData.java} (74%)
 copy core/src/test/resources/config/log4j.demo.properties => demo/demo-edge/business-2.0.0/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter (90%)
 copy swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/consumer/CseResponseConsumerResponseMapperFactory.java => demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/CustomResponseMetaMapper.java (57%)
 copy demo/{demo-schema/src/main/java/org/apache/servicecomb/demo/multiErrorCode/MultiResponse500.java => demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/IllegalStateErrorData.java} (75%)
 copy demo/{demo-spring-boot-discovery/demo-spring-boot-discovery-server/src/main/resources/application.properties => demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper} (92%)
 copy core/src/test/java/org/apache/servicecomb/core/provider/Person.java => demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModel.java (79%)
 create mode 100644 demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModelServiceClient.java
 create mode 100644 demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
 copy demo/{demo-spring-boot-transport/demo-spring-boot-pojo-client/src/main/java/org/apache/servicecomb/demo/server/User.java => demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java} (65%)
 copy archetypes/business-service-jaxrs/src/main/resources/archetype-resources/src/main/java/HelloImpl.java => demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultModelService.java (63%)
 copy demo/{demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/server/User.java => demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultRequestModel.java} (65%)
 copy demo/{demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/java/org/apache/servicecomb/demo/server/User.java => demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java} (65%)
 copy integration-tests/jaxrs-tests/src/test/java/org/apache/servicecomb/demo/jaxrs/tests/endpoints/EnglishGreetingRestEndpoint.java => demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationService.java (65%)
 copy demo/demo-schema/src/main/java/org/apache/servicecomb/demo/{RestObjectMapperWithStringMapper.java => RestObjectMapperWithStringMapperNotWriteNull.java} (68%)
 copy demo/demo-schema/src/main/java/org/apache/servicecomb/demo/{validator/Student.java => jaxrs/server/validation/ValidationModel.java} (71%)
 copy service-registry/src/main/java/org/apache/servicecomb/serviceregistry/registry/ServiceRegistryTaskInitializer.java => swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMetaMapper.java (83%)


[incubator-servicecomb-java-chassis] 05/10: [SCB-847]fix default value feature for primitive bugs.

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 8b9ea359760624c086f1e5fa373b7cc6f944334a
Author: liubao <ba...@huawei.com>
AuthorDate: Thu Aug 16 13:27:03 2018 +0800

    [SCB-847]fix default value feature for primitive bugs.
---
 .../servicecomb/demo/jaxrs/client/JaxrsClient.java | 11 ++++---
 .../demo/jaxrs/server/JaxRSDefaultValues.java      | 22 ++++++++++++++
 .../demo/springmvc/client/SpringmvcClient.java     |  5 +++-
 .../springmvc/server/SpringMvcDefaultValues.java   | 34 ++++++++++++++++++----
 .../swagger/generator/core/OperationGenerator.java | 31 +++++++++-----------
 5 files changed, 76 insertions(+), 27 deletions(-)

diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
index ac13405..71407ef 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
@@ -296,7 +296,7 @@ public class JaxrsClient {
       // Message dependends on locale, so just check the short part.
       // 'must be greater than or equal to 20', propertyPath=add.arg1, rootBeanClass=class org.apache.servicecomb.demo.jaxrs.server.Validator, messageTemplate='{javax.validation.constraints.Min.message}'}]]
       // ignored
-      Map data = (Map)e.getErrorData();
+      Map data = (Map) e.getErrorData();
       TestMgr.check(
           "[ConstraintViolationImpl{interpolatedMessage=",
           data.get("message").toString().substring(0,
@@ -324,7 +324,7 @@ public class JaxrsClient {
       TestMgr.check(400, e.getStatus().getStatusCode());
       TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());
       // Message dependends on locale, so just check the short part.
-      Map data = (Map)e.getErrorData();
+      Map data = (Map) e.getErrorData();
       TestMgr.check(
           "[ConstraintViolationImpl{interpolatedMessage=",
           data.get("message").toString().substring(0,
@@ -359,7 +359,7 @@ public class JaxrsClient {
       TestMgr.check(400, e.getStatus().getStatusCode());
       TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());
       // Message dependends on locale, so just check the short part.
-      Map data = (Map)e.getErrorData();
+      Map data = (Map) e.getErrorData();
       TestMgr.check(
           "[ConstraintViolationImpl{interpolatedMessage",
           data.get("message").toString().substring(0,
@@ -438,6 +438,9 @@ public class JaxrsClient {
     TestMgr.check("Hello", result);
 
     result = template.postForObject(cseUrlPrefix + "/javaprimitivecomb", request, String.class);
-    TestMgr.check("Hello 00.0", result);
+    TestMgr.check("Hello nullnull", result);
+
+    result = template.postForObject(cseUrlPrefix + "/allprimitivetypes", null, String.class);
+    TestMgr.check("Hello false,0,0,0,0,0,0.0,0.0,null", result);
   }
 }
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java
index aa8f461..5a2788e 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java
@@ -118,4 +118,26 @@ public class JaxRSDefaultValues {
   public String jaxRsJavaPrimitiveCombnation(@QueryParam("a") Integer a, @QueryParam("b") Float b) {
     return "Hello " + a + b;
   }
+
+  @Path("/allprimitivetypes")
+  @POST
+  public String allprimitivetypes(@QueryParam("pBoolean") boolean pBoolean,
+      @QueryParam("pChar") char pChar,
+      @QueryParam("pByte") byte pByte,
+      @QueryParam("pShort") short pShort,
+      @QueryParam("pInt") int pInt,
+      @QueryParam("pLong") long pLong,
+      @QueryParam("pFloat") float pFloat,
+      @QueryParam("pDouble") double pDouble,
+      @QueryParam("pDoubleWrap") Double pDoubleWrap) {
+    return "Hello " + pBoolean + ","
+        + pChar + ","
+        + pByte + ","
+        + pShort + ","
+        + pInt + ","
+        + pLong + ","
+        + pFloat + ","
+        + pDouble + ","
+        + pDoubleWrap;
+  }
 }
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index d9bd62c..37aa870 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -363,6 +363,9 @@ public class SpringmvcClient {
     TestMgr.check("Hello", result);
 
     result = template.postForObject(cseUrlPrefix + "/javaprimitivecomb", null, String.class);
-    TestMgr.check("Hello 00.0", result);
+    TestMgr.check("Hello nullnull", result);
+
+    result = template.postForObject(cseUrlPrefix + "/allprimitivetypes", null, String.class);
+    TestMgr.check("Hello false,0,0,0,0,0,0.0,0.0,null", result);
   }
 }
diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
index 1c99505..d6b33eb 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
@@ -52,7 +52,8 @@ public class SpringMvcDefaultValues {
   }
 
   @GetMapping("/query2")
-  public String query2(@RequestParam(name = "e", required = false) int e, @RequestParam(name = "a", defaultValue = "20") int a,
+  public String query2(@RequestParam(name = "e", required = false) int e,
+      @RequestParam(name = "a", defaultValue = "20") int a,
       @RequestParam(name = "b", defaultValue = "bobo") String b,
       @RequestParam(name = "c", defaultValue = "40") Integer c,
       @Min(value = 20) @Max(value = 30) @RequestParam(name = "d", required = false) int d) {
@@ -71,21 +72,44 @@ public class SpringMvcDefaultValues {
   }
 
   @PostMapping("/javaprimitivenumber")
-  public String springJavaPrimitiveNumber(@RequestParam(name = "a", required = false) float a, @RequestParam(name = "b", required = false) boolean b) {
+  public String springJavaPrimitiveNumber(@RequestParam(name = "a", required = false) float a,
+      @RequestParam(name = "b", required = false) boolean b) {
     return "Hello " + a + b;
   }
 
   @PostMapping("/javaprimitivestr")
-  public String springJavaPrimitiveStr(@RequestParam(name = "a", required = false) int a, @RequestParam(name = "b", required = false) String b) {
+  public String springJavaPrimitiveStr(@RequestParam(name = "a", required = false) int a,
+      @RequestParam(name = "b", required = false) String b) {
     if (b == null || b.equals("")) {
       return "Hello";
     }
     return "Hello " + b + a;
-
   }
 
   @PostMapping("/javaprimitivecomb")
-  public String springJavaPrimitiveCombination(@RequestParam(name = "a", required = false) Integer a, @RequestParam(name = "b", required = false) Float b) {
+  public String springJavaPrimitiveCombination(@RequestParam(name = "a", required = false) Integer a,
+      @RequestParam(name = "b", required = false) Float b) {
     return "Hello " + a + b;
   }
+
+  @PostMapping("/allprimitivetypes")
+  public String allprimitivetypes(@RequestParam(name = "pBoolean", required = false) boolean pBoolean,
+      @RequestParam(name = "pChar", required = false) char pChar,
+      @RequestParam(name = "pByte", required = false) byte pByte,
+      @RequestParam(name = "pShort", required = false) short pShort,
+      @RequestParam(name = "pInt", required = false) int pInt,
+      @RequestParam(name = "pLong", required = false) long pLong,
+      @RequestParam(name = "pFloat", required = false) float pFloat,
+      @RequestParam(name = "pDouble", required = false) double pDouble,
+      @RequestParam(name = "pDoubleWrap", required = false) Double pDoubleWrap) {
+    return "Hello " + pBoolean + ","
+        + pChar + ","
+        + pByte + ","
+        + pShort + ","
+        + pInt + ","
+        + pLong + ","
+        + pFloat + ","
+        + pDouble + ","
+        + pDoubleWrap;
+  }
 }
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
index f8251f9..376a1b3 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
@@ -277,13 +277,13 @@ public class OperationGenerator {
     Type[] parameterTypes = providerMethod.getGenericParameterTypes();
     for (int paramIdx = 0; paramIdx < parameterTypes.length; paramIdx++) {
       int swaggerParamCount = providerParameters.size();
+      Type type = parameterTypes[paramIdx];
 
       // 根据annotation处理
       Annotation[] paramAnnotations = allAnnotations[paramIdx];
-      processByParameterAnnotation(paramAnnotations, paramIdx);
+      processByParameterAnnotation(paramAnnotations, paramIdx, type);
 
       if (isArgumentNotProcessed(swaggerParamCount)) {
-        Type type = parameterTypes[paramIdx];
         // 是否需要根据参数类型处理,目标场景:httpRequest之类
         processByParameterType(type, paramIdx);
       }
@@ -299,7 +299,8 @@ public class OperationGenerator {
     return swaggerParamCount == providerParameters.size();
   }
 
-  protected void processByParameterAnnotation(Annotation[] paramAnnotations, int paramIdx) {
+  @SuppressWarnings({"rawtypes", "unckecked"})
+  protected void processByParameterAnnotation(Annotation[] paramAnnotations, int paramIdx, Type parameterType) {
     String defaultValue = null;
     Parameter parameter = null;
     for (Annotation annotation : paramAnnotations) {
@@ -319,20 +320,16 @@ public class OperationGenerator {
       if (defaultValue != null) {
         ((AbstractSerializableParameter<?>) parameter).setDefaultValue(defaultValue);
       } else if ((((AbstractSerializableParameter<?>) parameter).getDefaultValue() == null)
-          && (!((AbstractSerializableParameter<?>) parameter).getRequired())) { //if required false then only take java primitive values as defaults
-        String type = ((AbstractSerializableParameter<?>) parameter).getType();
-        switch (type) {
-          case "integer":
-            defaultValue = "0";
-            break;
-          case "number":
-            defaultValue = "0.0";
-            break;
-          case "boolean":
-            defaultValue = "false";
-            break;
-          default:
-            defaultValue = null;
+          && (!((AbstractSerializableParameter<?>) parameter)
+          .getRequired())) { //if required false then only take java primitive values as defaults
+        if (parameterType instanceof Class && ((Class) parameterType).isPrimitive()) {
+          switch (parameterType.getTypeName()) {
+            case "boolean":
+              defaultValue = "false";
+              break;
+            default:
+              defaultValue = "0";
+          }
         }
         ((AbstractSerializableParameter<?>) parameter).setDefaultValue(defaultValue);
       }


[incubator-servicecomb-java-chassis] 01/10: [SCB-847]Provide a way to decode user's custom error data

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 8e8a3ec9aaa7390048af04d9717224465d250899
Author: liubao <ba...@huawei.com>
AuthorDate: Wed Aug 15 18:53:51 2018 +0800

    [SCB-847]Provide a way to decode user's custom error data
---
 .../error/CustomExceptionToResponseConverter.java  | 47 ++++++++++++++++++++
 .../demo/edge/business/error/ErrorData.java        | 40 +++++++++++++++++
 .../demo/edge/business/error/ErrorService.java     | 46 ++++++++++++++++++++
 .../edge/business/error/IllegalStateErrorData.java | 50 ++++++++++++++++++++++
 ...vocation.exception.ExceptionToResponseConverter | 18 ++++++++
 .../servicecomb/demo/edge/consumer/Consumer.java   | 28 ++++++++++++
 .../edge/service/CustomResponseMetaMapper.java     | 46 ++++++++++++++++++++
 .../demo/edge/service/IllegalStateErrorData.java   | 50 ++++++++++++++++++++++
 ....swagger.invocation.response.ResponseMetaMapper | 18 ++++++++
 .../invocation/response/ResponseMetaMapper.java    | 28 ++++++++++++
 .../swagger/invocation/response/ResponsesMeta.java | 29 ++++++++++++-
 11 files changed, 398 insertions(+), 2 deletions(-)

diff --git a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/CustomExceptionToResponseConverter.java b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/CustomExceptionToResponseConverter.java
new file mode 100644
index 0000000..fd2ccd9
--- /dev/null
+++ b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/CustomExceptionToResponseConverter.java
@@ -0,0 +1,47 @@
+/*
+ * 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.edge.business.error;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
+import org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+
+public class CustomExceptionToResponseConverter implements ExceptionToResponseConverter<IllegalStateException> {
+  @Override
+  public Class<IllegalStateException> getExceptionClass() {
+    return IllegalStateException.class;
+  }
+
+  @Override
+  public int getOrder() {
+    return 100;
+  }
+
+  @Override
+  public Response convert(SwaggerInvocation swaggerInvocation, IllegalStateException e) {
+    IllegalStateErrorData data = new IllegalStateErrorData();
+    data.setId(500);
+    data.setMessage(e.getMessage());
+    data.setState(e.getMessage());
+    InvocationException state = new InvocationException(Status.INTERNAL_SERVER_ERROR, data);
+    return Response.failResp(state);
+  }
+}
diff --git a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorData.java b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorData.java
new file mode 100644
index 0000000..078c194
--- /dev/null
+++ b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorData.java
@@ -0,0 +1,40 @@
+/*
+ * 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.edge.business.error;
+
+public class ErrorData {
+  private int id;
+
+  private String message;
+
+  public int getId() {
+    return id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+}
diff --git a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorService.java b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorService.java
new file mode 100644
index 0000000..8bdba9c
--- /dev/null
+++ b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorService.java
@@ -0,0 +1,46 @@
+/*
+ * 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.edge.business.error;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@RestSchema(schemaId = "error-v2")
+@RequestMapping(path = "/business/v2/error")
+public class ErrorService {
+  @RequestMapping(path = "/add", method = RequestMethod.GET)
+  public int add(int x, int y) {
+    if (x == 99) {
+      throw new NullPointerException("un expected NPE test.");
+    }
+    if (x == 88) {
+      ErrorData data = new ErrorData();
+      data.setId(12);
+      data.setMessage("not allowed id.");
+      throw new InvocationException(Status.FORBIDDEN, data);
+    }
+    if (x == 77) {
+      throw new IllegalStateException("77");
+    }
+    return x + y;
+  }
+}
diff --git a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/IllegalStateErrorData.java b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/IllegalStateErrorData.java
new file mode 100644
index 0000000..d771c7a
--- /dev/null
+++ b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/IllegalStateErrorData.java
@@ -0,0 +1,50 @@
+/*
+ * 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.edge.business.error;
+
+public class IllegalStateErrorData {
+  private int id;
+
+  private String message;
+
+  private String state;
+
+  public int getId() {
+    return id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public String getState() {
+    return state;
+  }
+
+  public void setState(String state) {
+    this.state = state;
+  }
+}
diff --git a/demo/demo-edge/business-2.0.0/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter b/demo/demo-edge/business-2.0.0/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter
new file mode 100644
index 0000000..9a43331
--- /dev/null
+++ b/demo/demo-edge/business-2.0.0/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.demo.edge.business.error.CustomExceptionToResponseConverter
\ No newline at end of file
diff --git a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
index 7796de9..c5c22ea 100644
--- a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
+++ b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
@@ -46,6 +46,8 @@ import org.springframework.http.ResponseEntity;
 import org.springframework.util.Assert;
 import org.springframework.util.LinkedMultiValueMap;
 import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
 import org.springframework.web.client.RestTemplate;
 
 public class Consumer {
@@ -88,6 +90,7 @@ public class Consumer {
     testDependType();
     testDownload();
     testDownloadBigFile();
+    testErrorCode();
 
     invoke("/v1/add", 2, 1, addV1Result);
     invoke("/v1/add", 3, 1, addV1Result);
@@ -158,6 +161,31 @@ public class Consumer {
     Assert.isNull(response.getField().getField(), "must be null");
   }
 
+  protected void testErrorCode() {
+    String url = edgePrefix + "/v2/error/add";
+
+    int response = template.getForObject(url + "?x=2&y=3", Integer.class);
+    Assert.isTrue(response == 5, "not get 5.");
+
+    Map raw = template.getForObject(url + "?x=99&y=3", Map.class);
+    Assert.isTrue(raw.get("message").equals("Cse Internal Server Error"), "x99");
+
+    try {
+      raw = template.getForObject(url + "?x=88&y=3", Map.class);
+      Assert.isTrue(false, "x88");
+    } catch (HttpClientErrorException e) {
+      Assert.isTrue(e.getRawStatusCode() == 403, "x88");
+      Assert.isTrue(e.getResponseBodyAsString().equals("{\"id\":12,\"message\":\"not allowed id.\"}"), "x88");
+    }
+    try {
+      raw = template.getForObject(url + "?x=77&y=3", Map.class);
+      Assert.isTrue(false, "x77");
+    } catch (HttpServerErrorException e) {
+      Assert.isTrue(e.getRawStatusCode() == 500, "x77");
+      Assert.isTrue(e.getResponseBodyAsString().equals("{\"id\":500,\"message\":\"77\",\"state\":\"77\"}"), "x77");
+    }
+  }
+
   protected void testDependType() {
     String url = edgePrefix + "/v2/dependType";
 
diff --git a/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/CustomResponseMetaMapper.java b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/CustomResponseMetaMapper.java
new file mode 100644
index 0000000..c3eaa51
--- /dev/null
+++ b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/CustomResponseMetaMapper.java
@@ -0,0 +1,46 @@
+/*
+ * 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.edge.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.swagger.invocation.response.ResponseMeta;
+import org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper;
+
+import com.fasterxml.jackson.databind.type.SimpleType;
+
+public class CustomResponseMetaMapper implements ResponseMetaMapper {
+  private final static Map<Integer, ResponseMeta> CODES = new HashMap<>(1);
+
+  static {
+    ResponseMeta meta = new ResponseMeta();
+    meta.setJavaType(SimpleType.constructUnsafe(IllegalStateErrorData.class));
+    CODES.put(500, meta);
+  }
+
+  @Override
+  public int getOrder() {
+    return 100;
+  }
+
+  @Override
+  public Map<Integer, ResponseMeta> getMapper() {
+    return CODES;
+  }
+}
diff --git a/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/IllegalStateErrorData.java b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/IllegalStateErrorData.java
new file mode 100644
index 0000000..017183f
--- /dev/null
+++ b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/IllegalStateErrorData.java
@@ -0,0 +1,50 @@
+/*
+ * 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.edge.service;
+
+public class IllegalStateErrorData {
+  private int id;
+
+  private String message;
+
+  private String state;
+
+  public int getId() {
+    return id;
+  }
+
+  public void setId(int id) {
+    this.id = id;
+  }
+
+  public String getMessage() {
+    return message;
+  }
+
+  public void setMessage(String message) {
+    this.message = message;
+  }
+
+  public String getState() {
+    return state;
+  }
+
+  public void setState(String state) {
+    this.state = state;
+  }
+}
diff --git a/demo/demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper b/demo/demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper
new file mode 100644
index 0000000..d8a88a7
--- /dev/null
+++ b/demo/demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.apache.servicecomb.demo.edge.service.CustomResponseMetaMapper
\ No newline at end of file
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMetaMapper.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMetaMapper.java
new file mode 100644
index 0000000..e357711
--- /dev/null
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMetaMapper.java
@@ -0,0 +1,28 @@
+/*
+ * 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.invocation.response;
+
+import java.util.Map;
+
+public interface ResponseMetaMapper {
+  default int getOrder() {
+    return 0;
+  }
+
+  Map<Integer, ResponseMeta> getMapper();
+}
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
index 09b96da..856e3f0 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
@@ -23,9 +23,11 @@ import java.util.Map.Entry;
 
 import javax.ws.rs.core.Response.Status;
 
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 import org.apache.servicecomb.swagger.converter.SwaggerToClassGenerator;
 import org.apache.servicecomb.swagger.invocation.context.HttpStatus;
 import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
+import org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;
 
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.SimpleType;
@@ -35,7 +37,12 @@ import io.swagger.models.Operation;
 import io.swagger.models.Response;
 
 public class ResponsesMeta {
-  private static final JavaType COMMON_EXCEPTION_JAVATYPE = SimpleType.constructUnsafe(CommonExceptionData.class);
+  private static final JavaType COMMON_EXCEPTION_JAVA_TYPE = SimpleType.constructUnsafe(CommonExceptionData.class);
+
+  private static final JavaType OBJECT_JAVA_TYPE = SimpleType.constructUnsafe(Object.class);
+
+  private static final ResponseMetaMapper GLOBAL_DEFAULT_MAPPER = SPIServiceUtils
+      .getPriorityHighestService(ResponseMetaMapper.class);
 
   private Map<Integer, ResponseMeta> responseMap = new HashMap<>();
 
@@ -46,6 +53,8 @@ public class ResponsesMeta {
   // 如果不传return类型进来,完全以swagger为标准,会导致生成的class不等于return
   public void init(SwaggerToClassGenerator swaggerToClassGenerator, Operation operation, Type returnType) {
     initSuccessResponse(returnType);
+    initInternalErrorResponse();
+    initGlobalDefaultMapper();
 
     for (Entry<String, Response> entry : operation.getResponses().entrySet()) {
       if ("default".equals(entry.getKey())) {
@@ -62,7 +71,7 @@ public class ResponsesMeta {
     if (defaultResponse == null) {
       // swagger中没有定义default,加上default专用于处理exception
       ResponseMeta responseMeta = new ResponseMeta();
-      responseMeta.setJavaType(COMMON_EXCEPTION_JAVATYPE);
+      responseMeta.setJavaType(OBJECT_JAVA_TYPE);
 
       defaultResponse = responseMeta;
     }
@@ -74,6 +83,22 @@ public class ResponsesMeta {
     responseMap.put(Status.OK.getStatusCode(), successResponse);
   }
 
+  protected void initInternalErrorResponse() {
+    ResponseMeta internalErrorResponse = new ResponseMeta();
+    internalErrorResponse.setJavaType(COMMON_EXCEPTION_JAVA_TYPE);
+    responseMap.put(ExceptionFactory.CONSUMER_INNER_STATUS_CODE, internalErrorResponse);
+    responseMap.put(ExceptionFactory.PRODUCER_INNER_STATUS_CODE, internalErrorResponse);
+  }
+
+  protected void initGlobalDefaultMapper() {
+    if (GLOBAL_DEFAULT_MAPPER != null) {
+      Map<Integer, ResponseMeta> mappers = GLOBAL_DEFAULT_MAPPER.getMapper();
+      if (mappers != null) {
+        responseMap.putAll(mappers);
+      }
+    }
+  }
+
   public ResponseMeta findResponseMeta(int statusCode) {
     ResponseMeta responseMeta = responseMap.get(statusCode);
     if (responseMeta == null) {


[incubator-servicecomb-java-chassis] 06/10: [SCB-847]support client not write null value and server write null value.

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 44cd5bc7a9e6d48dcd3df0244008a815fa545270
Author: liubao <ba...@huawei.com>
AuthorDate: Thu Aug 16 19:50:42 2018 +0800

    [SCB-847]support client not write null value and server write null value.
---
 .../common/rest/codec/RestObjectMapperFactory.java | 23 +++++++
 .../rest/codec/param/BodyProcessorCreator.java     |  7 +-
 .../rest/codec/param/CookieProcessorCreator.java   |  3 +-
 .../rest/codec/param/HeaderProcessorCreator.java   |  3 +-
 .../rest/codec/param/ParamValueProcessor.java      |  3 +-
 .../rest/codec/produce/ProduceJsonProcessor.java   |  5 +-
 .../servicecomb/demo/jaxrs/client/JaxrsClient.java |  9 ++-
 .../jaxrs/client/pojoDefault/DefaultModel.java     | 17 ++---
 .../pojoDefault/DefaultModelServiceClient.java     | 46 +++++++++++++
 .../server/pojoDefault/DefaultResponseModel.java   | 76 ++++++++++++++++++++++
 .../servicecomb/demo/jaxrs/server/JaxrsServer.java |  7 +-
 .../server/pojoDefault/DefaultModelService.java    | 27 ++++----
 .../server/pojoDefault/DefaultRequestModel.java    | 76 ++++++++++++++++++++++
 .../server/pojoDefault/DefaultResponseModel.java   | 76 ++++++++++++++++++++++
 .../demo/RestObjectMapperWithStringMapper.java     |  2 +
 15 files changed, 349 insertions(+), 31 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
index 188d9de..65b107e 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
@@ -17,12 +17,31 @@
 
 package org.apache.servicecomb.common.rest.codec;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Manage RestObjectMapper instances. Give users an option to specify custom mappers.
  */
 public class RestObjectMapperFactory {
+  public static final String KEY_PROVIDER_READ_OR_CONSUMER_READ = "provider.consumer.read";
+
+  public static final String KEY_PROVIDER_WRITE = "provider.write";
+
+  public static final String KEY_CONSUMER_WRITE = "consumer.write";
+
   private static AbstractRestObjectMapper defaultMapper = new RestObjectMapper();
 
+  private static Map<String, AbstractRestObjectMapper> allMappers = new HashMap<>();
+
+  public static AbstractRestObjectMapper getRestObjectMapper(String key) {
+    AbstractRestObjectMapper mapper = allMappers.get(key);
+    if (mapper != null) {
+      return mapper;
+    }
+    return defaultMapper;
+  }
+
   public static AbstractRestObjectMapper getRestObjectMapper() {
     return defaultMapper;
   }
@@ -30,4 +49,8 @@ public class RestObjectMapperFactory {
   public static void setDefaultRestObjectMapper(AbstractRestObjectMapper customMapper) {
     defaultMapper = customMapper;
   }
+
+  public static void setCustomMapper(String key, AbstractRestObjectMapper mapper) {
+    allMappers.put(key, mapper);
+  }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
index 61f0ea9..fc40579 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
@@ -68,7 +68,7 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator {
       contentType = contentType == null ? "" : contentType.toLowerCase(Locale.US);
       if (contentType.startsWith(MediaType.MULTIPART_FORM_DATA)
           || contentType.startsWith(MediaType.APPLICATION_FORM_URLENCODED)) {
-        return RestObjectMapperFactory.getRestObjectMapper().convertValue(request.getParameterMap(), targetType);
+        return convertValue(request.getParameterMap(), targetType);
       }
 
       // for standard HttpServletRequest, getInputStream will never return null
@@ -85,7 +85,8 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator {
       }
 
       try {
-        return RestObjectMapperFactory.getRestObjectMapper().readValue(inputStream, targetType);
+        return RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ)
+            .readValue(inputStream, targetType);
       } catch (MismatchedInputException e) {
         // there is no way to detect InputStream is empty, so have to catch the exception
         if (!isRequired) {
@@ -100,7 +101,7 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator {
     public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {
       try (BufferOutputStream output = new BufferOutputStream()) {
         clientRequest.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
-        RestObjectMapperFactory.getRestObjectMapper().writeValue(output, arg);
+        RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE).writeValue(output, arg);
         if (arg != null) {
           clientRequest.write(output.getBuffer());
         }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
index 7f8a776..1688349 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
@@ -64,7 +64,8 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
 
     @Override
     public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {
-      clientRequest.addCookie(paramPath, RestObjectMapperFactory.getRestObjectMapper().convertToString(arg));
+      clientRequest.addCookie(paramPath,
+          RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE).convertToString(arg));
     }
 
     @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
index 43b4582..44fa146 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
@@ -74,7 +74,8 @@ public class HeaderProcessorCreator implements ParamValueProcessorCreator {
         LOGGER.debug("Header arg is null, will not be set into clientRequest. paramPath = [{}]", paramPath);
         return;
       }
-      clientRequest.putHeader(paramPath, RestObjectMapperFactory.getRestObjectMapper().convertToString(arg));
+      clientRequest.putHeader(paramPath,
+          RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE).convertToString(arg));
     }
 
     @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
index e38f7dc..8753b40 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
@@ -30,7 +30,8 @@ public interface ParamValueProcessor {
   void setValue(RestClientRequest clientRequest, Object arg) throws Exception;
 
   default Object convertValue(Object value, JavaType targetType) {
-    return RestObjectMapperFactory.getRestObjectMapper().convertValue(value, targetType);
+    return RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ)
+        .convertValue(value, targetType);
   }
 
   String getParameterPath();
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
index 817aef0..4f57553 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
@@ -35,12 +35,13 @@ public class ProduceJsonProcessor implements ProduceProcessor {
 
   @Override
   public void doEncodeResponse(OutputStream output, Object result) throws Exception {
-    RestObjectMapperFactory.getRestObjectMapper().writeValue(output, result);
+    RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE).writeValue(output, result);
   }
 
   @Override
   public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {
-    return RestObjectMapperFactory.getRestObjectMapper().readValue(input, type);
+    return RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ)
+        .readValue(input, type);
   }
 
   @Override
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
index 71407ef..2bd2a74 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
@@ -24,6 +24,7 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.http.HttpStatus;
+import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.core.Const;
 import org.apache.servicecomb.core.CseContext;
@@ -34,6 +35,7 @@ import org.apache.servicecomb.demo.TestMgr;
 import org.apache.servicecomb.demo.compute.Person;
 import org.apache.servicecomb.demo.jaxrs.client.beanParam.BeanParamPojoClient;
 import org.apache.servicecomb.demo.jaxrs.client.beanParam.BeanParamRestTemplateClient;
+import org.apache.servicecomb.demo.jaxrs.client.pojoDefault.DefaultModelServiceClient;
 import org.apache.servicecomb.demo.validator.Student;
 import org.apache.servicecomb.foundation.common.utils.BeanUtils;
 import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
@@ -61,7 +63,11 @@ public class JaxrsClient {
   public static void init() throws Exception {
     Log4jUtils.init();
     BeanUtils.init();
-    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory
+        .setCustomMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE, new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE, new RestObjectMapper());
+    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ,
+        new RestObjectMapperWithStringMapper());
   }
 
   public static void run() throws Exception {
@@ -78,6 +84,7 @@ public class JaxrsClient {
     beanParamPojoClient.testAll();
     BeanParamRestTemplateClient beanParamRestTemplateClient = new BeanParamRestTemplateClient();
     beanParamRestTemplateClient.testAll();
+    DefaultModelServiceClient.run();
   }
 
   private static void testCompute(RestTemplate template) throws Exception {
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModel.java
similarity index 63%
copy from common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
copy to demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModel.java
index 188d9de..1c5d64e 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModel.java
@@ -15,19 +15,16 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.common.rest.codec;
+package org.apache.servicecomb.demo.jaxrs.client.pojoDefault;
 
-/**
- * Manage RestObjectMapper instances. Give users an option to specify custom mappers.
- */
-public class RestObjectMapperFactory {
-  private static AbstractRestObjectMapper defaultMapper = new RestObjectMapper();
+public class DefaultModel {
+  private int index;
 
-  public static AbstractRestObjectMapper getRestObjectMapper() {
-    return defaultMapper;
+  public int getIndex() {
+    return index;
   }
 
-  public static void setDefaultRestObjectMapper(AbstractRestObjectMapper customMapper) {
-    defaultMapper = customMapper;
+  public void setIndex(int index) {
+    this.index = index;
   }
 }
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModelServiceClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModelServiceClient.java
new file mode 100644
index 0000000..f6dedf1
--- /dev/null
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModelServiceClient.java
@@ -0,0 +1,46 @@
+/*
+ * 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.jaxrs.client.pojoDefault;
+
+import org.apache.servicecomb.core.CseContext;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.demo.jaxrs.server.pojoDefault.DefaultResponseModel;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.springframework.web.client.RestTemplate;
+
+public class DefaultModelServiceClient {
+  private static RestTemplate template = RestTemplateBuilder.create();
+
+  private static String urlPrefix = "cse://jaxrs/DefaultModelService";
+
+  public static void run() {
+    // highway do not support this feature
+    CseContext.getInstance().getConsumerProviderManager().setTransport("jaxrs", "rest");
+    testDefaultModelService();
+  }
+
+  private static void testDefaultModelService() {
+    DefaultModel model = new DefaultModel();
+    model.setIndex(400);
+    DefaultResponseModel result = template.postForObject(urlPrefix + "/model", model, DefaultResponseModel.class);
+    TestMgr.check(result.getAge(), 200);
+    TestMgr.check(result.getIndex(), 400);
+    TestMgr.check(result.getName(), "World");
+    TestMgr.check(result.getDesc(), null);
+  }
+}
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
new file mode 100644
index 0000000..6c4350a
--- /dev/null
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
@@ -0,0 +1,76 @@
+/*
+ * 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.jaxrs.server.pojoDefault;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Null;
+
+public class DefaultResponseModel {
+  @Min(20)
+  @Max(2000)
+  @Null
+  private Integer age = 200;
+
+  @Min(2)
+  @Max(30)
+  @Null
+  private String name = "World";
+
+  private int index;
+
+  private String desc = "Hello";
+
+  public Integer getAge() {
+    return age;
+  }
+
+  public void setAge(Integer age) {
+    this.age = age;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+
+  public int getIndex() {
+    return index;
+  }
+
+  public void setIndex(int index) {
+    this.index = index;
+  }
+
+  public String getDesc() {
+    return desc;
+  }
+
+  public void setDesc(String desc) {
+    this.desc = desc;
+  }
+
+  @Override
+  public String toString() {
+    return "index=" + index + ";name=" + name + ";age=" + age;
+  }
+}
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
index bf5eba5..f661720 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.demo.jaxrs.server;
 
+import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
 import org.apache.servicecomb.foundation.common.utils.BeanUtils;
@@ -26,6 +27,10 @@ public class JaxrsServer {
   public static void main(String[] args) throws Exception {
     Log4jUtils.init();
     BeanUtils.init();
-    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory
+        .setCustomMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE, new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE, new RestObjectMapper());
+    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ,
+        new RestObjectMapperWithStringMapper());
   }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultModelService.java
similarity index 57%
copy from common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
copy to demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultModelService.java
index 188d9de..7296a09 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultModelService.java
@@ -15,19 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.common.rest.codec;
+package org.apache.servicecomb.demo.jaxrs.server.pojoDefault;
 
-/**
- * Manage RestObjectMapper instances. Give users an option to specify custom mappers.
- */
-public class RestObjectMapperFactory {
-  private static AbstractRestObjectMapper defaultMapper = new RestObjectMapper();
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
 
-  public static AbstractRestObjectMapper getRestObjectMapper() {
-    return defaultMapper;
-  }
+import org.apache.servicecomb.provider.rest.common.RestSchema;
 
-  public static void setDefaultRestObjectMapper(AbstractRestObjectMapper customMapper) {
-    defaultMapper = customMapper;
+@RestSchema(schemaId = "DefaultModelService")
+@Path("DefaultModelService")
+public class DefaultModelService {
+  @Path("/model")
+  @POST
+  public DefaultResponseModel errorCode(DefaultRequestModel request) {
+    DefaultResponseModel model = new DefaultResponseModel();
+    model.setIndex(request.getIndex());
+    model.setAge(request.getAge());
+    model.setName(request.getName());
+    model.setDesc(null);
+    return model;
   }
 }
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultRequestModel.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultRequestModel.java
new file mode 100644
index 0000000..0cc5357
--- /dev/null
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultRequestModel.java
@@ -0,0 +1,76 @@
+/*
+ * 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.jaxrs.server.pojoDefault;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Null;
+
+public class DefaultRequestModel {
+  @Min(20)
+  @Max(2000)
+  @Null
+  private Integer age = 200;
+
+  @Min(2)
+  @Max(30)
+  @Null
+  private String name = "World";
+
+  private int index;
+
+  private String desc;
+
+  public Integer getAge() {
+    return age;
+  }
+
+  public void setAge(Integer age) {
+    this.age = age;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+
+  public int getIndex() {
+    return index;
+  }
+
+  public void setIndex(int index) {
+    this.index = index;
+  }
+
+  public String getDesc() {
+    return desc;
+  }
+
+  public void setDesc(String desc) {
+    this.desc = desc;
+  }
+
+  @Override
+  public String toString() {
+    return "index=" + index + ";name=" + name + ";age=" + age;
+  }
+}
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
new file mode 100644
index 0000000..bf4288a
--- /dev/null
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
@@ -0,0 +1,76 @@
+/*
+ * 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.jaxrs.server.pojoDefault;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Null;
+
+public class DefaultResponseModel {
+  @Min(20)
+  @Max(2000)
+  @Null
+  private Integer age = 200;
+
+  @Min(2)
+  @Max(30)
+  @Null
+  private String name = "World";
+
+  private int index;
+
+  private String desc;
+
+  public Integer getAge() {
+    return age;
+  }
+
+  public void setAge(Integer age) {
+    this.age = age;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+
+
+  public int getIndex() {
+    return index;
+  }
+
+  public void setIndex(int index) {
+    this.index = index;
+  }
+
+  public String getDesc() {
+    return desc;
+  }
+
+  public void setDesc(String desc) {
+    this.desc = desc;
+  }
+
+  @Override
+  public String toString() {
+    return "index=" + index + ";name=" + name + ";age=" + age;
+  }
+}
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java
index d90160c..6438069 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java
@@ -24,6 +24,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
 import com.fasterxml.jackson.databind.JavaType;
 
 /**
@@ -50,6 +51,7 @@ public class RestObjectMapperWithStringMapper extends RestObjectMapper {
 
   public RestObjectMapperWithStringMapper() {
     super();
+    setSerializationInclusion(Include.NON_NULL);
   }
 
   @Override


[incubator-servicecomb-java-chassis] 07/10: [SCB-847]fix it fail

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 a23edf205b74d189e4e781a21f501905956cbdd5
Author: liubao <ba...@huawei.com>
AuthorDate: Thu Aug 16 20:44:17 2018 +0800

    [SCB-847]fix it fail
---
 .../apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java   | 8 ++++++--
 .../apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java   | 7 ++++++-
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
index 2bd3330..f35efe5 100644
--- a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.springboot.jaxrs.client;
 
+import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
 import org.apache.servicecomb.demo.TestMgr;
@@ -30,10 +31,13 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 public class JaxrsClient {
 
   public static void main(String[] args) throws Exception {
+    RestObjectMapperFactory
+        .setCustomMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE, new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE, new RestObjectMapper());
+    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ,
+        new RestObjectMapperWithStringMapper());
     Log4jUtils.init();
     SpringApplication.run(JaxrsClient.class, args);
-
-    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());
     org.apache.servicecomb.demo.jaxrs.client.JaxrsClient.run();
     TestMgr.summary();
   }
diff --git a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
index 5b4add3..d74ecf0 100644
--- a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
+++ b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
@@ -17,6 +17,7 @@
 
 package org.apache.servicecomb.springboot.jaxrs.server;
 
+import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
 import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
@@ -28,8 +29,12 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 @EnableServiceComb
 public class JaxrsServer {
   public static void main(final String[] args) throws Exception {
+    RestObjectMapperFactory
+        .setCustomMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE, new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE, new RestObjectMapper());
+    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ,
+        new RestObjectMapperWithStringMapper());
     Log4jUtils.init();
     SpringApplication.run(JaxrsServer.class, args);
-    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());
   }
 }


[incubator-servicecomb-java-chassis] 08/10: [SCB-847]add validation related test case

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 9f18a56cd7b2f172401bc1c4aedebbda27e1e03f
Author: liubao <ba...@huawei.com>
AuthorDate: Thu Aug 16 21:26:25 2018 +0800

    [SCB-847]add validation related test case
---
 .../servicecomb/demo/jaxrs/client/JaxrsClient.java |  2 +
 .../client/validation/ValidationServiceClient.java | 77 ++++++++++++++++++++++
 .../jaxrs/server/validation/ValidationService.java | 43 ++++++++++++
 .../jaxrs/server/validation/ValidationModel.java   | 57 ++++++++++++++++
 4 files changed, 179 insertions(+)

diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
index 2bd2a74..d116af4 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
@@ -36,6 +36,7 @@ import org.apache.servicecomb.demo.compute.Person;
 import org.apache.servicecomb.demo.jaxrs.client.beanParam.BeanParamPojoClient;
 import org.apache.servicecomb.demo.jaxrs.client.beanParam.BeanParamRestTemplateClient;
 import org.apache.servicecomb.demo.jaxrs.client.pojoDefault.DefaultModelServiceClient;
+import org.apache.servicecomb.demo.jaxrs.client.validation.ValidationServiceClient;
 import org.apache.servicecomb.demo.validator.Student;
 import org.apache.servicecomb.foundation.common.utils.BeanUtils;
 import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
@@ -85,6 +86,7 @@ public class JaxrsClient {
     BeanParamRestTemplateClient beanParamRestTemplateClient = new BeanParamRestTemplateClient();
     beanParamRestTemplateClient.testAll();
     DefaultModelServiceClient.run();
+    ValidationServiceClient.run();
   }
 
   private static void testCompute(RestTemplate template) throws Exception {
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
new file mode 100644
index 0000000..727a050
--- /dev/null
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
@@ -0,0 +1,77 @@
+/*
+ * 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.jaxrs.client.validation;
+
+import java.util.ArrayList;
+
+import org.apache.servicecomb.core.CseContext;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.demo.jaxrs.server.validation.ValidationModel;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.web.client.RestTemplate;
+
+public class ValidationServiceClient {
+  private static RestTemplate template = RestTemplateBuilder.create();
+
+  private static String urlPrefix = "cse://jaxrs/ValidationService";
+
+  public static void run() {
+    // highway do not support this feature
+    CseContext.getInstance().getConsumerProviderManager().setTransport("jaxrs", "rest");
+    testValidation();
+  }
+
+  private static void testValidation() {
+    ValidationModel model = new ValidationModel();
+    model.setAge(20);
+    model.setMembers(new ArrayList<>());
+    model.setName("name");
+    ValidationModel result = template.postForObject(urlPrefix + "/validate", model, ValidationModel.class);
+    TestMgr.check(result.getAge(), 20);
+    TestMgr.check(result.getName(), "name");
+    TestMgr.check(result.getMembers().size(), 0);
+
+    try {
+      model.setAge(null);
+      template.postForObject(urlPrefix + "/validate", model, ValidationModel.class);
+      TestMgr.check(false, true);
+    } catch (InvocationException e) {
+      TestMgr.check(e.getErrorData().toString().contains("age"), true);
+    }
+
+    try {
+      model.setAge(20);
+      model.setMembers(null);
+      template.postForObject(urlPrefix + "/validate", model, ValidationModel.class);
+      TestMgr.check(false, true);
+    } catch (InvocationException e) {
+      TestMgr.check(e.getErrorData().toString().contains("member"), true);
+    }
+
+    String strResult = template.getForObject(urlPrefix + "/validateQuery?name=", String.class);
+    TestMgr.check(strResult, "");
+
+    try {
+      template.getForObject(urlPrefix + "/validateQuery", String.class);
+      TestMgr.check(false, true);
+    } catch (InvocationException e) {
+      TestMgr.check(e.getErrorData().toString().contains("null"), true);
+    }
+  }
+}
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationService.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationService.java
new file mode 100644
index 0000000..7324669
--- /dev/null
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationService.java
@@ -0,0 +1,43 @@
+/*
+ * 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.jaxrs.server.validation;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+
+@RestSchema(schemaId = "ValidationService")
+@Path("ValidationService")
+public class ValidationService {
+  @Path("/validate")
+  @POST
+  public ValidationModel errorCode(@Valid ValidationModel request) {
+    return request;
+  }
+
+  @Path("/validateQuery")
+  @GET
+  public String queryValidate(@NotNull @QueryParam("name") String name) {
+    return name;
+  }
+}
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationModel.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationModel.java
new file mode 100644
index 0000000..09e2612
--- /dev/null
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationModel.java
@@ -0,0 +1,57 @@
+/*
+ * 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.jaxrs.server.validation;
+
+import java.util.List;
+
+import javax.validation.constraints.NotNull;
+
+public class ValidationModel {
+  @NotNull
+  private Integer age;
+
+  @NotNull
+  private List<String> members;
+
+  @NotNull
+  private String name;
+
+  public Integer getAge() {
+    return age;
+  }
+
+  public void setAge(Integer age) {
+    this.age = age;
+  }
+
+  public List<String> getMembers() {
+    return members;
+  }
+
+  public void setMembers(List<String> members) {
+    this.members = members;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void setName(String name) {
+    this.name = name;
+  }
+}


[incubator-servicecomb-java-chassis] 03/10: [SCB-847]fix container error code handling logic

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 fa9ff764c73459a218ede84880dc4a4907cc5a42
Author: liubao <ba...@huawei.com>
AuthorDate: Thu Aug 16 10:21:52 2018 +0800

    [SCB-847]fix container error code handling logic
---
 .../rest/client/http/DefaultHttpClientFilter.java  |  8 ++++---
 .../client/http/TestDefaultHttpClientFilter.java   | 25 ++++++++++++++++------
 2 files changed, 23 insertions(+), 10 deletions(-)

diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
index 7d54078..60921c5 100644
--- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
+++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
@@ -23,13 +23,13 @@ import javax.ws.rs.core.HttpHeaders;
 
 import org.apache.servicecomb.common.rest.RestConst;
 import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
+import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;
 import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
 import org.apache.servicecomb.common.rest.filter.HttpClientFilter;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
-import org.apache.servicecomb.swagger.invocation.InvocationType;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.apache.servicecomb.swagger.invocation.response.ResponseMeta;
 import org.slf4j.Logger;
@@ -74,6 +74,8 @@ public class DefaultHttpClientFilter implements HttpClientFilter {
     RestOperationMeta swaggerRestOperation = operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
     ProduceProcessor produceProcessor = findProduceProcessor(swaggerRestOperation, responseEx);
     if (produceProcessor == null) {
+      // This happens outside the runtime such as Servlet filter response. Here we give a default json parser to it
+      // and keep user data not get lose.
       String msg =
           String.format("method %s, path %s, statusCode %d, reasonPhrase %s, response content-type %s is not supported",
               swaggerRestOperation.getHttpMethod(),
@@ -81,8 +83,8 @@ public class DefaultHttpClientFilter implements HttpClientFilter {
               responseEx.getStatus(),
               responseEx.getStatusType().getReasonPhrase(),
               responseEx.getHeader(HttpHeaders.CONTENT_TYPE));
-      LOGGER.error(msg);
-      return Response.createFail(InvocationType.CONSUMER, msg);
+      LOGGER.warn(msg);
+      produceProcessor = ProduceProcessorManager.DEFAULT_PROCESSOR;
     }
 
     try {
diff --git a/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestDefaultHttpClientFilter.java b/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestDefaultHttpClientFilter.java
index 3279ab3..d14bc1d 100644
--- a/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestDefaultHttpClientFilter.java
+++ b/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestDefaultHttpClientFilter.java
@@ -31,6 +31,7 @@ import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
 import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.foundation.common.utils.JsonUtils;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
 import org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;
 import org.apache.servicecomb.swagger.invocation.Response;
@@ -48,6 +49,7 @@ import io.vertx.core.buffer.Buffer;
 import io.vertx.core.buffer.impl.BufferImpl;
 import io.vertx.core.http.CaseInsensitiveHeaders;
 import mockit.Expectations;
+import mockit.Injectable;
 import mockit.Mock;
 import mockit.MockUp;
 import mockit.Mocked;
@@ -172,29 +174,38 @@ public class TestDefaultHttpClientFilter {
   public void testAfterReceiveResponseNullProduceProcessor(@Mocked Invocation invocation,
       @Mocked HttpServletResponseEx responseEx,
       @Mocked OperationMeta operationMeta,
-      @Mocked RestOperationMeta swaggerRestOperation) {
+      @Mocked RestOperationMeta swaggerRestOperation,
+      @Injectable ResponseMeta responseMeta) throws Exception {
+    CommonExceptionData data = new CommonExceptionData("abcd");
     new Expectations() {
       {
         invocation.getOperationMeta();
         result = operationMeta;
         operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
         result = swaggerRestOperation;
+        operationMeta.findResponseMeta(403);
+        result = responseMeta;
+        responseMeta.getJavaType();
+        result = SimpleType.constructUnsafe(CommonExceptionData.class);
         responseEx.getStatus();
-        result = 200;
+        result = 403;
+        responseEx.getStatusType();
+        result = Status.FORBIDDEN;
+        responseEx.getBodyBuffer();
+        result = Buffer.buffer(JsonUtils.writeValueAsString(data).getBytes());
       }
     };
 
     Response response = filter.afterReceiveResponse(invocation, responseEx);
-    Assert.assertEquals(490, response.getStatusCode());
-    Assert.assertEquals(ExceptionFactory.CONSUMER_INNER_REASON_PHRASE, response.getReasonPhrase());
+    Assert.assertEquals(403, response.getStatusCode());
+    Assert.assertEquals("Forbidden", response.getReasonPhrase());
     Assert.assertEquals(InvocationException.class, response.<InvocationException>getResult().getClass());
     InvocationException invocationException = response.getResult();
     Assert.assertEquals(
-        490,
+        403,
         invocationException.getStatusCode());
     Assert.assertEquals(
-        "CommonExceptionData [message=method null, path null, statusCode 200, reasonPhrase null, "
-            + "response content-type null is not supported]",
+        "CommonExceptionData [message=abcd]",
         invocationException.getErrorData().toString());
   }
 


[incubator-servicecomb-java-chassis] 02/10: [SCB-847]fix test errors and deal with error code override

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 a0131f061b77e64556da2bab91e4de99330c25c8
Author: liubao <ba...@huawei.com>
AuthorDate: Thu Aug 16 09:30:31 2018 +0800

    [SCB-847]fix test errors and deal with error code override
---
 .../servicecomb/demo/edge/consumer/Consumer.java   |  5 ++--
 .../servicecomb/demo/jaxrs/client/JaxrsClient.java | 27 ++++++++++++++--------
 .../resources/microservices/jaxrs/compute.yaml     |  1 +
 .../demo/springmvc/client/SpringmvcClient.java     |  3 +++
 .../swagger/generator/core/OperationGenerator.java |  3 ---
 .../swagger/invocation/response/ResponsesMeta.java |  5 ++--
 .../invocation/response/TestResponsesMeta.java     | 11 +++++----
 7 files changed, 35 insertions(+), 20 deletions(-)

diff --git a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
index c5c22ea..95ea17a 100644
--- a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
+++ b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
@@ -161,6 +161,7 @@ public class Consumer {
     Assert.isNull(response.getField().getField(), "must be null");
   }
 
+  @SuppressWarnings({"unckecked", "rawtypes"})
   protected void testErrorCode() {
     String url = edgePrefix + "/v2/error/add";
 
@@ -171,14 +172,14 @@ public class Consumer {
     Assert.isTrue(raw.get("message").equals("Cse Internal Server Error"), "x99");
 
     try {
-      raw = template.getForObject(url + "?x=88&y=3", Map.class);
+      template.getForObject(url + "?x=88&y=3", Map.class);
       Assert.isTrue(false, "x88");
     } catch (HttpClientErrorException e) {
       Assert.isTrue(e.getRawStatusCode() == 403, "x88");
       Assert.isTrue(e.getResponseBodyAsString().equals("{\"id\":12,\"message\":\"not allowed id.\"}"), "x88");
     }
     try {
-      raw = template.getForObject(url + "?x=77&y=3", Map.class);
+      template.getForObject(url + "?x=77&y=3", Map.class);
       Assert.isTrue(false, "x77");
     } catch (HttpServerErrorException e) {
       Assert.isTrue(e.getRawStatusCode() == 500, "x77");
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
index f285d5f..ac13405 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
@@ -179,6 +179,9 @@ public class JaxrsClient {
       result = template.getForObject(cseUrlPrefix + "/query3?a=30&b=2", String.class);
       TestMgr.check("Hello 302", result);
 
+      result = template.getForObject(cseUrlPrefix + "/query3?a=30", String.class);
+      TestMgr.check("Hello 30null", result);
+
       //input values
       headers = new HttpHeaders();
       headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);
@@ -278,6 +281,7 @@ public class JaxrsClient {
         template.postForObject(cseUrlPrefix + "/compute/testrawjson", jsonPerson, String.class));
   }
 
+  @SuppressWarnings({"unckecked", "rawtypes"})
   private static void testValidatorAddFail(RestTemplate template, String cseUrlPrefix) {
     Map<String, String> params = new HashMap<>();
     params.put("a", "5");
@@ -292,10 +296,11 @@ public class JaxrsClient {
       // Message dependends on locale, so just check the short part.
       // 'must be greater than or equal to 20', propertyPath=add.arg1, rootBeanClass=class org.apache.servicecomb.demo.jaxrs.server.Validator, messageTemplate='{javax.validation.constraints.Min.message}'}]]
       // ignored
+      Map data = (Map)e.getErrorData();
       TestMgr.check(
-          "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage=",
-          e.getErrorData().toString().substring(0,
-              "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage=".length()));
+          "[ConstraintViolationImpl{interpolatedMessage=",
+          data.get("message").toString().substring(0,
+              "[ConstraintViolationImpl{interpolatedMessage=".length()));
     }
 
     TestMgr.check(true, isExcep);
@@ -309,6 +314,7 @@ public class JaxrsClient {
     TestMgr.check(25, result);
   }
 
+  @SuppressWarnings({"unckecked", "rawtypes"})
   private static void testValidatorSayHiFail(RestTemplate template, String cseUrlPrefix) {
     boolean isExcep = false;
     try {
@@ -318,10 +324,11 @@ public class JaxrsClient {
       TestMgr.check(400, e.getStatus().getStatusCode());
       TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());
       // Message dependends on locale, so just check the short part.
+      Map data = (Map)e.getErrorData();
       TestMgr.check(
-          "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage=",
-          e.getErrorData().toString().substring(0,
-              "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage=".length()));
+          "[ConstraintViolationImpl{interpolatedMessage=",
+          data.get("message").toString().substring(0,
+              "[ConstraintViolationImpl{interpolatedMessage=".length()));
     }
     TestMgr.check(true, isExcep);
   }
@@ -333,6 +340,7 @@ public class JaxrsClient {
     TestMgr.check("world sayhi", responseEntity.getBody());
   }
 
+  @SuppressWarnings({"unckecked", "rawtypes"})
   private static void testValidatorExchangeFail(RestTemplate template, String cseUrlPrefix) {
     HttpHeaders headers = new HttpHeaders();
     headers.add("Accept", MediaType.APPLICATION_JSON);
@@ -351,10 +359,11 @@ public class JaxrsClient {
       TestMgr.check(400, e.getStatus().getStatusCode());
       TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());
       // Message dependends on locale, so just check the short part.
+      Map data = (Map)e.getErrorData();
       TestMgr.check(
-          "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage=",
-          e.getErrorData().toString().substring(0,
-              "CommonExceptionData [message=[ConstraintViolationImpl{interpolatedMessage=".length()));
+          "[ConstraintViolationImpl{interpolatedMessage",
+          data.get("message").toString().substring(0,
+              "[ConstraintViolationImpl{interpolatedMessage".length()));
     }
     TestMgr.check(true, isExcep);
   }
diff --git a/demo/demo-schema/src/main/resources/microservices/jaxrs/compute.yaml b/demo/demo-schema/src/main/resources/microservices/jaxrs/compute.yaml
index fcca77c..66eb476 100644
--- a/demo/demo-schema/src/main/resources/microservices/jaxrs/compute.yaml
+++ b/demo/demo-schema/src/main/resources/microservices/jaxrs/compute.yaml
@@ -197,3 +197,4 @@ definitions:
     properties:
       name:
         type: string
+    x-java-class: "org.apache.servicecomb.demo.compute.Person"
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index a555fc9..d9bd62c 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -325,6 +325,9 @@ public class SpringmvcClient {
     result = template.getForObject(cseUrlPrefix + "/query3?a=30&b=2", String.class);
     TestMgr.check("Hello 302", result);
 
+    result = template.getForObject(cseUrlPrefix + "/query3?a=30", String.class);
+    TestMgr.check("Hello 30null", result);
+
     //input values
     headers = new HttpHeaders();
     headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
index 8698585..f8251f9 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
@@ -328,9 +328,6 @@ public class OperationGenerator {
           case "number":
             defaultValue = "0.0";
             break;
-          case "string":
-            defaultValue = "";
-            break;
           case "boolean":
             defaultValue = "false";
             break;
diff --git a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
index 856e3f0..5c53375 100644
--- a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
+++ b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
@@ -64,8 +64,9 @@ public class ResponsesMeta {
       }
 
       Integer statusCode = Integer.parseInt(entry.getKey());
-      ResponseMeta responseMeta = responseMap.computeIfAbsent(statusCode, k -> new ResponseMeta());
-      responseMeta.init(swaggerToClassGenerator, entry.getValue());
+      ResponseMeta codeMeta = new ResponseMeta();
+      codeMeta.init(swaggerToClassGenerator, entry.getValue());
+      ResponseMeta responseMeta = responseMap.put(statusCode, codeMeta);
     }
 
     if (defaultResponse == null) {
diff --git a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java
index 6b03522..6955040 100644
--- a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java
+++ b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java
@@ -19,7 +19,6 @@ package org.apache.servicecomb.swagger.invocation.response;
 import org.apache.servicecomb.swagger.converter.SwaggerToClassGenerator;
 import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
 import org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;
-import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -55,10 +54,13 @@ public class TestResponsesMeta {
     meta.init(swaggerToClassGenerator, operation, int.class);
 
     ResponseMeta resp = meta.findResponseMeta(200);
-    Assert.assertEquals(int.class, resp.getJavaType().getRawClass());
+    // Response is based on swagger type and is Integer type.
+    Assert.assertEquals(Integer.class, resp.getJavaType().getRawClass());
 
     resp = meta.findResponseMeta(201);
-    Assert.assertEquals(int.class, resp.getJavaType().getRawClass());
+    // Response is based on swagger type and is Integer type. For this test case there is one problem need to discuss.
+    // If SUCCESS family, do we should use OK response type?
+    Assert.assertEquals(Integer.class, resp.getJavaType().getRawClass());
 
     resp = meta.findResponseMeta(400);
     Assert.assertEquals(String.class, resp.getJavaType().getRawClass());
@@ -68,6 +70,7 @@ public class TestResponsesMeta {
     Assert.assertEquals(Integer.class, resp.getHeaders().get("h1").getRawClass());
 
     resp = meta.findResponseMeta(500);
-    Assert.assertEquals(CommonExceptionData.class, resp.getJavaType().getRawClass());
+    // changed to Object for new version to keep user defined error data not lose and can be parsed.
+    Assert.assertEquals(Object.class, resp.getJavaType().getRawClass());
   }
 }


[incubator-servicecomb-java-chassis] 04/10: [SCB-847]fix integration test error

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 e66da4affc43876a682b1741c6d57aa304798fc4
Author: liubao <ba...@huawei.com>
AuthorDate: Thu Aug 16 10:52:08 2018 +0800

    [SCB-847]fix integration test error
---
 demo/demo-schema/src/main/resources/microservices/pojo/server.yaml       | 1 +
 .../src/main/resources/microservices/pojo/server.yaml                    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml b/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
index d7c6a0a..985fcb7 100644
--- a/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
+++ b/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
@@ -215,3 +215,4 @@ definitions:
         type: integer
       index:
         type: number
+    x-java-class: "org.apache.servicecomb.demo.server.User"
diff --git a/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/microservices/pojo/server.yaml b/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/microservices/pojo/server.yaml
index 903bf15..3fa0fda 100644
--- a/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/microservices/pojo/server.yaml
+++ b/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/microservices/pojo/server.yaml
@@ -194,3 +194,4 @@ definitions:
         type: number
       index:
         type: number
+    x-java-class: "org.apache.servicecomb.demo.server.User"
\ No newline at end of file


[incubator-servicecomb-java-chassis] 10/10: [SCB-847]fix compile fail

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 1f5b6614099221a10c1e3cceb9a5a7adf4e3ca81
Author: liubao <ba...@huawei.com>
AuthorDate: Fri Aug 17 09:51:54 2018 +0800

    [SCB-847]fix compile fail
---
 .../apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java  | 9 +++------
 .../apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java  | 9 +++------
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
index f35efe5..3e1ea78 100644
--- a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
@@ -17,9 +17,9 @@
 
 package org.apache.servicecomb.springboot.jaxrs.client;
 
-import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
+import org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;
 import org.apache.servicecomb.demo.TestMgr;
 import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
 import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb;
@@ -31,11 +31,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 public class JaxrsClient {
 
   public static void main(String[] args) throws Exception {
-    RestObjectMapperFactory
-        .setCustomMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE, new RestObjectMapperWithStringMapper());
-    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE, new RestObjectMapper());
-    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ,
-        new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setConsumerWriterMapper(new RestObjectMapperWithStringMapperNotWriteNull());
     Log4jUtils.init();
     SpringApplication.run(JaxrsClient.class, args);
     org.apache.servicecomb.demo.jaxrs.client.JaxrsClient.run();
diff --git a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
index d74ecf0..fc133f6 100644
--- a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
+++ b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
@@ -17,9 +17,9 @@
 
 package org.apache.servicecomb.springboot.jaxrs.server;
 
-import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
+import org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;
 import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
 import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb;
 import org.springframework.boot.SpringApplication;
@@ -29,11 +29,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
 @EnableServiceComb
 public class JaxrsServer {
   public static void main(final String[] args) throws Exception {
-    RestObjectMapperFactory
-        .setCustomMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE, new RestObjectMapperWithStringMapper());
-    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE, new RestObjectMapper());
-    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ,
-        new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setConsumerWriterMapper(new RestObjectMapperWithStringMapperNotWriteNull());
     Log4jUtils.init();
     SpringApplication.run(JaxrsServer.class, args);
   }


[incubator-servicecomb-java-chassis] 09/10: [SCB-847]change mapper to two categories

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 9e99226b3295cc870922363f1ce72c33d1d1af0a
Author: liubao <ba...@huawei.com>
AuthorDate: Fri Aug 17 09:28:32 2018 +0800

    [SCB-847]change mapper to two categories
---
 .../common/rest/codec/RestObjectMapperFactory.java | 27 ++++++----------------
 .../rest/codec/param/BodyProcessorCreator.java     |  4 ++--
 .../rest/codec/param/CookieProcessorCreator.java   |  2 +-
 .../rest/codec/param/HeaderProcessorCreator.java   |  2 +-
 .../rest/codec/param/ParamValueProcessor.java      |  2 +-
 .../rest/codec/produce/ProduceJsonProcessor.java   |  4 ++--
 .../servicecomb/demo/jaxrs/client/JaxrsClient.java |  9 +++-----
 .../servicecomb/demo/jaxrs/server/JaxrsServer.java | 10 ++++----
 .../demo/RestObjectMapperWithStringMapper.java     |  2 --
 ...tObjectMapperWithStringMapperNotWriteNull.java} | 24 +++----------------
 10 files changed, 24 insertions(+), 62 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
index 65b107e..c6d5d65 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
@@ -17,40 +17,27 @@
 
 package org.apache.servicecomb.common.rest.codec;
 
-import java.util.HashMap;
-import java.util.Map;
-
 /**
  * Manage RestObjectMapper instances. Give users an option to specify custom mappers.
  */
 public class RestObjectMapperFactory {
-  public static final String KEY_PROVIDER_READ_OR_CONSUMER_READ = "provider.consumer.read";
-
-  public static final String KEY_PROVIDER_WRITE = "provider.write";
-
-  public static final String KEY_CONSUMER_WRITE = "consumer.write";
-
   private static AbstractRestObjectMapper defaultMapper = new RestObjectMapper();
 
-  private static Map<String, AbstractRestObjectMapper> allMappers = new HashMap<>();
+  private static AbstractRestObjectMapper consumerWriterMapper = new RestObjectMapper();
 
-  public static AbstractRestObjectMapper getRestObjectMapper(String key) {
-    AbstractRestObjectMapper mapper = allMappers.get(key);
-    if (mapper != null) {
-      return mapper;
-    }
-    return defaultMapper;
+  public static AbstractRestObjectMapper getConsumerWriterMapper() {
+    return consumerWriterMapper;
   }
 
   public static AbstractRestObjectMapper getRestObjectMapper() {
     return defaultMapper;
   }
 
-  public static void setDefaultRestObjectMapper(AbstractRestObjectMapper customMapper) {
-    defaultMapper = customMapper;
+  public static void setConsumerWriterMapper(AbstractRestObjectMapper customMapper) {
+    consumerWriterMapper = customMapper;
   }
 
-  public static void setCustomMapper(String key, AbstractRestObjectMapper mapper) {
-    allMappers.put(key, mapper);
+  public static void setDefaultRestObjectMapper(AbstractRestObjectMapper customMapper) {
+    defaultMapper = customMapper;
   }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
index fc40579..ff5f587 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
@@ -85,7 +85,7 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator {
       }
 
       try {
-        return RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ)
+        return RestObjectMapperFactory.getRestObjectMapper()
             .readValue(inputStream, targetType);
       } catch (MismatchedInputException e) {
         // there is no way to detect InputStream is empty, so have to catch the exception
@@ -101,7 +101,7 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator {
     public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {
       try (BufferOutputStream output = new BufferOutputStream()) {
         clientRequest.putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON);
-        RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE).writeValue(output, arg);
+        RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output, arg);
         if (arg != null) {
           clientRequest.write(output.getBuffer());
         }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
index 1688349..659637e 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
@@ -65,7 +65,7 @@ public class CookieProcessorCreator implements ParamValueProcessorCreator {
     @Override
     public void setValue(RestClientRequest clientRequest, Object arg) throws Exception {
       clientRequest.addCookie(paramPath,
-          RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE).convertToString(arg));
+          RestObjectMapperFactory.getConsumerWriterMapper().convertToString(arg));
     }
 
     @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
index 44fa146..810e018 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
@@ -75,7 +75,7 @@ public class HeaderProcessorCreator implements ParamValueProcessorCreator {
         return;
       }
       clientRequest.putHeader(paramPath,
-          RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE).convertToString(arg));
+          RestObjectMapperFactory.getConsumerWriterMapper().convertToString(arg));
     }
 
     @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
index 8753b40..e2d8b67 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
@@ -30,7 +30,7 @@ public interface ParamValueProcessor {
   void setValue(RestClientRequest clientRequest, Object arg) throws Exception;
 
   default Object convertValue(Object value, JavaType targetType) {
-    return RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ)
+    return RestObjectMapperFactory.getRestObjectMapper()
         .convertValue(value, targetType);
   }
 
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
index 4f57553..d4006c7 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
@@ -35,12 +35,12 @@ public class ProduceJsonProcessor implements ProduceProcessor {
 
   @Override
   public void doEncodeResponse(OutputStream output, Object result) throws Exception {
-    RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE).writeValue(output, result);
+    RestObjectMapperFactory.getRestObjectMapper().writeValue(output, result);
   }
 
   @Override
   public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {
-    return RestObjectMapperFactory.getRestObjectMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ)
+    return RestObjectMapperFactory.getRestObjectMapper()
         .readValue(input, type);
   }
 
diff --git a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
index d116af4..f28ffbd 100644
--- a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
+++ b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
@@ -24,13 +24,13 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response.Status;
 
 import org.apache.http.HttpStatus;
-import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.core.Const;
 import org.apache.servicecomb.core.CseContext;
 import org.apache.servicecomb.demo.CodeFirstRestTemplate;
 import org.apache.servicecomb.demo.DemoConst;
 import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
+import org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;
 import org.apache.servicecomb.demo.TestMgr;
 import org.apache.servicecomb.demo.compute.Person;
 import org.apache.servicecomb.demo.jaxrs.client.beanParam.BeanParamPojoClient;
@@ -64,11 +64,8 @@ public class JaxrsClient {
   public static void init() throws Exception {
     Log4jUtils.init();
     BeanUtils.init();
-    RestObjectMapperFactory
-        .setCustomMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE, new RestObjectMapperWithStringMapper());
-    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE, new RestObjectMapper());
-    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ,
-        new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setConsumerWriterMapper(new RestObjectMapperWithStringMapperNotWriteNull());
   }
 
   public static void run() throws Exception {
diff --git a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
index f661720..3b2d952 100644
--- a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
+++ b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
@@ -17,20 +17,18 @@
 
 package org.apache.servicecomb.demo.jaxrs.server;
 
-import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
+import org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;
 import org.apache.servicecomb.foundation.common.utils.BeanUtils;
 import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
 
 public class JaxrsServer {
   public static void main(String[] args) throws Exception {
+    RestObjectMapperFactory.setDefaultRestObjectMapper(new RestObjectMapperWithStringMapper());
+    RestObjectMapperFactory.setConsumerWriterMapper(new RestObjectMapperWithStringMapperNotWriteNull());
+
     Log4jUtils.init();
     BeanUtils.init();
-    RestObjectMapperFactory
-        .setCustomMapper(RestObjectMapperFactory.KEY_CONSUMER_WRITE, new RestObjectMapperWithStringMapper());
-    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_WRITE, new RestObjectMapper());
-    RestObjectMapperFactory.setCustomMapper(RestObjectMapperFactory.KEY_PROVIDER_READ_OR_CONSUMER_READ,
-        new RestObjectMapperWithStringMapper());
   }
 }
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java
index 6438069..d90160c 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java
@@ -24,7 +24,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.BeanUtils;
 
-import com.fasterxml.jackson.annotation.JsonInclude.Include;
 import com.fasterxml.jackson.databind.JavaType;
 
 /**
@@ -51,7 +50,6 @@ public class RestObjectMapperWithStringMapper extends RestObjectMapper {
 
   public RestObjectMapperWithStringMapper() {
     super();
-    setSerializationInclusion(Include.NON_NULL);
   }
 
   @Override
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapperNotWriteNull.java
similarity index 69%
copy from demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java
copy to demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapperNotWriteNull.java
index 6438069..9eacb22 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapper.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapperNotWriteNull.java
@@ -17,15 +17,10 @@
 
 package org.apache.servicecomb.demo;
 
-import java.io.IOException;
-
-import org.apache.servicecomb.common.rest.codec.RestObjectMapper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeanUtils;
 
 import com.fasterxml.jackson.annotation.JsonInclude.Include;
-import com.fasterxml.jackson.databind.JavaType;
 
 /**
  *  Demonstrate how to using String as raw type when using RestTemplate to invoke a service that use POJO. e.g.
@@ -44,26 +39,13 @@ import com.fasterxml.jackson.databind.JavaType;
  *  <b>Caution:</b> json will convert String to object based on String constructor, using this feature will make default
  *  conversion change. You must write  convertValue to check possible types using.
  */
-public class RestObjectMapperWithStringMapper extends RestObjectMapper {
-  private static final long serialVersionUID = 4279371572149490568L;
+public class RestObjectMapperWithStringMapperNotWriteNull extends RestObjectMapperWithStringMapper {
+  private static final long serialVersionUID = 4279371572149490560L;
 
   private static Logger LOGGER = LoggerFactory.getLogger(RestObjectMapperWithStringMapper.class);
 
-  public RestObjectMapperWithStringMapper() {
+  public RestObjectMapperWithStringMapperNotWriteNull() {
     super();
     setSerializationInclusion(Include.NON_NULL);
   }
-
-  @Override
-  public <T> T convertValue(Object fromValue, JavaType toValueType) throws IllegalArgumentException {
-    if (String.class.isInstance(fromValue)
-        && !BeanUtils.isSimpleValueType(toValueType.getRawClass())) {
-      try {
-        return super.readValue((String) fromValue, toValueType);
-      } catch (IOException e) {
-        LOGGER.error("Failed to convert value for {}.", e.getMessage());
-      }
-    }
-    return super.convertValue(fromValue, toValueType);
-  }
 }