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 2020/04/13 08:27:59 UTC

[servicecomb-java-chassis] 04/04: [SCB-1828] Support @JsonView: fixed as reviewed

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/servicecomb-java-chassis.git

commit 71821ab05f0ba936b0de142cce6fd7fadc694d80
Author: heyile <25...@qq.com>
AuthorDate: Tue Apr 7 17:43:51 2020 +0800

    [SCB-1828] Support @JsonView: fixed as reviewed
---
 .../common/rest/AbstractRestInvocation.java        |   5 +-
 .../rest/codec/param/BodyProcessorCreator.java     |  13 +-
 .../rest/codec/produce/ProduceJsonProcessor.java   |   2 +-
 .../codec/produce/ProduceProcessorManager.java     |  77 +++++--
 .../common/rest/definition/RestOperationMeta.java  | 110 ++++-----
 .../common/rest/TestAbstractRestInvocation.java    |  10 +-
 .../codec/produce/TestProduceJsonProcessor.java    |   3 +-
 .../codec/produce/TestProduceProcessorManager.java |   6 +-
 .../produce/TestProduceTextPlainProcessor.java     |   2 +-
 .../rest/definition/TestRestOperationMeta.java     | 251 ++++++++++++++-------
 .../servicecomb/demo/CodeFirstRestTemplate.java    |   5 +-
 .../foundation/common/RegisterManager.java         |   2 +-
 .../swagger/generator/SwaggerConst.java            |   2 +
 .../processor/parameter/JsonViewProcessor.java     |   4 +-
 .../rest/client/http/DefaultHttpClientFilter.java  |   3 +-
 15 files changed, 296 insertions(+), 199 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
index 15a717f..a3ebba4 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/AbstractRestInvocation.java
@@ -182,7 +182,7 @@ public abstract class AbstractRestInvocation {
       try {
         providerQpsFlowControlHandler.handle(invocation, response -> {
           qpsFlowControlReject.value = true;
-          produceProcessor = ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS);
+          produceProcessor = ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor();
           sendResponse(response);
         });
       } catch (Throwable e) {
@@ -249,8 +249,7 @@ public abstract class AbstractRestInvocation {
 
   public void sendFailResponse(Throwable throwable) {
     if (produceProcessor == null) {
-      produceProcessor = ProduceProcessorManager.INSTANCE.getDefaultProcessorMap()
-          .get(DEFAULT_SERIAL_CLASS);
+      produceProcessor = ProduceProcessorManager.INSTANCE.findDefaultProcessor();
     }
 
     Response response = Response.createProducerFail(throwable);
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 ffce833..3a612f7 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
@@ -34,7 +34,7 @@ import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.foundation.vertx.stream.BufferOutputStream;
 import org.apache.servicecomb.swagger.SwaggerUtils;
 import org.apache.servicecomb.swagger.converter.ConverterMgr;
-import org.apache.servicecomb.swagger.generator.core.processor.parameter.JsonViewProcessor;
+import org.apache.servicecomb.swagger.generator.SwaggerConst;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.util.StringUtils;
@@ -78,11 +78,12 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator {
     }
 
     public BodyProcessor(JavaType targetType, String serialViewClass, boolean isString, boolean isRequired) {
-      if (serialViewClass != null) {
+      if (!StringUtils.isEmpty(serialViewClass)) {
         try {
           this.serialViewClass = Class.forName(serialViewClass);
         } catch (Throwable e) {
           //ignore
+          LOGGER.warn("Failed to create body processor {}, annotation @JsonView may be invalid", serialViewClass, e);
         }
       }
       this.targetType = targetType;
@@ -254,11 +255,11 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator {
         genericParamType == null ? null : TypeFactory.defaultInstance().constructType(genericParamType);
     boolean rawJson = SwaggerUtils.isRawJsonType(parameter);
     if (rawJson) {
-      return new RawJsonBodyProcessor(targetType, (String) parameter.getVendorExtensions().get(
-          JsonViewProcessor.VENDOR_EXTENSION_KEY), isString, parameter.getRequired());
+      return new RawJsonBodyProcessor(targetType, (String) parameter.getVendorExtensions()
+          .get(SwaggerConst.EXT_JSON_VIEW), isString, parameter.getRequired());
     }
 
-    return new BodyProcessor(targetType, (String) parameter.getVendorExtensions().get(
-        JsonViewProcessor.VENDOR_EXTENSION_KEY), isString, parameter.getRequired());
+    return new BodyProcessor(targetType, (String) parameter.getVendorExtensions()
+        .get(SwaggerConst.EXT_JSON_VIEW), isString, parameter.getRequired());
   }
 }
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 c25f6f2..61989af 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
@@ -33,7 +33,7 @@ public class ProduceJsonProcessor implements ProduceProcessor {
   @Override
   public String getSerializationView() {
     return serializationView == null ? ProduceProcessor.super.getSerializationView()
-        : serializationView.getCanonicalName();
+        : serializationView.getName();
   }
 
   @Override
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
index b7ad3dc..916ad4f 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProcessorManager.java
@@ -27,6 +27,7 @@ import org.apache.servicecomb.foundation.common.RegisterManager;
 import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.util.CollectionUtils;
 
 public final class ProduceProcessorManager extends RegisterManager<String, Map<String, ProduceProcessor>> {
   private static final Logger LOGGER = LoggerFactory.getLogger(ProduceProcessorManager.class);
@@ -42,6 +43,8 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S
 
   public static final ProduceProcessorManager INSTANCE = new ProduceProcessorManager();
 
+  private Map<String, ProduceProcessor> nonSerialViewMap = new HashMap<>();
+
   private Map<String, ProduceProcessor> jsonProcessorMap;
 
   private Map<String, ProduceProcessor> plainProcessorMap;
@@ -51,6 +54,7 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S
   private ProduceProcessorManager() {
     super(NAME);
     produceProcessor.forEach(processor -> {
+      nonSerialViewMap.put(processor.getName(), processor);
       Map<String, ProduceProcessor> prodProcessorMap = getObjMap()
           .computeIfAbsent(processor.getName(), key -> new HashMap<>());
       prodProcessorMap.putIfAbsent(processor.getSerializationView(), processor);
@@ -60,7 +64,7 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S
     defaultProcessorMap = jsonProcessorMap;
   }
 
-  public static ProduceProcessor cloneNewProduceProcessor(String acceptType, Class<?> serialViewClass,
+  private static ProduceProcessor cloneNewProduceProcessor(Class<?> serialViewClass,
       Map<String, ProduceProcessor> produceViewMap) {
     ProduceProcessor newInstance;
     try {
@@ -68,38 +72,71 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S
       newInstance.setSerializationView(serialViewClass);
       return newInstance;
     } catch (Throwable e) {
-      LOGGER.error(String.format("Failed to create produceProcessor with %s", acceptType), e);
+      // ignore exception
+      LOGGER.warn("Failed to create produceProcessor with {}", serialViewClass.getName(), e);
     }
     return produceViewMap.get(DEFAULT_SERIAL_CLASS);
   }
 
-  public Map<String, ProduceProcessor> getJsonProcessorMap() {
-    return jsonProcessorMap;
+  // key -> accept type
+  public Map<String, ProduceProcessor> getOrCreateAcceptMap(Class<?> serialViewClass) {
+    if (serialViewClass == null) {
+      return nonSerialViewMap;
+    }
+    Map<String, ProduceProcessor> result = new HashMap<>();
+    getObjMap().forEach((acceptKey, viewMap) -> {
+      ProduceProcessor produceProcessor = viewMap.computeIfAbsent(serialViewClass.getName(),
+          viewKey -> cloneNewProduceProcessor(serialViewClass, viewMap));
+      result.put(acceptKey, produceProcessor);
+    });
+    return result;
+  }
+
+  public ProduceProcessor findProcessor(String acceptType, Class<?> serialViewClass) {
+    Map<String, ProduceProcessor> viewMap = findValue(acceptType);
+    if (CollectionUtils.isEmpty(viewMap)) {
+      return null;
+    }
+    if (serialViewClass == null) {
+      return viewMap.get(DEFAULT_SERIAL_CLASS);
+    }
+    return viewMap.computeIfAbsent(serialViewClass.getName(),
+        viewKey -> cloneNewProduceProcessor(serialViewClass, viewMap));
+  }
+
+  public ProduceProcessor findJsonProcessorByViewClass(Class<?> serialViewClass) {
+    if (serialViewClass == null) {
+      return jsonProcessorMap.get(DEFAULT_SERIAL_CLASS);
+    }
+    return jsonProcessorMap.computeIfAbsent(serialViewClass.getName(),
+        viewKey -> cloneNewProduceProcessor(serialViewClass, jsonProcessorMap));
   }
 
-  public ProduceProcessorManager setJsonProcessorMap(
-      Map<String, ProduceProcessor> jsonProcessorMap) {
-    this.jsonProcessorMap = jsonProcessorMap;
-    return this;
+  public ProduceProcessor findDefaultProcessorByViewClass(Class<?> serialViewClass) {
+    if (serialViewClass == null) {
+      return defaultProcessorMap.get(DEFAULT_SERIAL_CLASS);
+    }
+    return defaultProcessorMap.computeIfAbsent(serialViewClass.getName(),
+        viewKey -> cloneNewProduceProcessor(serialViewClass, defaultProcessorMap));
   }
 
-  public Map<String, ProduceProcessor> getPlainProcessorMap() {
-    return plainProcessorMap;
+  public ProduceProcessor findPlainProcessorByViewClass(Class<?> serialViewClass) {
+    if (serialViewClass == null) {
+      return plainProcessorMap.get(DEFAULT_SERIAL_CLASS);
+    }
+    return plainProcessorMap.computeIfAbsent(serialViewClass.getName(),
+        viewKey -> cloneNewProduceProcessor(serialViewClass, plainProcessorMap));
   }
 
-  public ProduceProcessorManager setPlainProcessorMap(
-      Map<String, ProduceProcessor> plainProcessorMap) {
-    this.plainProcessorMap = plainProcessorMap;
-    return this;
+  public ProduceProcessor findDefaultJsonProcessor() {
+    return jsonProcessorMap.get(DEFAULT_SERIAL_CLASS);
   }
 
-  public Map<String, ProduceProcessor> getDefaultProcessorMap() {
-    return defaultProcessorMap;
+  public ProduceProcessor findDefaultProcessor() {
+    return defaultProcessorMap.get(DEFAULT_SERIAL_CLASS);
   }
 
-  public ProduceProcessorManager setDefaultProcessorMap(
-      Map<String, ProduceProcessor> defaultProcessorMap) {
-    this.defaultProcessorMap = defaultProcessorMap;
-    return this;
+  public ProduceProcessor findDefaultPlainProcessor() {
+    return plainProcessorMap.get(DEFAULT_SERIAL_CLASS);
   }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
index c952221..715eb24 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/definition/RestOperationMeta.java
@@ -76,10 +76,10 @@ public class RestOperationMeta {
   protected List<String> fileKeys = new ArrayList<>();
 
   // key为数据类型,比如json之类
-  private Map<String, Map<String, ProduceProcessor>> produceProcessorAcceptMap = new LinkedHashMap<>();
+  private Map<String, ProduceProcessor> produceProcessorMap = new LinkedHashMap<>();
 
   // 不一定等于mgr中的default,因为本operation可能不支持mgr中的default
-  private Map<String, ProduceProcessor> defaultProcessorViewMap;
+  private ProduceProcessor defaultProcessor;
 
   protected String absolutePath;
 
@@ -218,33 +218,61 @@ public class RestOperationMeta {
     return operationMeta;
   }
 
-  // 为operation创建支持的多种produce processor
   protected void createProduceProcessors() {
+    SwaggerProducerOperation producerOperation = operationMeta.getExtData(Const.PRODUCER_OPERATION);
+    if (producerOperation != null && producerOperation.getProducerMethod() != null) {
+      createProduceProcessors(producerOperation.getProducerMethod().getDeclaredAnnotations());
+      return;
+    }
+    createProduceProcessors(null);
+  }
+
+  // serialViewClass is deterministic for each operation
+  protected void createProduceProcessors(Annotation[] annotations) {
+    if (annotations == null || annotations.length < 1) {
+      doCreateProduceProcessors(null);
+      return;
+    }
+    for (Annotation annotation : annotations) {
+      if (annotation.annotationType() == JsonView.class) {
+        Class<?>[] value = ((JsonView) annotation).value();
+        if (value.length != 1) {
+          throw new IllegalArgumentException(
+              "@JsonView only supported for exactly 1 class argument ");
+        }
+        doCreateProduceProcessors(value[0]);
+        return;
+      }
+    }
+    doCreateProduceProcessors(null);
+  }
+
+  // 为operation创建支持的多种produce processor
+  protected void doCreateProduceProcessors(Class<?> serialViewClass) {
     if (null == produces || produces.isEmpty()) {
-      ProduceProcessorManager.INSTANCE.getObjMap().forEach((processorName, prodMap) -> {
-        this.produceProcessorAcceptMap.put(processorName, prodMap);
-      });
+      produceProcessorMap.putAll(
+          ProduceProcessorManager.INSTANCE.getOrCreateAcceptMap(serialViewClass));
     } else {
       for (String produce : produces) {
         if (produce.contains(";")) {
           produce = produce.substring(0, produce.indexOf(";"));
         }
-        Map<String, ProduceProcessor> processorMap = ProduceProcessorManager.INSTANCE.findValue(produce);
-        if (processorMap == null) {
+        ProduceProcessor processor = ProduceProcessorManager.INSTANCE.findProcessor(produce, serialViewClass);
+        if (processor == null) {
           LOGGER.error("produce {} is not supported", produce);
           continue;
         }
-        this.produceProcessorAcceptMap.put(produce, processorMap);
+        this.produceProcessorMap.put(produce, processor);
       }
 
-      if (produceProcessorAcceptMap.isEmpty()) {
-        produceProcessorAcceptMap
-            .put(ProduceProcessorManager.DEFAULT_TYPE, ProduceProcessorManager.INSTANCE.getDefaultProcessorMap());
+      if (produceProcessorMap.isEmpty()) {
+        produceProcessorMap.put(ProduceProcessorManager.DEFAULT_TYPE,
+            ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(serialViewClass));
       }
     }
 
-    defaultProcessorViewMap = produceProcessorAcceptMap.values().stream().findFirst().get();
-    produceProcessorAcceptMap.putIfAbsent(MediaType.WILDCARD, defaultProcessorViewMap);
+    defaultProcessor = produceProcessorMap.values().stream().findFirst().get();
+    produceProcessorMap.putIfAbsent(MediaType.WILDCARD, defaultProcessor);
   }
 
   public URLPathBuilder getPathBuilder() {
@@ -263,71 +291,31 @@ public class RestOperationMeta {
     paramMap.put(param.getParamName(), param);
   }
 
-  public ProduceProcessor findProduceProcessor(String type, String serialView) {
-    if (this.produceProcessorAcceptMap.get(type) == null) {
-      LOGGER.error(String.format("Unable to  find produce processor with type/%s", type));
-      return null;
-    }
-    return this.produceProcessorAcceptMap.get(type).get(serialView);
-  }
-
   public ProduceProcessor findProduceProcessor(String type) {
-    return findProduceProcessor(type, ProduceProcessorManager.DEFAULT_SERIAL_CLASS);
+    return this.produceProcessorMap.get(type);
   }
 
   // 选择与accept匹配的produce processor或者缺省的
   public ProduceProcessor ensureFindProduceProcessor(HttpServletRequestEx requestEx) {
     String acceptType = requestEx.getHeader(HttpHeaders.ACCEPT);
-    SwaggerProducerOperation producerOperation = operationMeta.getExtData(Const.PRODUCER_OPERATION);
-    if (producerOperation == null || producerOperation.getProducerMethod() == null) {
-      return ensureFindProduceProcessor(acceptType);
-    }
-    return ensureFindProduceProcessor(acceptType, producerOperation.getProducerMethod().getDeclaredAnnotations());
+    return ensureFindProduceProcessor(acceptType);
   }
 
   public ProduceProcessor ensureFindProduceProcessor(String acceptType) {
-    return doEnsureFindProduceProcessor(acceptType, null);
-  }
-
-  public ProduceProcessor ensureFindProduceProcessor(String acceptType, Annotation[] annotations) {
-    if (annotations == null || annotations.length < 1) {
-      return doEnsureFindProduceProcessor(acceptType, null);
-    }
-    for (Annotation annotation : annotations) {
-      if (annotation.annotationType() == JsonView.class) {
-        Class<?>[] value = ((JsonView) annotation).value();
-        if (value.length != 1) {
-          throw new IllegalArgumentException(
-              "@JsonView only supported for exactly 1 class argument ");
-        }
-        return doEnsureFindProduceProcessor(acceptType, value[0]);
-      }
-    }
-    return doEnsureFindProduceProcessor(acceptType, null);
-  }
-
-  private ProduceProcessor doEnsureFindProduceProcessor(String acceptType, Class<?> serialViewClass) {
-    String serialViewKey =
-        (serialViewClass == null ? ProduceProcessorManager.DEFAULT_SERIAL_CLASS : serialViewClass.getCanonicalName());
     if (downloadFile) {
       //do not check accept type, when the produces of provider is text/plain there will return text/plain processor
       //when the produces of provider is application/json there will return the application/json processor
       //so do not care what accept type the consumer will set.
-      return this.produceProcessorAcceptMap.get(MediaType.WILDCARD)
-          .computeIfAbsent(serialViewKey, key -> ProduceProcessorManager.cloneNewProduceProcessor(
-              acceptType, serialViewClass, produceProcessorAcceptMap.get(MediaType.WILDCARD)));
+      return this.produceProcessorMap.get(MediaType.WILDCARD);
     }
     if (StringUtils.isEmpty(acceptType)) {
-      return defaultProcessorViewMap
-          .computeIfAbsent(serialViewKey, key -> ProduceProcessorManager.cloneNewProduceProcessor(
-              acceptType, serialViewClass, defaultProcessorViewMap));
+      return defaultProcessor;
     }
     List<String> mimeTypes = MimeTypesUtils.getSortedAcceptableMimeTypes(acceptType.toLowerCase(Locale.US));
     for (String mime : mimeTypes) {
-      Map<String, ProduceProcessor> processorMap = this.produceProcessorAcceptMap.get(mime);
-      if (null != processorMap) {
-        return processorMap.computeIfAbsent(serialViewKey, key ->
-            ProduceProcessorManager.cloneNewProduceProcessor(acceptType, serialViewClass, processorMap));
+      ProduceProcessor processor = this.produceProcessorMap.get(mime);
+      if (null != processor) {
+        return processor;
       }
     }
 
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
index 15eb233..2880499 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/TestAbstractRestInvocation.java
@@ -17,7 +17,6 @@
 
 package org.apache.servicecomb.common.rest;
 
-import static org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager.DEFAULT_SERIAL_CLASS;
 import static org.junit.Assert.assertEquals;
 
 import java.util.Arrays;
@@ -171,7 +170,7 @@ public class TestAbstractRestInvocation {
   }
 
   private void initRestInvocation() {
-    restInvocation.produceProcessor = ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS);
+    restInvocation.produceProcessor = ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor();
     restInvocation.requestEx = requestEx;
     restInvocation.responseEx = responseEx;
     restInvocation.invocation = invocation;
@@ -453,7 +452,7 @@ public class TestAbstractRestInvocation {
     restInvocation.produceProcessor = null;
     restInvocation.sendFailResponse(new RuntimeExceptionWithoutStackTrace());
 
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),
         restInvocation.produceProcessor);
   }
 
@@ -471,14 +470,13 @@ public class TestAbstractRestInvocation {
       }
     };
     initRestInvocation();
-    restInvocation.produceProcessor = ProduceProcessorManager.INSTANCE.getPlainProcessorMap().get(DEFAULT_SERIAL_CLASS);
+    restInvocation.produceProcessor = ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor();
 
     Throwable e = new InvocationException(Status.BAD_GATEWAY, "");
     restInvocation.sendFailResponse(e);
     Assert.assertSame(e, result.value.getResult());
     Assert.assertSame(
-        ProduceProcessorManager.INSTANCE.getPlainProcessorMap().get(ProduceProcessorManager.DEFAULT_SERIAL_CLASS),
-        restInvocation.produceProcessor);
+        ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(), restInvocation.produceProcessor);
   }
 
   public static class SendResponseQuietlyNormalEventHandler {
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceJsonProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceJsonProcessor.java
index f5337f0..dcd5ea4 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceJsonProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceJsonProcessor.java
@@ -33,8 +33,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
 import io.vertx.core.buffer.Buffer;
 
 public class TestProduceJsonProcessor {
-  ProduceProcessor pp = ProduceProcessorManager.INSTANCE.getJsonProcessorMap()
-      .get(DEFAULT_SERIAL_CLASS);
+  ProduceProcessor pp = ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor();
 
   JavaType stringType = TypeFactory.defaultInstance().constructType(String.class);
 
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceProcessorManager.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceProcessorManager.java
index 4f7abfd..1c08656 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceProcessorManager.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceProcessorManager.java
@@ -17,15 +17,13 @@
 
 package org.apache.servicecomb.common.rest.codec.produce;
 
-import static org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager.DEFAULT_SERIAL_CLASS;
-
 import org.junit.Assert;
 import org.junit.Test;
 
 public class TestProduceProcessorManager {
   @Test
   public void testDefault() {
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS),
-        ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),
+        ProduceProcessorManager.INSTANCE.findDefaultProcessor());
   }
 }
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceTextPlainProcessor.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceTextPlainProcessor.java
index 3709f91..aa6eca9 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceTextPlainProcessor.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/produce/TestProduceTextPlainProcessor.java
@@ -32,7 +32,7 @@ import com.fasterxml.jackson.databind.type.TypeFactory;
 import io.vertx.core.buffer.Buffer;
 
 public class TestProduceTextPlainProcessor {
-  ProduceProcessor pp = ProduceProcessorManager.INSTANCE.getPlainProcessorMap().get(DEFAULT_SERIAL_CLASS);
+  ProduceProcessor pp = ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor();
 
   JavaType stringType = TypeFactory.defaultInstance().constructType(String.class);
 
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/TestRestOperationMeta.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/TestRestOperationMeta.java
index 79ca0bb..830be4b 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/TestRestOperationMeta.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/definition/TestRestOperationMeta.java
@@ -17,12 +17,10 @@
 
 package org.apache.servicecomb.common.rest.definition;
 
-import static org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager.DEFAULT_SERIAL_CLASS;
 import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertThat;
 
 import java.io.File;
-import java.lang.annotation.Annotation;
 import java.util.Arrays;
 
 import javax.ws.rs.FormParam;
@@ -30,7 +28,6 @@ import javax.ws.rs.GET;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
-import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 
 import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
@@ -38,7 +35,6 @@ import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;
 import org.apache.servicecomb.core.SCBEngine;
 import org.apache.servicecomb.core.bootstrap.SCBBootstrap;
 import org.apache.servicecomb.core.definition.OperationMeta;
-import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
@@ -48,7 +44,6 @@ import com.fasterxml.jackson.annotation.JsonView;
 
 import io.swagger.models.Swagger;
 import mockit.Expectations;
-import mockit.Mocked;
 
 public class TestRestOperationMeta {
   @Path("/")
@@ -60,6 +55,14 @@ public class TestRestOperationMeta {
       return null;
     }
 
+    @Path("/emptyProducesWithView")
+    @GET
+    @Produces("")
+    @JsonView(Object.class)
+    public String emptyProducesWithView() {
+      return null;
+    }
+
     @Path("/notSupport")
     @GET
     @Produces("notSupport")
@@ -67,6 +70,14 @@ public class TestRestOperationMeta {
 
     }
 
+    @Path("/notSupportWithView")
+    @GET
+    @Produces("notSupport")
+    @JsonView(Object.class)
+    public void notSupportWithView() {
+
+    }
+
     @Path("/textPlain")
     @GET
     @Produces(MediaType.TEXT_PLAIN)
@@ -74,6 +85,14 @@ public class TestRestOperationMeta {
       return null;
     }
 
+    @Path("/textPlainWithView")
+    @GET
+    @Produces(MediaType.TEXT_PLAIN)
+    @JsonView(Object.class)
+    public String textPlainWithView() {
+      return null;
+    }
+
     @Path("/json")
     @GET
     @Produces(MediaType.APPLICATION_JSON)
@@ -81,6 +100,14 @@ public class TestRestOperationMeta {
       return null;
     }
 
+    @Path("/jsonWithView")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @JsonView(Object.class)
+    public String jsonWithView() {
+      return null;
+    }
+
     @Path("/textCharJsonChar")
     @GET
     @Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8", MediaType.TEXT_PLAIN + ";charset=UTF-8"})
@@ -88,6 +115,14 @@ public class TestRestOperationMeta {
 
     }
 
+    @Path("/textCharJsonCharWithView")
+    @GET
+    @Produces({MediaType.APPLICATION_JSON + ";charset=UTF-8", MediaType.TEXT_PLAIN + ";charset=UTF-8"})
+    @JsonView(Object.class)
+    public void textCharJsonCharWithView() {
+
+    }
+
     @Path("/download")
     @GET
     @Produces(MediaType.APPLICATION_JSON)
@@ -95,10 +130,23 @@ public class TestRestOperationMeta {
       return null;
     }
 
+    @Path("/downloadWithView")
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    @JsonView(Object.class)
+    public File downloadWithView() {
+      return null;
+    }
+
     @Path("/form")
     @POST
     public void form(@FormParam("form") String form) {
     }
+
+    @Path("/formWithView")
+    @POST
+    public void formWithView(@FormParam("form") String form) {
+    }
   }
 
   static SCBEngine scbEngine;
@@ -133,14 +181,32 @@ public class TestRestOperationMeta {
     operationMeta.produces = null;
     operationMeta.createProduceProcessors();
 
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor((String) null));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor("*/*"));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
+    for (String produce : ProduceProcessorManager.INSTANCE.keys()) {
+      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findProcessor(produce, null);
+      Assert.assertSame(expected, operationMeta.findProduceProcessor(produce));
+    }
+  }
+
+  @Test
+  public void testCreateProduceProcessorsNullWithView() {
+    findOperation("emptyProducesWithView");
+    operationMeta.produces = null;
+    operationMeta.createProduceProcessors();
+
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor((String) null));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor("*/*"));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
     for (String produce : ProduceProcessorManager.INSTANCE.keys()) {
-      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findValue(produce).get(DEFAULT_SERIAL_CLASS);
+      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findProcessor(produce, Object.class);
       Assert.assertSame(expected, operationMeta.findProduceProcessor(produce));
     }
   }
@@ -151,14 +217,32 @@ public class TestRestOperationMeta {
     operationMeta.produces = Arrays.asList();
     operationMeta.createProduceProcessors();
 
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor((String) null));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor("*/*"));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
+    for (String produce : ProduceProcessorManager.INSTANCE.keys()) {
+      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findProcessor(produce, null);
+      Assert.assertSame(expected, operationMeta.findProduceProcessor(produce));
+    }
+  }
+
+  @Test
+  public void testCreateProduceProcessorsEmptyWithView() {
+    findOperation("emptyProducesWithView");
+    operationMeta.produces = Arrays.asList();
+    operationMeta.createProduceProcessors();
+
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor((String) null));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor("*/*"));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
     for (String produce : ProduceProcessorManager.INSTANCE.keys()) {
-      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findValue(produce).get(DEFAULT_SERIAL_CLASS);
+      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findProcessor(produce, Object.class);
       Assert.assertSame(expected, operationMeta.findProduceProcessor(produce));
     }
   }
@@ -167,13 +251,28 @@ public class TestRestOperationMeta {
   public void testCreateProduceProcessorsNormal() {
     findOperation("json");
 
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor((String) null));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor("*/*"));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
+        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),
+        operationMeta.findProduceProcessor(MediaType.APPLICATION_JSON));
+    Assert.assertNull(operationMeta.findProduceProcessor(MediaType.TEXT_PLAIN));
+  }
+
+  @Test
+  public void testCreateProduceProcessorsNormalWithView() {
+    findOperation("jsonWithView");
+
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor((String) null));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor("*/*"));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
         operationMeta.findProduceProcessor(MediaType.APPLICATION_JSON));
     Assert.assertNull(operationMeta.findProduceProcessor(MediaType.TEXT_PLAIN));
   }
@@ -182,13 +281,28 @@ public class TestRestOperationMeta {
   public void testCreateProduceProcessorsNotSupported() {
     findOperation("notSupport");
 
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
         operationMeta.ensureFindProduceProcessor((String) null));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
         operationMeta.ensureFindProduceProcessor("*/*"));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getDefaultProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
         operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),
+        operationMeta.findProduceProcessor(MediaType.APPLICATION_JSON));
+    Assert.assertNull(operationMeta.findProduceProcessor(MediaType.TEXT_PLAIN));
+  }
+
+  @Test
+  public void testCreateProduceProcessorsNotSupportedWithView() {
+    findOperation("notSupportWithView");
+
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
+        operationMeta.ensureFindProduceProcessor((String) null));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
+        operationMeta.ensureFindProduceProcessor("*/*"));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
+        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
         operationMeta.findProduceProcessor(MediaType.APPLICATION_JSON));
     Assert.assertNull(operationMeta.findProduceProcessor(MediaType.TEXT_PLAIN));
   }
@@ -197,94 +311,59 @@ public class TestRestOperationMeta {
   public void testCreateProduceProcessorsTextAndWildcard() {
     findOperation("textPlain");
 
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getPlainProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(),
         operationMeta.ensureFindProduceProcessor(MediaType.WILDCARD));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getPlainProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(),
         operationMeta.ensureFindProduceProcessor(MediaType.TEXT_PLAIN));
     Assert.assertNull(operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getPlainProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(),
         operationMeta.ensureFindProduceProcessor(
             MediaType.APPLICATION_JSON + "," + MediaType.APPLICATION_XML + "," + MediaType.WILDCARD));
   }
 
   @Test
-  public void testCreateProduceProcessorsWithSemicolon() {
-    findOperation("textCharJsonChar");
+  public void testCreateProduceProcessorsTextAndWildcardWithView() {
+    findOperation("textPlainWithView");
 
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getPlainProcessorMap().get(DEFAULT_SERIAL_CLASS),
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findPlainProcessorByViewClass(Object.class),
+        operationMeta.ensureFindProduceProcessor(MediaType.WILDCARD));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findPlainProcessorByViewClass(Object.class),
         operationMeta.ensureFindProduceProcessor(MediaType.TEXT_PLAIN));
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS),
-        operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
-  }
-
-  @Test
-  public void testEnsureFindProduceProcessorRequest(@Mocked HttpServletRequestEx requestEx,
-      @Mocked JsonView annotation) {
-    findOperation("emptyProduces");
-    new Expectations() {
-      {
-        requestEx.getHeader(HttpHeaders.ACCEPT);
-        result = null;
-        annotation.value();
-        result = Object.class;
-      }
-    };
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS),
-        operationMeta.ensureFindProduceProcessor(requestEx));
-
-    ProduceProcessor actualProcessor = operationMeta
-        .ensureFindProduceProcessor(requestEx.getHeader(HttpHeaders.ACCEPT), new Annotation[] {annotation});
-    ProduceProcessor expectProcessor = ProduceProcessorManager.INSTANCE.getJsonProcessorMap()
-        .get(Object.class.getCanonicalName());
-    Assert.assertSame(expectProcessor, actualProcessor);
-    Assert.assertEquals(expectProcessor.getSerializationView(), Object.class.getCanonicalName());
+    Assert.assertNull(operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findPlainProcessorByViewClass(Object.class),
+        operationMeta.ensureFindProduceProcessor(
+            MediaType.APPLICATION_JSON + "," + MediaType.APPLICATION_XML + "," + MediaType.WILDCARD));
   }
 
   @Test
-  public void testEnsureFindProduceProcessorAcceptFound(@Mocked JsonView annotation) {
+  public void testCreateProduceProcessorsWithSemicolon() {
     findOperation("textCharJsonChar");
-    new Expectations() {
-      {
-        annotation.value();
-        result = Object.class;
-      }
-    };
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS),
-        operationMeta.ensureFindProduceProcessor("text/plain;q=0.7;charset=utf-8,application/json;q=0.8"));
-
-    ProduceProcessor actualProcessor = operationMeta
-        .ensureFindProduceProcessor("text/plain;q=0.7;charset=utf-8,application/json;q=0.8",
-            new Annotation[] {annotation});
-    ProduceProcessor expectProcessor = ProduceProcessorManager.INSTANCE.getJsonProcessorMap()
-        .get(Object.class.getCanonicalName());
-    Assert.assertSame(expectProcessor, actualProcessor);
-    Assert.assertEquals(expectProcessor.getSerializationView(), Object.class.getCanonicalName());
+
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(),
+        operationMeta.ensureFindProduceProcessor(MediaType.TEXT_PLAIN));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),
+        operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
   }
 
   @Test
-  public void testEnsureFindProduceProcessorWithDownload(@Mocked JsonView annotation) {
-    findOperation("download");
-    new Expectations() {
-      {
-        annotation.value();
-        result = Object.class;
-      }
-    };
-    Assert.assertSame(ProduceProcessorManager.INSTANCE.getJsonProcessorMap().get(DEFAULT_SERIAL_CLASS),
-        operationMeta.ensureFindProduceProcessor("text/plain"));
-
-    ProduceProcessor actualProcessor = operationMeta
-        .ensureFindProduceProcessor("text/plain", new Annotation[] {annotation});
-    ProduceProcessor expectProcessor = ProduceProcessorManager.INSTANCE.getJsonProcessorMap()
-        .get(Object.class.getCanonicalName());
-    Assert.assertSame(expectProcessor, actualProcessor);
-    Assert.assertEquals(expectProcessor.getSerializationView(), Object.class.getCanonicalName());
+  public void testCreateProduceProcessorsWithSemicolonWithView() {
+    findOperation("textCharJsonCharWithView");
+
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findPlainProcessorByViewClass(Object.class),
+        operationMeta.ensureFindProduceProcessor(MediaType.TEXT_PLAIN));
+    Assert.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
+        operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
   }
 
   @Test
   public void testEnsureFindProduceProcessorAcceptNotFound() {
     findOperation("textCharJsonChar");
+    Assert.assertNull(operationMeta.ensureFindProduceProcessor("notSupport"));
+  }
 
+  @Test
+  public void testEnsureFindProduceProcessorAcceptNotFoundWithView() {
+    findOperation("textCharJsonCharWithView");
     Assert.assertNull(operationMeta.ensureFindProduceProcessor("notSupport"));
   }
 
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
index db0f694..9e49f24 100644
--- a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CodeFirstRestTemplate.java
@@ -17,8 +17,6 @@
 
 package org.apache.servicecomb.demo;
 
-import static org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager.DEFAULT_SERIAL_CLASS;
-
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
@@ -148,8 +146,7 @@ public class CodeFirstRestTemplate {
         HttpMethod.POST,
         requestEntity,
         JAXBPerson.class);
-    TestMgr.check(-1, ProduceProcessorManager.INSTANCE.ensureFindValue(MediaType.APPLICATION_XML_VALUE)
-        .get(DEFAULT_SERIAL_CLASS).getOrder());
+    TestMgr.check(-1, ProduceProcessorManager.INSTANCE.findProcessor(MediaType.APPLICATION_XML_VALUE, null).getOrder());
     TestMgr.check(person, resEntity.getBody());
   }
 
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/RegisterManager.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/RegisterManager.java
index cf26de5..f3608c6 100644
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/RegisterManager.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/RegisterManager.java
@@ -69,7 +69,7 @@ public class RegisterManager<KEY, VALUE> {
     }
   }
 
-  public Map<KEY, VALUE> getObjMap() {
+  protected Map<KEY, VALUE> getObjMap() {
     return objMap;
   }
 
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerConst.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerConst.java
index e41e6a6..b9d7b00 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerConst.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/SwaggerConst.java
@@ -31,4 +31,6 @@ public final class SwaggerConst {
   public static final String EXT_JAVA_CLASS = "x-java-class";
 
   public static final String EXT_RAW_JSON_TYPE = "x-raw-json";
+
+  public static final String EXT_JSON_VIEW = "x-json-view";
 }
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/JsonViewProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/JsonViewProcessor.java
index e157e5c..1f5e817 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/JsonViewProcessor.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/parameter/JsonViewProcessor.java
@@ -20,6 +20,7 @@ import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 
 import org.apache.servicecomb.swagger.generator.ParameterProcessor;
+import org.apache.servicecomb.swagger.generator.SwaggerConst;
 import org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;
 
 import com.fasterxml.jackson.annotation.JsonView;
@@ -29,7 +30,6 @@ import io.swagger.models.Swagger;
 import io.swagger.models.parameters.Parameter;
 
 public class JsonViewProcessor implements ParameterProcessor<Parameter, Annotation> {
-  public static final String VENDOR_EXTENSION_KEY = "x-json-view";
 
   @Override
   public Type getProcessType() {
@@ -58,6 +58,6 @@ public class JsonViewProcessor implements ParameterProcessor<Parameter, Annotati
       throw new IllegalArgumentException(
           "@JsonView only supported for exactly 1 class argument ");
     }
-    parameter.getVendorExtensions().put(VENDOR_EXTENSION_KEY, jvValue[0].getName());
+    parameter.getVendorExtensions().put(SwaggerConst.EXT_JSON_VIEW, jvValue[0].getName());
   }
 }
\ No newline at end of file
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 9030c53..1e60b06 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
@@ -97,8 +97,7 @@ public class DefaultHttpClientFilter implements HttpClientFilter {
               responseEx.getStatusType().getReasonPhrase(),
               responseEx.getHeader(HttpHeaders.CONTENT_TYPE));
       LOGGER.warn(msg);
-      produceProcessor = ProduceProcessorManager.INSTANCE.getDefaultProcessorMap()
-          .get(ProduceProcessorManager.DEFAULT_SERIAL_CLASS);
+      produceProcessor = ProduceProcessorManager.INSTANCE.findDefaultProcessor();
     }
 
     try {