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 2023/08/23 00:55:09 UTC

[servicecomb-java-chassis] 04/06: [SCB-2803]add response proto-buffer codec

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 2607f03314d7fb6e18e0d2f4188783bd56142220
Author: liubao <bi...@qq.com>
AuthorDate: Tue Aug 22 17:33:45 2023 +0800

    [SCB-2803]add response proto-buffer codec
---
 .../common/rest/HttpTransportContext.java          |  11 +-
 .../common/rest/RestProducerInvocationCreator.java |  17 --
 .../rest/RestVertxProducerInvocationCreator.java   |   3 +-
 .../common/rest/VertxHttpTransportContext.java     |   5 +-
 .../rest/codec/param/BodyProcessorCreator.java     |  10 +-
 .../codec/produce/ProduceProcessorManager.java     |  90 +++++-----
 .../codec/produce/ProduceProtoBufferProcessor.java | 107 +++++++++++
 .../codec/produce/ProduceTextPlainProcessor.java   |  23 +--
 .../common/rest/definition/RestOperationMeta.java  | 124 -------------
 .../rest/filter/inner/RestServerCodecFilter.java   |   8 +-
 .../rest/RestProducerInvocationCreatorTest.java    |  39 +----
 .../common/rest/codec/TestRestCodec.java           |   3 +-
 .../produce/TestProduceTextPlainProcessor.java     |   4 +-
 .../rest/definition/TestRestOperationMeta.java     | 195 ---------------------
 .../filter/inner/RestServerCodecFilterTest.java    |  33 ++--
 .../transport/rest/client/RestClientDecoder.java   |   7 +-
 .../RestServletProducerInvocationCreator.java      |   2 +-
 17 files changed, 226 insertions(+), 455 deletions(-)

diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/HttpTransportContext.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/HttpTransportContext.java
index b9c8ea20a..d9b0df27c 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/HttpTransportContext.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/HttpTransportContext.java
@@ -16,7 +16,6 @@
  */
 package org.apache.servicecomb.common.rest;
 
-import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
 import org.apache.servicecomb.swagger.invocation.context.TransportContext;
@@ -26,13 +25,9 @@ public class HttpTransportContext implements TransportContext {
 
   private final HttpServletResponseEx responseEx;
 
-  private final ProduceProcessor produceProcessor;
-
-  public HttpTransportContext(HttpServletRequestEx requestEx, HttpServletResponseEx responseEx,
-      ProduceProcessor produceProcessor) {
+  public HttpTransportContext(HttpServletRequestEx requestEx, HttpServletResponseEx responseEx) {
     this.requestEx = requestEx;
     this.responseEx = responseEx;
-    this.produceProcessor = produceProcessor;
   }
 
   public HttpServletRequestEx getRequestEx() {
@@ -42,8 +37,4 @@ public class HttpTransportContext implements TransportContext {
   public HttpServletResponseEx getResponseEx() {
     return responseEx;
   }
-
-  public ProduceProcessor getProduceProcessor() {
-    return produceProcessor;
-  }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreator.java
index e38f228c7..778f3de4c 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreator.java
@@ -16,9 +16,7 @@
  */
 package org.apache.servicecomb.common.rest;
 
-import static jakarta.ws.rs.core.Response.Status.NOT_ACCEPTABLE;
 import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
-import static org.apache.servicecomb.core.exception.ExceptionCodes.GENERIC_CLIENT;
 import static org.apache.servicecomb.core.exception.ExceptionCodes.NOT_DEFINED_ANY_SCHEMA;
 
 import java.util.HashMap;
@@ -26,7 +24,6 @@ import java.util.Map;
 import java.util.concurrent.CompletableFuture;
 
 import javax.annotation.Nonnull;
-import jakarta.ws.rs.core.HttpHeaders;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
@@ -46,7 +43,6 @@ import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.netflix.config.DynamicPropertyFactory;
 
 import io.vertx.core.json.Json;
@@ -81,7 +77,6 @@ public abstract class RestProducerInvocationCreator implements InvocationCreator
     Invocation invocation = createInstance();
     initInvocationContext(invocation);
     addParameterContext(invocation);
-    initProduceProcessor();
     initTransportContext(invocation);
 
     invocation.addLocalContext(RestConst.REST_REQUEST, requestEx);
@@ -158,16 +153,4 @@ public abstract class RestProducerInvocationCreator implements InvocationCreator
   protected OperationLocator locateOperation(ServicePathManager servicePathManager) {
     return servicePathManager.producerLocateOperation(requestEx.getRequestURI(), requestEx.getMethod());
   }
-
-  @VisibleForTesting
-  void initProduceProcessor() {
-    produceProcessor = restOperationMeta.ensureFindProduceProcessor(requestEx);
-    if (produceProcessor == null) {
-      LOGGER.error("Accept {} is not supported, operation={}.", requestEx.getHeader(HttpHeaders.ACCEPT),
-          restOperationMeta.getOperationMeta().getMicroserviceQualifiedName());
-
-      String msg = String.format("Accept %s is not supported", requestEx.getHeader(HttpHeaders.ACCEPT));
-      throw Exceptions.create(NOT_ACCEPTABLE, GENERIC_CLIENT, msg);
-    }
-  }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestVertxProducerInvocationCreator.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestVertxProducerInvocationCreator.java
index fcae4c7ab..a809f0968 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestVertxProducerInvocationCreator.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestVertxProducerInvocationCreator.java
@@ -38,8 +38,7 @@ public class RestVertxProducerInvocationCreator extends RestProducerInvocationCr
 
   @Override
   protected void initTransportContext(Invocation invocation) {
-    VertxHttpTransportContext transportContext = new VertxHttpTransportContext(routingContext, requestEx, responseEx,
-        produceProcessor);
+    VertxHttpTransportContext transportContext = new VertxHttpTransportContext(routingContext, requestEx, responseEx);
     invocation.setTransportContext(transportContext);
     routingContext.put(RestConst.REST_INVOCATION_CONTEXT, invocation);
   }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/VertxHttpTransportContext.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/VertxHttpTransportContext.java
index b88c1a12b..55576022e 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/VertxHttpTransportContext.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/VertxHttpTransportContext.java
@@ -16,7 +16,6 @@
  */
 package org.apache.servicecomb.common.rest;
 
-import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
 import org.apache.servicecomb.swagger.invocation.context.VertxTransportContext;
@@ -31,8 +30,8 @@ public class VertxHttpTransportContext extends HttpTransportContext implements V
   private final Context vertxContext;
 
   public VertxHttpTransportContext(RoutingContext routingContext, HttpServletRequestEx requestEx,
-      HttpServletResponseEx responseEx, ProduceProcessor produceProcessor) {
-    super(requestEx, responseEx, produceProcessor);
+      HttpServletResponseEx responseEx) {
+    super(requestEx, responseEx);
 
     this.routingContext = routingContext;
     this.vertxContext = Vertx.currentContext();
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 736b8a060..b231f854c 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
@@ -194,6 +194,10 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator<RequestB
 
       // For application/json and text/plain
       try {
+        if (MediaType.TEXT_PLAIN.equals(contentType) &&
+            targetType != null && String.class.equals(targetType.getRawClass())) {
+          return IOUtils.toString(inputStream, StandardCharsets.UTF_8);
+        }
         ObjectReader reader = serialViewClass != null
             ? RestObjectMapperFactory.getRestObjectMapper().readerWithView(serialViewClass)
             : RestObjectMapperFactory.getRestObjectMapper().reader();
@@ -257,7 +261,11 @@ public class BodyProcessorCreator implements ParamValueProcessorCreator<RequestB
 
       // For application/json and text/plain
       try (BufferOutputStream output = new BufferOutputStream()) {
-        RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output, arg);
+        if (MediaType.TEXT_PLAIN.equals(contentType) && (arg instanceof String)) {
+          output.write(((String) arg).getBytes(StandardCharsets.UTF_8));
+        } else {
+          RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output, arg);
+        }
         return output.getBuffer();
       }
     }
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 c883fa4c1..81302d576 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
@@ -21,13 +21,17 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import jakarta.ws.rs.core.MediaType;
-
+import org.apache.http.entity.ContentType;
+import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.foundation.common.RegisterManager;
 import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
+import org.apache.servicecomb.swagger.generator.SwaggerConst;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.util.CollectionUtils;
+
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import io.swagger.v3.oas.models.responses.ApiResponses;
+import jakarta.ws.rs.core.MediaType;
 
 public final class ProduceProcessorManager extends RegisterManager<String, Map<String, ProduceProcessor>> {
   private static final Logger LOGGER = LoggerFactory.getLogger(ProduceProcessorManager.class);
@@ -37,14 +41,10 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S
 
   private static final String NAME = "produce processor mgr";
 
-  public static final String DEFAULT_TYPE = MediaType.APPLICATION_JSON;
-
   public static final String DEFAULT_SERIAL_CLASS = "servicecomb_default_class";
 
   public static final ProduceProcessorManager INSTANCE = new ProduceProcessorManager();
 
-  private final Map<String, ProduceProcessor> nonSerialViewMap = new HashMap<>();
-
   private final Map<String, ProduceProcessor> jsonProcessorMap;
 
   private final Map<String, ProduceProcessor> plainProcessorMap;
@@ -54,7 +54,6 @@ 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);
@@ -78,32 +77,6 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S
     return produceViewMap.get(DEFAULT_SERIAL_CLASS);
   }
 
-  // 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);
@@ -112,14 +85,6 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S
         viewKey -> cloneNewProduceProcessor(serialViewClass, jsonProcessorMap));
   }
 
-  public ProduceProcessor findDefaultProcessorByViewClass(Class<?> serialViewClass) {
-    if (serialViewClass == null) {
-      return defaultProcessorMap.get(DEFAULT_SERIAL_CLASS);
-    }
-    return defaultProcessorMap.computeIfAbsent(serialViewClass.getName(),
-        viewKey -> cloneNewProduceProcessor(serialViewClass, defaultProcessorMap));
-  }
-
   public ProduceProcessor findPlainProcessorByViewClass(Class<?> serialViewClass) {
     if (serialViewClass == null) {
       return plainProcessorMap.get(DEFAULT_SERIAL_CLASS);
@@ -139,4 +104,45 @@ public final class ProduceProcessorManager extends RegisterManager<String, Map<S
   public ProduceProcessor findDefaultPlainProcessor() {
     return plainProcessorMap.get(DEFAULT_SERIAL_CLASS);
   }
+
+  public ProduceProcessor createProduceProcessor(OperationMeta operationMeta,
+      int statusCode, String accept, Class<?> serialViewClass) {
+    ApiResponses responses = operationMeta.getSwaggerOperation().getResponses();
+    ApiResponse response = responses.get(String.valueOf(statusCode));
+    if (response == null || response.getContent() == null ||
+        response.getContent().size() == 0) {
+      return findDefaultProcessor();
+    }
+    String actualAccept = accept;
+    if (actualAccept == null) {
+      if (response.getContent().get(MediaType.APPLICATION_JSON) != null) {
+        actualAccept = MediaType.APPLICATION_JSON;
+      } else {
+        actualAccept = response.getContent().keySet().iterator().next();
+      }
+    }
+    ContentType contentType = ContentType.parse(actualAccept);
+    actualAccept = contentType.getMimeType();
+    if (MediaType.WILDCARD.equals(contentType.getMimeType()) ||
+        MediaType.MEDIA_TYPE_WILDCARD.equals(contentType.getMimeType())) {
+      if (response.getContent().get(MediaType.APPLICATION_JSON) != null) {
+        actualAccept = MediaType.APPLICATION_JSON;
+      } else {
+        actualAccept = response.getContent().keySet().iterator().next();
+      }
+    }
+    if (response.getContent().get(actualAccept) == null) {
+      LOGGER.warn("Operation do not support accept type {}/{}", accept, actualAccept);
+      return findDefaultProcessor();
+    }
+    if (SwaggerConst.PROTOBUF_TYPE.equals(actualAccept)) {
+      return new ProduceProtoBufferProcessor(operationMeta,
+          operationMeta.getSchemaMeta().getSwagger(), response.getContent().get(accept).getSchema());
+    }
+    if (MediaType.TEXT_PLAIN.equals(actualAccept)) {
+      return findPlainProcessorByViewClass(serialViewClass);
+    }
+    // json
+    return findJsonProcessorByViewClass(serialViewClass);
+  }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProtoBufferProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProtoBufferProcessor.java
new file mode 100644
index 000000000..f1c8bc105
--- /dev/null
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceProtoBufferProcessor.java
@@ -0,0 +1,107 @@
+/*
+ * 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.common.rest.codec.produce;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;
+import org.apache.servicecomb.core.definition.MicroserviceMeta;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
+import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+import org.apache.servicecomb.foundation.protobuf.RootSerializer;
+import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
+import org.apache.servicecomb.swagger.generator.SwaggerConst;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.media.Schema;
+
+public class ProduceProtoBufferProcessor implements ProduceProcessor {
+  public static final String RESPONSE_MESSAGE_NAME = "response";
+
+  public static final String EXT_ID = "protobuf";
+
+  private static final Object LOCK = new Object();
+
+  private final OperationMeta operationMeta;
+
+  private final OpenAPI openAPI;
+
+  private final Schema<?> schema;
+
+  private final ScopedProtobufSchemaManager scopedProtobufSchemaManager;
+
+  public ProduceProtoBufferProcessor(OperationMeta operationMeta, OpenAPI openAPI, Schema<?> schema) {
+    this.operationMeta = operationMeta;
+    this.openAPI = openAPI;
+    this.schema = schema;
+    this.scopedProtobufSchemaManager = getOrCreateScopedProtobufSchemaManager(operationMeta.getMicroserviceMeta());
+  }
+
+  private ScopedProtobufSchemaManager getOrCreateScopedProtobufSchemaManager(MicroserviceMeta microserviceMeta) {
+    ScopedProtobufSchemaManager scopedProtobufSchemaManager = microserviceMeta.getExtData(EXT_ID);
+    if (scopedProtobufSchemaManager == null) {
+      synchronized (LOCK) {
+        scopedProtobufSchemaManager = microserviceMeta.getExtData(EXT_ID);
+        if (scopedProtobufSchemaManager == null) {
+          scopedProtobufSchemaManager = new ScopedProtobufSchemaManager();
+          microserviceMeta.putExtData(EXT_ID, scopedProtobufSchemaManager);
+        }
+      }
+    }
+    return scopedProtobufSchemaManager;
+  }
+
+  @Override
+  public String getName() {
+    return SwaggerConst.PROTOBUF_TYPE;
+  }
+
+  @Override
+  public int getOrder() {
+    return 0;
+  }
+
+  @Override
+  public void doEncodeResponse(OutputStream output, Object result) throws Exception {
+    ProtoMapper protoMapper = scopedProtobufSchemaManager
+        .getOrCreateProtoMapper(openAPI, operationMeta.getSchemaId(),
+            RESPONSE_MESSAGE_NAME, schema);
+    RootSerializer serializer = protoMapper.getSerializerSchemaManager()
+        .createRootSerializer(protoMapper.getProto().getMessage(RESPONSE_MESSAGE_NAME),
+            Object.class);
+    Map<String, Object> bodyArg = new HashMap<>(1);
+    bodyArg.put("value", result);
+    output.write(serializer.serialize(bodyArg));
+  }
+
+  @Override
+  public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {
+    ProtoMapper protoMapper = scopedProtobufSchemaManager
+        .getOrCreateProtoMapper(openAPI, operationMeta.getSchemaId(),
+            RESPONSE_MESSAGE_NAME, schema);
+    RootDeserializer<PropertyWrapper<Object>> deserializer = protoMapper.getDeserializerSchemaManager()
+        .createRootDeserializer(protoMapper.getProto().getMessage(RESPONSE_MESSAGE_NAME), type);
+    PropertyWrapper<Object> result = deserializer.deserialize(input.readAllBytes());
+    return result.getValue();
+  }
+}
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java
index d5739be48..21d73688d 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceTextPlainProcessor.java
@@ -21,13 +21,13 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 
-import jakarta.ws.rs.core.MediaType;
-
 import org.apache.commons.io.IOUtils;
 
 import com.fasterxml.jackson.databind.JavaType;
 
-public class ProduceTextPlainProcessor implements ProduceProcessor {
+import jakarta.ws.rs.core.MediaType;
+
+public class ProduceTextPlainProcessor extends ProduceJsonProcessor {
   @Override
   public String getName() {
     return MediaType.TEXT_PLAIN;
@@ -35,17 +35,18 @@ public class ProduceTextPlainProcessor implements ProduceProcessor {
 
   @Override
   public void doEncodeResponse(OutputStream output, Object result) throws Exception {
-    output.write(String.valueOf(result).getBytes(StandardCharsets.UTF_8));
+    if (result instanceof String) {
+      output.write(((String) result).getBytes(StandardCharsets.UTF_8));
+      return;
+    }
+    super.doEncodeResponse(output, result);
   }
 
   @Override
   public Object doDecodeResponse(InputStream input, JavaType type) throws Exception {
-    // plainText类型,肯定是返回string的,想不出有其他类型的场景
-    return IOUtils.toString(input, StandardCharsets.UTF_8);
-  }
-
-  @Override
-  public int getOrder() {
-    return 0;
+    if (String.class.equals(type.getRawClass())) {
+      return IOUtils.toString(input, StandardCharsets.UTF_8);
+    }
+    return super.doDecodeResponse(input, type);
   }
 }
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 764160100..48bb32a8b 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
@@ -17,32 +17,23 @@
 
 package org.apache.servicecomb.common.rest.definition;
 
-import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
 import org.apache.servicecomb.common.rest.codec.param.FormProcessorCreator.PartProcessor;
-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.path.PathRegExp;
 import org.apache.servicecomb.common.rest.definition.path.URLPathBuilder;
-import org.apache.servicecomb.core.Const;
 import org.apache.servicecomb.core.definition.OperationMeta;
-import org.apache.servicecomb.foundation.common.utils.MimeTypesUtils;
-import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.apache.servicecomb.swagger.SwaggerUtils;
-import org.apache.servicecomb.swagger.engine.SwaggerProducerOperation;
 import org.apache.servicecomb.swagger.generator.SwaggerConst;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.fasterxml.jackson.annotation.JsonView;
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
 
@@ -54,7 +45,6 @@ import io.swagger.v3.oas.models.parameters.Parameter;
 import io.swagger.v3.oas.models.parameters.RequestBody;
 import io.swagger.v3.oas.models.responses.ApiResponse;
 import io.swagger.v3.oas.models.responses.ApiResponses;
-import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.MediaType;
 
 @SuppressWarnings("rawtypes")
@@ -63,8 +53,6 @@ public class RestOperationMeta {
 
   protected OperationMeta operationMeta;
 
-  protected List<String> produces;
-
   protected boolean formData;
 
   // make sure if response is file
@@ -77,12 +65,6 @@ public class RestOperationMeta {
 
   protected List<String> fileKeys = new ArrayList<>();
 
-  // key为数据类型,比如json之类
-  private final Map<String, ProduceProcessor> produceProcessorMap = new LinkedHashMap<>();
-
-  // 不一定等于mgr中的default,因为本operation可能不支持mgr中的default
-  private ProduceProcessor defaultProcessor;
-
   protected String absolutePath;
 
   protected PathRegExp absolutePathRegExp;
@@ -95,13 +77,8 @@ public class RestOperationMeta {
 
     OpenAPI swagger = operationMeta.getSchemaMeta().getSwagger();
     Operation operation = operationMeta.getSwaggerOperation();
-    this.produces =
-        (operation.getResponses().get(SwaggerConst.SUCCESS_KEY) == null ||
-            operation.getResponses().get(SwaggerConst.SUCCESS_KEY).getContent() == null) ?
-            null : operation.getResponses().get(SwaggerConst.SUCCESS_KEY).getContent().keySet().stream().toList();
 
     this.downloadFile = checkDownloadFileFlag();
-    this.createProduceProcessors();
 
     if (operation.getParameters() != null) {
       for (int swaggerParameterIdx = 0; swaggerParameterIdx < operation.getParameters().size(); swaggerParameterIdx++) {
@@ -259,76 +236,10 @@ public class RestOperationMeta {
     return paramMap.get(name);
   }
 
-  public RestParam getParamByIndex(int index) {
-    return paramList.get(index);
-  }
-
   public OperationMeta getOperationMeta() {
     return operationMeta;
   }
 
-  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()) {
-      produceProcessorMap.putAll(
-          ProduceProcessorManager.INSTANCE.getOrCreateAcceptMap(serialViewClass));
-    } else {
-      for (String produce : produces) {
-        if (produce.contains(";")) {
-          produce = produce.substring(0, produce.indexOf(";"));
-        }
-        ProduceProcessor processor = ProduceProcessorManager.INSTANCE.findProcessor(produce, serialViewClass);
-        if (processor == null) {
-          LOGGER.error("produce {} is not supported, operation={}.", produce,
-              operationMeta.getMicroserviceQualifiedName());
-          continue;
-        }
-        this.produceProcessorMap.put(produce, processor);
-      }
-
-      if (produceProcessorMap.isEmpty()) {
-        produceProcessorMap.put(ProduceProcessorManager.DEFAULT_TYPE,
-            ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(serialViewClass));
-      }
-    }
-
-    if (produceProcessorMap.get(ProduceProcessorManager.DEFAULT_TYPE) != null) {
-      defaultProcessor = produceProcessorMap.get(ProduceProcessorManager.DEFAULT_TYPE);
-    } else {
-      defaultProcessor = produceProcessorMap.values().stream().findFirst().get();
-    }
-    produceProcessorMap.putIfAbsent(MediaType.WILDCARD, defaultProcessor);
-  }
-
   public URLPathBuilder getPathBuilder() {
     return this.pathBuilder;
   }
@@ -345,37 +256,6 @@ public class RestOperationMeta {
     paramMap.put(param.getParamName(), param);
   }
 
-  public ProduceProcessor findProduceProcessor(String type) {
-    return this.produceProcessorMap.get(type);
-  }
-
-  // 选择与accept匹配的produce processor或者缺省的
-  public ProduceProcessor ensureFindProduceProcessor(HttpServletRequestEx requestEx) {
-    String acceptType = requestEx.getHeader(HttpHeaders.ACCEPT);
-    return ensureFindProduceProcessor(acceptType);
-  }
-
-  public ProduceProcessor ensureFindProduceProcessor(String acceptType) {
-    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.produceProcessorMap.get(MediaType.WILDCARD);
-    }
-    if (StringUtils.isEmpty(acceptType)) {
-      return defaultProcessor;
-    }
-    List<String> mimeTypes = MimeTypesUtils.getSortedAcceptableMimeTypes(acceptType.toLowerCase(Locale.US));
-    for (String mime : mimeTypes) {
-      ProduceProcessor processor = this.produceProcessorMap.get(mime);
-      if (null != processor) {
-        return processor;
-      }
-    }
-
-    return null;
-  }
-
   public String getHttpMethod() {
     return operationMeta.getHttpMethod();
   }
@@ -383,8 +263,4 @@ public class RestOperationMeta {
   public List<String> getFileKeys() {
     return fileKeys;
   }
-
-  public List<String> getProduces() {
-    return produces;
-  }
 }
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java
index 392112ec6..a40c7cb55 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilter.java
@@ -31,6 +31,7 @@ import org.apache.servicecomb.common.rest.HttpTransportContext;
 import org.apache.servicecomb.common.rest.RestConst;
 import org.apache.servicecomb.common.rest.codec.RestCodec;
 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.core.Const;
 import org.apache.servicecomb.core.Invocation;
@@ -51,6 +52,7 @@ import org.slf4j.LoggerFactory;
 import io.netty.buffer.Unpooled;
 import io.vertx.core.MultiMap;
 import jakarta.servlet.http.Part;
+import jakarta.ws.rs.core.HttpHeaders;
 
 public class RestServerCodecFilter implements ProviderFilter {
   private static final Logger LOGGER = LoggerFactory.getLogger(RestServerCodecFilter.class);
@@ -100,7 +102,11 @@ public class RestServerCodecFilter implements ProviderFilter {
     invocation.onEncodeResponseStart(response);
 
     HttpTransportContext transportContext = invocation.getTransportContext();
-    ProduceProcessor produceProcessor = transportContext.getProduceProcessor();
+
+    // TODO: response support JsonView
+    ProduceProcessor produceProcessor = ProduceProcessorManager.INSTANCE
+        .createProduceProcessor(invocation.getOperationMeta(), response.getStatusCode(),
+            invocation.getRequestEx().getHeader(HttpHeaders.ACCEPT), null);
     HttpServletResponseEx responseEx = transportContext.getResponseEx();
     boolean download = isDownloadFileResponseType(invocation, response);
 
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreatorTest.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreatorTest.java
index 730aa22bf..108fb8722 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreatorTest.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/RestProducerInvocationCreatorTest.java
@@ -22,8 +22,6 @@ import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.catchThrowable;
 
-import jakarta.ws.rs.core.HttpHeaders;
-
 import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
 import org.apache.servicecomb.common.rest.locator.OperationLocator;
 import org.apache.servicecomb.common.rest.locator.ServicePathManager;
@@ -52,6 +50,7 @@ import org.mockito.Mockito;
 
 import io.vertx.core.json.Json;
 import io.vertx.ext.web.RoutingContext;
+import jakarta.ws.rs.core.HttpHeaders;
 
 public class RestProducerInvocationCreatorTest {
 
@@ -113,43 +112,21 @@ public class RestProducerInvocationCreatorTest {
 
       assertThat(throwable.getStatusCode()).isEqualTo(NOT_FOUND.getStatusCode());
       assertThat(Json.encode(data)).isIn("{\"code\":\"SCB.00000002\",\"message\":\"Not Found\"}",
-              "{\"message\":\"Not Found\",\"code\":\"SCB.00000002\"}");
-    }
-  }
-
-  @Test
-  public void should_failed_when_accept_is_not_support() {
-    try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {
-      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta)).thenReturn(servicePathManager);
-      Mockito.when(requestEx.getHeader(HttpHeaders.ACCEPT)).thenReturn("test-type");
-      Mockito.when(restOperationMeta.ensureFindProduceProcessor(requestEx)).thenReturn(null);
-      Mockito.when(creator.locateOperation(microserviceMeta)).thenReturn(locator);
-      Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);
-      Mockito.when(restOperationMeta.getOperationMeta()).thenReturn(operationMeta);
-      Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);
-      Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
-      Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
-
-      InvocationException throwable = (InvocationException) catchThrowable(() -> creator.createAsync().join());
-      CommonExceptionData data = (CommonExceptionData) throwable.getErrorData();
-
-      assertThat(throwable.getStatusCode()).isEqualTo(NOT_ACCEPTABLE.getStatusCode());
-      assertThat(Json.encode(data)).isIn("{\"code\":\"SCB.00000000\",\"message\":\"Accept test-type is not supported\"}",
-              "{\"message\":\"Accept test-type is not supported\",\"code\":\"SCB.00000000\"}");
+          "{\"message\":\"Not Found\",\"code\":\"SCB.00000002\"}");
     }
   }
 
   @Test
   public void should_save_requestEx_in_invocation_context() {
     try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {
-      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta)).thenReturn(servicePathManager);
+      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta))
+          .thenReturn(servicePathManager);
       Mockito.when(creator.locateOperation(microserviceMeta)).thenReturn(locator);
       Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);
       Mockito.when(restOperationMeta.getOperationMeta()).thenReturn(operationMeta);
       Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);
       Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
       Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
-      Mockito.doNothing().when(creator).initProduceProcessor();
 
       Invocation invocation = creator.createAsync().join();
 
@@ -161,14 +138,14 @@ public class RestProducerInvocationCreatorTest {
   @Test
   public void should_save_path_var_map_in_requestEx() {
     try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {
-      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta)).thenReturn(servicePathManager);
+      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta))
+          .thenReturn(servicePathManager);
       Mockito.when(creator.locateOperation(microserviceMeta)).thenReturn(locator);
       Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);
       Mockito.when(restOperationMeta.getOperationMeta()).thenReturn(operationMeta);
       Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);
       Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
       Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
-      Mockito.doNothing().when(creator).initProduceProcessor();
 
       creator.createAsync().join();
 
@@ -179,14 +156,14 @@ public class RestProducerInvocationCreatorTest {
   @Test
   public void should_merge_invocation_context_from_request() {
     try (MockedStatic<ServicePathManager> mockedStatic = Mockito.mockStatic(ServicePathManager.class)) {
-      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta)).thenReturn(servicePathManager);
+      mockedStatic.when(() -> ServicePathManager.getServicePathManager(microserviceMeta))
+          .thenReturn(servicePathManager);
       Mockito.when(creator.locateOperation(microserviceMeta)).thenReturn(locator);
       Mockito.when(locator.getOperation()).thenReturn(restOperationMeta);
       Mockito.when(restOperationMeta.getOperationMeta()).thenReturn(operationMeta);
       Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);
       Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
       Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
-      Mockito.doNothing().when(creator).initProduceProcessor();
       Mockito.when(requestEx.getHeader(Const.CSE_CONTEXT)).thenReturn("{\"k\":\"v\"}");
 
       Invocation invocation = creator.createAsync().join();
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java
index ebbe2975a..5e7270a6e 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/codec/TestRestCodec.java
@@ -27,7 +27,6 @@ import org.apache.servicecomb.common.rest.codec.param.RestClientRequestImpl;
 import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
 import org.apache.servicecomb.common.rest.definition.RestParam;
 import org.apache.servicecomb.core.definition.OperationMeta;
-import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
@@ -160,7 +159,7 @@ public class TestRestCodec {
       success = true;
     } catch (InvocationException e) {
       Assertions.assertEquals(e.getStatusCode(), Status.BAD_REQUEST.getStatusCode());
-      Assertions.assertTrue(((CommonExceptionData) e.getErrorData()).getMessage()
+      Assertions.assertTrue(((String) e.getErrorData())
           .contains("Parameter is not valid for operation"));
     }
     Assertions.assertFalse(success);
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 d7413d938..d717072a2 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
@@ -52,7 +52,7 @@ public class TestProduceTextPlainProcessor {
     Object result = pp.decodeResponse(Buffer.buffer(), resultType);
     Assertions.assertNull(result);
 
-    ByteArrayInputStream is = new ByteArrayInputStream(new byte[] {});
+    ByteArrayInputStream is = new ByteArrayInputStream("\"\"".getBytes(StandardCharsets.UTF_8));
     result = pp.decodeResponse(is, resultType);
     Assertions.assertEquals(result, "");
   }
@@ -91,6 +91,6 @@ public class TestProduceTextPlainProcessor {
     Assertions.assertEquals(DEFAULT_SERIAL_CLASS, pp.getSerializationView());
 
     pp.setSerializationView(Object.class);
-    Assertions.assertEquals(DEFAULT_SERIAL_CLASS, pp.getSerializationView());
+    Assertions.assertEquals("java.lang.Object", pp.getSerializationView());
   }
 }
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 27d70d4e7..911bf2c6f 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
@@ -25,8 +25,6 @@ import java.util.Arrays;
 import java.util.List;
 
 import org.apache.servicecomb.common.rest.RestEngineSchemaListener;
-import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
-import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;
 import org.apache.servicecomb.config.ConfigUtil;
 import org.apache.servicecomb.core.BootListener;
 import org.apache.servicecomb.core.SCBEngine;
@@ -36,7 +34,6 @@ import org.apache.servicecomb.core.definition.SchemaMeta;
 import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
 import org.hamcrest.MatcherAssert;
 import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
@@ -191,198 +188,6 @@ public class TestRestOperationMeta {
     Mockito.when(schemaMeta.getSwagger()).thenReturn(swagger);
   }
 
-  @Test
-  public void testCreateProduceProcessorsNull() {
-    findOperation("emptyProduces");
-    operationMeta.produces = null;
-    operationMeta.createProduceProcessors();
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor((String) null));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor("*/*"));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    for (String produce : ProduceProcessorManager.INSTANCE.keys()) {
-      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findProcessor(produce, null);
-      Assertions.assertSame(expected, operationMeta.findProduceProcessor(produce));
-    }
-  }
-
-  @Test
-  public void testCreateProduceProcessorsNullWithView() {
-    findOperation("emptyProducesWithView");
-    operationMeta.produces = null;
-    operationMeta.createProduceProcessors();
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor((String) null));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor("*/*"));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    for (String produce : ProduceProcessorManager.INSTANCE.keys()) {
-      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findProcessor(produce, Object.class);
-      Assertions.assertSame(expected, operationMeta.findProduceProcessor(produce));
-    }
-  }
-
-  @Test
-  public void testCreateProduceProcessorsEmpty() {
-    findOperation("emptyProduces");
-    operationMeta.produces = Arrays.asList();
-    operationMeta.createProduceProcessors();
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor((String) null));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor("*/*"));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    for (String produce : ProduceProcessorManager.INSTANCE.keys()) {
-      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findProcessor(produce, null);
-      Assertions.assertSame(expected, operationMeta.findProduceProcessor(produce));
-    }
-  }
-
-  @Test
-  public void testCreateProduceProcessorsEmptyWithView() {
-    findOperation("emptyProducesWithView");
-    operationMeta.produces = Arrays.asList();
-    operationMeta.createProduceProcessors();
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor((String) null));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor("*/*"));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    for (String produce : ProduceProcessorManager.INSTANCE.keys()) {
-      ProduceProcessor expected = ProduceProcessorManager.INSTANCE.findProcessor(produce, Object.class);
-      Assertions.assertSame(expected, operationMeta.findProduceProcessor(produce));
-    }
-  }
-
-  @Test
-  public void testCreateProduceProcessorsNormal() {
-    findOperation("json");
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor((String) null));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor("*/*"));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),
-        operationMeta.findProduceProcessor(MediaType.APPLICATION_JSON));
-    Assertions.assertNull(operationMeta.findProduceProcessor(MediaType.TEXT_PLAIN));
-  }
-
-  @Test
-  public void testCreateProduceProcessorsNormalWithView() {
-    findOperation("jsonWithView");
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor((String) null));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor("*/*"));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
-        operationMeta.findProduceProcessor(MediaType.APPLICATION_JSON));
-    Assertions.assertNull(operationMeta.findProduceProcessor(MediaType.TEXT_PLAIN));
-  }
-
-  @Test
-  public void testCreateProduceProcessorsNotSupported() {
-    findOperation("notSupport");
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor((String) null));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor("*/*"));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessor(),
-        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),
-        operationMeta.findProduceProcessor(MediaType.APPLICATION_JSON));
-    Assertions.assertNotNull(operationMeta.findProduceProcessor(MediaType.TEXT_PLAIN));
-  }
-
-  @Test
-  public void testCreateProduceProcessorsNotSupportedWithView() {
-    findOperation("notSupportWithView");
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor((String) null));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor("*/*"));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(ProduceProcessorManager.DEFAULT_TYPE));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultProcessorByViewClass(Object.class),
-        operationMeta.findProduceProcessor(MediaType.APPLICATION_JSON));
-    Assertions.assertNotNull(operationMeta.findProduceProcessor(MediaType.TEXT_PLAIN));
-  }
-
-  @Test
-  public void testCreateProduceProcessorsTextAndWildcard() {
-    findOperation("textPlain");
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(),
-        operationMeta.ensureFindProduceProcessor(MediaType.WILDCARD));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(),
-        operationMeta.ensureFindProduceProcessor(MediaType.TEXT_PLAIN));
-    Assertions.assertNull(operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(),
-        operationMeta.ensureFindProduceProcessor(
-            MediaType.APPLICATION_JSON + "," + MediaType.APPLICATION_XML + "," + MediaType.WILDCARD));
-  }
-
-  @Test
-  public void testCreateProduceProcessorsTextAndWildcardWithView() {
-    findOperation("textPlainWithView");
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findPlainProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(MediaType.WILDCARD));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findPlainProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(MediaType.TEXT_PLAIN));
-    Assertions.assertNull(operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findPlainProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(
-            MediaType.APPLICATION_JSON + "," + MediaType.APPLICATION_XML + "," + MediaType.WILDCARD));
-  }
-
-  @Test
-  public void testCreateProduceProcessorsWithSemicolon() {
-    findOperation("textCharJsonChar");
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultPlainProcessor(),
-        operationMeta.ensureFindProduceProcessor(MediaType.TEXT_PLAIN));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findDefaultJsonProcessor(),
-        operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
-  }
-
-  @Test
-  public void testCreateProduceProcessorsWithSemicolonWithView() {
-    findOperation("textCharJsonCharWithView");
-
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findPlainProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(MediaType.TEXT_PLAIN));
-    Assertions.assertSame(ProduceProcessorManager.INSTANCE.findJsonProcessorByViewClass(Object.class),
-        operationMeta.ensureFindProduceProcessor(MediaType.APPLICATION_JSON));
-  }
-
-  @Test
-  public void testEnsureFindProduceProcessorAcceptNotFound() {
-    findOperation("textCharJsonChar");
-    Assertions.assertNull(operationMeta.ensureFindProduceProcessor("notSupport"));
-  }
-
-  @Test
-  public void testEnsureFindProduceProcessorAcceptNotFoundWithView() {
-    findOperation("textCharJsonCharWithView");
-    Assertions.assertNull(operationMeta.ensureFindProduceProcessor("notSupport"));
-  }
-
   @Test
   public void generatesAbsolutePathWithRootBasePath() {
     findOperation("textCharJsonChar");
diff --git a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilterTest.java b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilterTest.java
index 0a88c3c2b..ab982a409 100644
--- a/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilterTest.java
+++ b/common/common-rest/src/test/java/org/apache/servicecomb/common/rest/filter/inner/RestServerCodecFilterTest.java
@@ -20,14 +20,12 @@ package org.apache.servicecomb.common.rest.filter.inner;
 import static com.google.common.net.HttpHeaders.CONTENT_LENGTH;
 import static com.google.common.net.HttpHeaders.TRANSFER_ENCODING;
 import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR;
-import static org.assertj.core.api.Assertions.assertThat;
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 
 import org.apache.servicecomb.common.rest.HttpTransportContext;
 import org.apache.servicecomb.common.rest.RestConst;
-import org.apache.servicecomb.common.rest.codec.produce.ProduceJsonProcessor;
 import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
 import org.apache.servicecomb.config.ConfigUtil;
 import org.apache.servicecomb.core.Endpoint;
@@ -43,9 +41,11 @@ import org.apache.servicecomb.core.filter.FilterNode;
 import org.apache.servicecomb.core.invocation.InvocationFactory;
 import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
 import org.apache.servicecomb.foundation.test.scaffolding.exception.RuntimeExceptionWithoutStackTrace;
+import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
 import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -54,9 +54,14 @@ import org.mockito.Mockito;
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
 
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.media.Content;
+import io.swagger.v3.oas.models.media.StringSchema;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import io.swagger.v3.oas.models.responses.ApiResponses;
 import io.vertx.core.MultiMap;
-import io.vertx.core.json.Json;
 import jakarta.servlet.http.Part;
+import jakarta.ws.rs.core.MediaType;
 
 public class RestServerCodecFilterTest {
   final RestServerCodecFilter codecFilter = new RestServerCodecFilter();
@@ -109,7 +114,6 @@ public class RestServerCodecFilterTest {
     Mockito.when(operationMeta.getSchemaMeta()).thenReturn(schemaMeta);
     Mockito.when(schemaMeta.getMicroserviceMeta()).thenReturn(microserviceMeta);
     Mockito.when(operationMeta.buildBaseProviderRuntimeType()).thenReturn(invocationRuntimeType);
-    Mockito.when(transportContext.getProduceProcessor()).thenReturn(Mockito.mock(ProduceJsonProcessor.class));
     invocation = Mockito.spy(InvocationFactory.forProvider(endpoint, operationMeta, null));
   }
 
@@ -137,16 +141,25 @@ public class RestServerCodecFilterTest {
     Mockito.when(invocation.findResponseType(INTERNAL_SERVER_ERROR.getStatusCode()))
         .thenReturn(TypeFactory.defaultInstance().constructType(String.class));
 
-    Response response = codecFilter.onFilter(invocation, nextNode).get();
-
-    assertThat(response.getStatus()).isEqualTo(INTERNAL_SERVER_ERROR);
-    assertThat(Json.encode(response.getResult())).
-        isIn("{\"code\":\"SCB.50000000\",\"message\":\"Unexpected "
-            + "exception when processing null. mock encode request failed\"}");
+    Assertions.assertThrows(ExecutionException.class,
+        () -> codecFilter.onFilter(invocation, nextNode).get());
   }
 
   private void success_invocation() throws InterruptedException, ExecutionException {
     Mockito.when(invocation.getTransportContext()).thenReturn(transportContext);
+    HttpServletRequestEx requestExt = Mockito.mock(HttpServletRequestEx.class);
+    Mockito.when(invocation.getRequestEx()).thenReturn(requestExt);
+    Mockito.when(invocation.getOperationMeta()).thenReturn(operationMeta);
+    Operation swaggerOperation = Mockito.mock(Operation.class);
+    Mockito.when(operationMeta.getSwaggerOperation()).thenReturn(swaggerOperation);
+    ApiResponses apiResponses = Mockito.mock(ApiResponses.class);
+    Mockito.when(swaggerOperation.getResponses()).thenReturn(apiResponses);
+    ApiResponse apiResponse = Mockito.mock(ApiResponse.class);
+    Mockito.when(apiResponses.get("200")).thenReturn(apiResponse);
+    Content content = new Content();
+    content.addMediaType(MediaType.APPLICATION_JSON, new io.swagger.v3.oas.models.media.MediaType());
+    content.get(MediaType.APPLICATION_JSON).setSchema(new StringSchema());
+    Mockito.when(apiResponse.getContent()).thenReturn(content);
     Mockito.when(operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION)).thenReturn(restOperationMeta);
     Mockito.when(invocation.findResponseType(INTERNAL_SERVER_ERROR.getStatusCode()))
         .thenReturn(TypeFactory.defaultInstance().constructType(String.class));
diff --git a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientDecoder.java b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientDecoder.java
index db277b68e..cd3c4e89e 100644
--- a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientDecoder.java
+++ b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/RestClientDecoder.java
@@ -62,14 +62,15 @@ public class RestClientDecoder {
   }
 
   private ProduceProcessor safeFindProduceProcessor(Invocation invocation, Response response) {
-    RestClientTransportContext transportContext = invocation.getTransportContext();
-
     String contentType = extractContentType(response);
-    ProduceProcessor produceProcessor = transportContext.getRestOperationMeta().findProduceProcessor(contentType);
+    ProduceProcessor produceProcessor =
+        ProduceProcessorManager.INSTANCE.createProduceProcessor(invocation.getOperationMeta(), response.getStatusCode(),
+            contentType, null);
     if (produceProcessor != null) {
       return produceProcessor;
     }
 
+    RestClientTransportContext transportContext = invocation.getTransportContext();
     HttpClientRequest httpClientRequest = transportContext.getHttpClientRequest();
     LOGGER.warn(
         "operation={}, method={}, endpoint={}, uri={}, statusCode={}, reasonPhrase={}, response content-type={} is not supported in operation.",
diff --git a/transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/RestServletProducerInvocationCreator.java b/transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/RestServletProducerInvocationCreator.java
index 97cf131c5..a12ee8cc0 100644
--- a/transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/RestServletProducerInvocationCreator.java
+++ b/transports/transport-rest/transport-rest-servlet/src/main/java/org/apache/servicecomb/transport/rest/servlet/RestServletProducerInvocationCreator.java
@@ -34,7 +34,7 @@ public class RestServletProducerInvocationCreator extends RestProducerInvocation
 
   @Override
   protected void initTransportContext(Invocation invocation) {
-    HttpTransportContext transportContext = new HttpTransportContext(requestEx, responseEx, produceProcessor);
+    HttpTransportContext transportContext = new HttpTransportContext(requestEx, responseEx);
     invocation.setTransportContext(transportContext);
   }
 }