[
https://issues.apache.org/jira/browse/SCB-847?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16583279#comment-16583279
]
ASF GitHub Bot commented on SCB-847:
------------------------------------
liubao68 closed pull request #874: [SCB-847]Provide a way to decode user's
custom error data
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/874
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
index 188d9dec3..c6d5d65c4 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/RestObjectMapperFactory.java
@@ -23,10 +23,20 @@
public class RestObjectMapperFactory {
private static AbstractRestObjectMapper defaultMapper = new
RestObjectMapper();
+ private static AbstractRestObjectMapper consumerWriterMapper = new
RestObjectMapper();
+
+ public static AbstractRestObjectMapper getConsumerWriterMapper() {
+ return consumerWriterMapper;
+ }
+
public static AbstractRestObjectMapper getRestObjectMapper() {
return defaultMapper;
}
+ public static void setConsumerWriterMapper(AbstractRestObjectMapper
customMapper) {
+ consumerWriterMapper = customMapper;
+ }
+
public static void setDefaultRestObjectMapper(AbstractRestObjectMapper
customMapper) {
defaultMapper = customMapper;
}
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
index 61f0ea959..ff5f5872d 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/BodyProcessorCreator.java
@@ -68,7 +68,7 @@ public Object getValue(HttpServletRequest request) throws
Exception {
contentType = contentType == null ? "" :
contentType.toLowerCase(Locale.US);
if (contentType.startsWith(MediaType.MULTIPART_FORM_DATA)
|| contentType.startsWith(MediaType.APPLICATION_FORM_URLENCODED)) {
- return
RestObjectMapperFactory.getRestObjectMapper().convertValue(request.getParameterMap(),
targetType);
+ return convertValue(request.getParameterMap(), targetType);
}
// for standard HttpServletRequest, getInputStream will never return null
@@ -85,7 +85,8 @@ public Object getValue(HttpServletRequest request) throws
Exception {
}
try {
- return
RestObjectMapperFactory.getRestObjectMapper().readValue(inputStream,
targetType);
+ return RestObjectMapperFactory.getRestObjectMapper()
+ .readValue(inputStream, targetType);
} catch (MismatchedInputException e) {
// there is no way to detect InputStream is empty, so have to catch
the exception
if (!isRequired) {
@@ -100,7 +101,7 @@ public Object getValue(HttpServletRequest request) throws
Exception {
public void setValue(RestClientRequest clientRequest, Object arg) throws
Exception {
try (BufferOutputStream output = new BufferOutputStream()) {
clientRequest.putHeader(HttpHeaders.CONTENT_TYPE,
MediaType.APPLICATION_JSON);
- RestObjectMapperFactory.getRestObjectMapper().writeValue(output, arg);
+ RestObjectMapperFactory.getConsumerWriterMapper().writeValue(output,
arg);
if (arg != null) {
clientRequest.write(output.getBuffer());
}
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
index 7f8a7761a..659637e50 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/CookieProcessorCreator.java
@@ -64,7 +64,8 @@ public Object getValue(HttpServletRequest request) throws
Exception {
@Override
public void setValue(RestClientRequest clientRequest, Object arg) throws
Exception {
- clientRequest.addCookie(paramPath,
RestObjectMapperFactory.getRestObjectMapper().convertToString(arg));
+ clientRequest.addCookie(paramPath,
+
RestObjectMapperFactory.getConsumerWriterMapper().convertToString(arg));
}
@Override
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
index 43b458282..810e01814 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/HeaderProcessorCreator.java
@@ -74,7 +74,8 @@ public void setValue(RestClientRequest clientRequest, Object
arg) throws Excepti
LOGGER.debug("Header arg is null, will not be set into clientRequest.
paramPath = [{}]", paramPath);
return;
}
- clientRequest.putHeader(paramPath,
RestObjectMapperFactory.getRestObjectMapper().convertToString(arg));
+ clientRequest.putHeader(paramPath,
+
RestObjectMapperFactory.getConsumerWriterMapper().convertToString(arg));
}
@Override
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
index e38f7dc25..e2d8b67b3 100644
---
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
+++
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/param/ParamValueProcessor.java
@@ -30,7 +30,8 @@
void setValue(RestClientRequest clientRequest, Object arg) throws Exception;
default Object convertValue(Object value, JavaType targetType) {
- return RestObjectMapperFactory.getRestObjectMapper().convertValue(value,
targetType);
+ return RestObjectMapperFactory.getRestObjectMapper()
+ .convertValue(value, targetType);
}
String getParameterPath();
diff --git
a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/codec/produce/ProduceJsonProcessor.java
index 817aef0e6..d4006c74a 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
@@ -40,7 +40,8 @@ public void doEncodeResponse(OutputStream output, Object
result) throws Exceptio
@Override
public Object doDecodeResponse(InputStream input, JavaType type) throws
Exception {
- return RestObjectMapperFactory.getRestObjectMapper().readValue(input,
type);
+ return RestObjectMapperFactory.getRestObjectMapper()
+ .readValue(input, type);
}
@Override
diff --git
a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/CustomExceptionToResponseConverter.java
b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/CustomExceptionToResponseConverter.java
new file mode 100644
index 000000000..fd2ccd90f
--- /dev/null
+++
b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/CustomExceptionToResponseConverter.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.edge.business.error;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.servicecomb.swagger.invocation.Response;
+import org.apache.servicecomb.swagger.invocation.SwaggerInvocation;
+import
org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+
+public class CustomExceptionToResponseConverter implements
ExceptionToResponseConverter<IllegalStateException> {
+ @Override
+ public Class<IllegalStateException> getExceptionClass() {
+ return IllegalStateException.class;
+ }
+
+ @Override
+ public int getOrder() {
+ return 100;
+ }
+
+ @Override
+ public Response convert(SwaggerInvocation swaggerInvocation,
IllegalStateException e) {
+ IllegalStateErrorData data = new IllegalStateErrorData();
+ data.setId(500);
+ data.setMessage(e.getMessage());
+ data.setState(e.getMessage());
+ InvocationException state = new
InvocationException(Status.INTERNAL_SERVER_ERROR, data);
+ return Response.failResp(state);
+ }
+}
diff --git
a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorData.java
b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorData.java
new file mode 100644
index 000000000..078c19414
--- /dev/null
+++
b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorData.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.edge.business.error;
+
+public class ErrorData {
+ private int id;
+
+ private String message;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git
a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorService.java
b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorService.java
new file mode 100644
index 000000000..8bdba9c2b
--- /dev/null
+++
b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/ErrorService.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.edge.business.error;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+@RestSchema(schemaId = "error-v2")
+@RequestMapping(path = "/business/v2/error")
+public class ErrorService {
+ @RequestMapping(path = "/add", method = RequestMethod.GET)
+ public int add(int x, int y) {
+ if (x == 99) {
+ throw new NullPointerException("un expected NPE test.");
+ }
+ if (x == 88) {
+ ErrorData data = new ErrorData();
+ data.setId(12);
+ data.setMessage("not allowed id.");
+ throw new InvocationException(Status.FORBIDDEN, data);
+ }
+ if (x == 77) {
+ throw new IllegalStateException("77");
+ }
+ return x + y;
+ }
+}
diff --git
a/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/IllegalStateErrorData.java
b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/IllegalStateErrorData.java
new file mode 100644
index 000000000..d771c7a51
--- /dev/null
+++
b/demo/demo-edge/business-2.0.0/src/main/java/org/apache/servicecomb/demo/edge/business/error/IllegalStateErrorData.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.edge.business.error;
+
+public class IllegalStateErrorData {
+ private int id;
+
+ private String message;
+
+ private String state;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+}
diff --git
a/demo/demo-edge/business-2.0.0/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter
b/demo/demo-edge/business-2.0.0/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter
new file mode 100644
index 000000000..9a433318c
--- /dev/null
+++
b/demo/demo-edge/business-2.0.0/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.exception.ExceptionToResponseConverter
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.demo.edge.business.error.CustomExceptionToResponseConverter
\ No newline at end of file
diff --git
a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
index 7796de943..95ea17a32 100644
---
a/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
+++
b/demo/demo-edge/consumer/src/main/java/org/apache/servicecomb/demo/edge/consumer/Consumer.java
@@ -46,6 +46,8 @@
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
+import org.springframework.web.client.HttpClientErrorException;
+import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
public class Consumer {
@@ -88,6 +90,7 @@ public void run(String prefix) {
testDependType();
testDownload();
testDownloadBigFile();
+ testErrorCode();
invoke("/v1/add", 2, 1, addV1Result);
invoke("/v1/add", 3, 1, addV1Result);
@@ -158,6 +161,32 @@ protected void testRecursiveSelf() {
Assert.isNull(response.getField().getField(), "must be null");
}
+ @SuppressWarnings({"unckecked", "rawtypes"})
+ protected void testErrorCode() {
+ String url = edgePrefix + "/v2/error/add";
+
+ int response = template.getForObject(url + "?x=2&y=3", Integer.class);
+ Assert.isTrue(response == 5, "not get 5.");
+
+ Map raw = template.getForObject(url + "?x=99&y=3", Map.class);
+ Assert.isTrue(raw.get("message").equals("Cse Internal Server Error"),
"x99");
+
+ try {
+ template.getForObject(url + "?x=88&y=3", Map.class);
+ Assert.isTrue(false, "x88");
+ } catch (HttpClientErrorException e) {
+ Assert.isTrue(e.getRawStatusCode() == 403, "x88");
+
Assert.isTrue(e.getResponseBodyAsString().equals("{\"id\":12,\"message\":\"not
allowed id.\"}"), "x88");
+ }
+ try {
+ template.getForObject(url + "?x=77&y=3", Map.class);
+ Assert.isTrue(false, "x77");
+ } catch (HttpServerErrorException e) {
+ Assert.isTrue(e.getRawStatusCode() == 500, "x77");
+
Assert.isTrue(e.getResponseBodyAsString().equals("{\"id\":500,\"message\":\"77\",\"state\":\"77\"}"),
"x77");
+ }
+ }
+
protected void testDependType() {
String url = edgePrefix + "/v2/dependType";
diff --git
a/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/CustomResponseMetaMapper.java
b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/CustomResponseMetaMapper.java
new file mode 100644
index 000000000..c3eaa5110
--- /dev/null
+++
b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/CustomResponseMetaMapper.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.edge.service;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.swagger.invocation.response.ResponseMeta;
+import org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper;
+
+import com.fasterxml.jackson.databind.type.SimpleType;
+
+public class CustomResponseMetaMapper implements ResponseMetaMapper {
+ private final static Map<Integer, ResponseMeta> CODES = new HashMap<>(1);
+
+ static {
+ ResponseMeta meta = new ResponseMeta();
+ meta.setJavaType(SimpleType.constructUnsafe(IllegalStateErrorData.class));
+ CODES.put(500, meta);
+ }
+
+ @Override
+ public int getOrder() {
+ return 100;
+ }
+
+ @Override
+ public Map<Integer, ResponseMeta> getMapper() {
+ return CODES;
+ }
+}
diff --git
a/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/IllegalStateErrorData.java
b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/IllegalStateErrorData.java
new file mode 100644
index 000000000..017183f1c
--- /dev/null
+++
b/demo/demo-edge/edge-service/src/main/java/org/apache/servicecomb/demo/edge/service/IllegalStateErrorData.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.edge.service;
+
+public class IllegalStateErrorData {
+ private int id;
+
+ private String message;
+
+ private String state;
+
+ public int getId() {
+ return id;
+ }
+
+ public void setId(int id) {
+ this.id = id;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public void setState(String state) {
+ this.state = state;
+ }
+}
diff --git
a/demo/demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper
b/demo/demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper
new file mode 100644
index 000000000..d8a88a705
--- /dev/null
+++
b/demo/demo-edge/edge-service/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.invocation.response.ResponseMetaMapper
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.servicecomb.demo.edge.service.CustomResponseMetaMapper
\ No newline at end of file
diff --git
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
index f285d5fc0..f28ffbd8b 100644
---
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
+++
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/JaxrsClient.java
@@ -30,10 +30,13 @@
import org.apache.servicecomb.demo.CodeFirstRestTemplate;
import org.apache.servicecomb.demo.DemoConst;
import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
+import
org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;
import org.apache.servicecomb.demo.TestMgr;
import org.apache.servicecomb.demo.compute.Person;
import org.apache.servicecomb.demo.jaxrs.client.beanParam.BeanParamPojoClient;
import
org.apache.servicecomb.demo.jaxrs.client.beanParam.BeanParamRestTemplateClient;
+import
org.apache.servicecomb.demo.jaxrs.client.pojoDefault.DefaultModelServiceClient;
+import
org.apache.servicecomb.demo.jaxrs.client.validation.ValidationServiceClient;
import org.apache.servicecomb.demo.validator.Student;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
@@ -62,6 +65,7 @@ public static void init() throws Exception {
Log4jUtils.init();
BeanUtils.init();
RestObjectMapperFactory.setDefaultRestObjectMapper(new
RestObjectMapperWithStringMapper());
+ RestObjectMapperFactory.setConsumerWriterMapper(new
RestObjectMapperWithStringMapperNotWriteNull());
}
public static void run() throws Exception {
@@ -78,6 +82,8 @@ public static void run() throws Exception {
beanParamPojoClient.testAll();
BeanParamRestTemplateClient beanParamRestTemplateClient = new
BeanParamRestTemplateClient();
beanParamRestTemplateClient.testAll();
+ DefaultModelServiceClient.run();
+ ValidationServiceClient.run();
}
private static void testCompute(RestTemplate template) throws Exception {
@@ -179,6 +185,9 @@ private static void testJaxRSDefaultValues(RestTemplate
template) {
result = template.getForObject(cseUrlPrefix + "/query3?a=30&b=2",
String.class);
TestMgr.check("Hello 302", result);
+ result = template.getForObject(cseUrlPrefix + "/query3?a=30",
String.class);
+ TestMgr.check("Hello 30null", result);
+
//input values
headers = new HttpHeaders();
headers.setContentType(org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED);
@@ -278,6 +287,7 @@ private static void testRawJsonParam(RestTemplate template,
String cseUrlPrefix)
template.postForObject(cseUrlPrefix + "/compute/testrawjson",
jsonPerson, String.class));
}
+ @SuppressWarnings({"unckecked", "rawtypes"})
private static void testValidatorAddFail(RestTemplate template, String
cseUrlPrefix) {
Map<String, String> params = new HashMap<>();
params.put("a", "5");
@@ -292,10 +302,11 @@ private static void testValidatorAddFail(RestTemplate
template, String cseUrlPre
// Message dependends on locale, so just check the short part.
// 'must be greater than or equal to 20', propertyPath=add.arg1,
rootBeanClass=class org.apache.servicecomb.demo.jaxrs.server.Validator,
messageTemplate='{javax.validation.constraints.Min.message}'}]]
// ignored
+ Map data = (Map) e.getErrorData();
TestMgr.check(
- "CommonExceptionData
[message=[ConstraintViolationImpl{interpolatedMessage=",
- e.getErrorData().toString().substring(0,
- "CommonExceptionData
[message=[ConstraintViolationImpl{interpolatedMessage=".length()));
+ "[ConstraintViolationImpl{interpolatedMessage=",
+ data.get("message").toString().substring(0,
+ "[ConstraintViolationImpl{interpolatedMessage=".length()));
}
TestMgr.check(true, isExcep);
@@ -309,6 +320,7 @@ private static void testValidatorAddSuccess(RestTemplate
template, String cseUrl
TestMgr.check(25, result);
}
+ @SuppressWarnings({"unckecked", "rawtypes"})
private static void testValidatorSayHiFail(RestTemplate template, String
cseUrlPrefix) {
boolean isExcep = false;
try {
@@ -318,10 +330,11 @@ private static void testValidatorSayHiFail(RestTemplate
template, String cseUrlP
TestMgr.check(400, e.getStatus().getStatusCode());
TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());
// Message dependends on locale, so just check the short part.
+ Map data = (Map) e.getErrorData();
TestMgr.check(
- "CommonExceptionData
[message=[ConstraintViolationImpl{interpolatedMessage=",
- e.getErrorData().toString().substring(0,
- "CommonExceptionData
[message=[ConstraintViolationImpl{interpolatedMessage=".length()));
+ "[ConstraintViolationImpl{interpolatedMessage=",
+ data.get("message").toString().substring(0,
+ "[ConstraintViolationImpl{interpolatedMessage=".length()));
}
TestMgr.check(true, isExcep);
}
@@ -333,6 +346,7 @@ private static void testValidatorSayHiSuccess(RestTemplate
template, String cseU
TestMgr.check("world sayhi", responseEntity.getBody());
}
+ @SuppressWarnings({"unckecked", "rawtypes"})
private static void testValidatorExchangeFail(RestTemplate template, String
cseUrlPrefix) {
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", MediaType.APPLICATION_JSON);
@@ -351,10 +365,11 @@ private static void
testValidatorExchangeFail(RestTemplate template, String cseU
TestMgr.check(400, e.getStatus().getStatusCode());
TestMgr.check(Status.BAD_REQUEST, e.getReasonPhrase());
// Message dependends on locale, so just check the short part.
+ Map data = (Map) e.getErrorData();
TestMgr.check(
- "CommonExceptionData
[message=[ConstraintViolationImpl{interpolatedMessage=",
- e.getErrorData().toString().substring(0,
- "CommonExceptionData
[message=[ConstraintViolationImpl{interpolatedMessage=".length()));
+ "[ConstraintViolationImpl{interpolatedMessage",
+ data.get("message").toString().substring(0,
+ "[ConstraintViolationImpl{interpolatedMessage".length()));
}
TestMgr.check(true, isExcep);
}
@@ -429,6 +444,9 @@ private static void
testSpringMvcDefaultValuesJavaPrimitive(RestTemplate templat
TestMgr.check("Hello", result);
result = template.postForObject(cseUrlPrefix + "/javaprimitivecomb",
request, String.class);
- TestMgr.check("Hello 00.0", result);
+ TestMgr.check("Hello nullnull", result);
+
+ result = template.postForObject(cseUrlPrefix + "/allprimitivetypes", null,
String.class);
+ TestMgr.check("Hello false,0,0,0,0,0,0.0,0.0,null", result);
}
}
diff --git
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModel.java
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModel.java
new file mode 100644
index 000000000..1c5d64e64
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModel.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.client.pojoDefault;
+
+public class DefaultModel {
+ private int index;
+
+ public int getIndex() {
+ return index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+}
diff --git
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModelServiceClient.java
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModelServiceClient.java
new file mode 100644
index 000000000..f6dedf1ef
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/pojoDefault/DefaultModelServiceClient.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.client.pojoDefault;
+
+import org.apache.servicecomb.core.CseContext;
+import org.apache.servicecomb.demo.TestMgr;
+import
org.apache.servicecomb.demo.jaxrs.server.pojoDefault.DefaultResponseModel;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.springframework.web.client.RestTemplate;
+
+public class DefaultModelServiceClient {
+ private static RestTemplate template = RestTemplateBuilder.create();
+
+ private static String urlPrefix = "cse://jaxrs/DefaultModelService";
+
+ public static void run() {
+ // highway do not support this feature
+
CseContext.getInstance().getConsumerProviderManager().setTransport("jaxrs",
"rest");
+ testDefaultModelService();
+ }
+
+ private static void testDefaultModelService() {
+ DefaultModel model = new DefaultModel();
+ model.setIndex(400);
+ DefaultResponseModel result = template.postForObject(urlPrefix + "/model",
model, DefaultResponseModel.class);
+ TestMgr.check(result.getAge(), 200);
+ TestMgr.check(result.getIndex(), 400);
+ TestMgr.check(result.getName(), "World");
+ TestMgr.check(result.getDesc(), null);
+ }
+}
diff --git
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
new file mode 100644
index 000000000..727a05026
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/client/validation/ValidationServiceClient.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.client.validation;
+
+import java.util.ArrayList;
+
+import org.apache.servicecomb.core.CseContext;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.demo.jaxrs.server.validation.ValidationModel;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.springframework.web.client.RestTemplate;
+
+public class ValidationServiceClient {
+ private static RestTemplate template = RestTemplateBuilder.create();
+
+ private static String urlPrefix = "cse://jaxrs/ValidationService";
+
+ public static void run() {
+ // highway do not support this feature
+
CseContext.getInstance().getConsumerProviderManager().setTransport("jaxrs",
"rest");
+ testValidation();
+ }
+
+ private static void testValidation() {
+ ValidationModel model = new ValidationModel();
+ model.setAge(20);
+ model.setMembers(new ArrayList<>());
+ model.setName("name");
+ ValidationModel result = template.postForObject(urlPrefix + "/validate",
model, ValidationModel.class);
+ TestMgr.check(result.getAge(), 20);
+ TestMgr.check(result.getName(), "name");
+ TestMgr.check(result.getMembers().size(), 0);
+
+ try {
+ model.setAge(null);
+ template.postForObject(urlPrefix + "/validate", model,
ValidationModel.class);
+ TestMgr.check(false, true);
+ } catch (InvocationException e) {
+ TestMgr.check(e.getErrorData().toString().contains("age"), true);
+ }
+
+ try {
+ model.setAge(20);
+ model.setMembers(null);
+ template.postForObject(urlPrefix + "/validate", model,
ValidationModel.class);
+ TestMgr.check(false, true);
+ } catch (InvocationException e) {
+ TestMgr.check(e.getErrorData().toString().contains("member"), true);
+ }
+
+ String strResult = template.getForObject(urlPrefix +
"/validateQuery?name=", String.class);
+ TestMgr.check(strResult, "");
+
+ try {
+ template.getForObject(urlPrefix + "/validateQuery", String.class);
+ TestMgr.check(false, true);
+ } catch (InvocationException e) {
+ TestMgr.check(e.getErrorData().toString().contains("null"), true);
+ }
+ }
+}
diff --git
a/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
new file mode 100644
index 000000000..6c4350a07
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-client/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.server.pojoDefault;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Null;
+
+public class DefaultResponseModel {
+ @Min(20)
+ @Max(2000)
+ @Null
+ private Integer age = 200;
+
+ @Min(2)
+ @Max(30)
+ @Null
+ private String name = "World";
+
+ private int index;
+
+ private String desc = "Hello";
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ public int getIndex() {
+ return index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ @Override
+ public String toString() {
+ return "index=" + index + ";name=" + name + ";age=" + age;
+ }
+}
diff --git
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java
index aa8f461dc..5a2788e64 100644
---
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java
+++
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxRSDefaultValues.java
@@ -118,4 +118,26 @@ public String jaxRsJavaPrimitiveStr(@FormParam("b") int b,
@FormParam("a") Strin
public String jaxRsJavaPrimitiveCombnation(@QueryParam("a") Integer a,
@QueryParam("b") Float b) {
return "Hello " + a + b;
}
+
+ @Path("/allprimitivetypes")
+ @POST
+ public String allprimitivetypes(@QueryParam("pBoolean") boolean pBoolean,
+ @QueryParam("pChar") char pChar,
+ @QueryParam("pByte") byte pByte,
+ @QueryParam("pShort") short pShort,
+ @QueryParam("pInt") int pInt,
+ @QueryParam("pLong") long pLong,
+ @QueryParam("pFloat") float pFloat,
+ @QueryParam("pDouble") double pDouble,
+ @QueryParam("pDoubleWrap") Double pDoubleWrap) {
+ return "Hello " + pBoolean + ","
+ + pChar + ","
+ + pByte + ","
+ + pShort + ","
+ + pInt + ","
+ + pLong + ","
+ + pFloat + ","
+ + pDouble + ","
+ + pDoubleWrap;
+ }
}
diff --git
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
index bf5eba5fd..3b2d952a3 100644
---
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
+++
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/JaxrsServer.java
@@ -19,13 +19,16 @@
import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
+import
org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;
import org.apache.servicecomb.foundation.common.utils.BeanUtils;
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
public class JaxrsServer {
public static void main(String[] args) throws Exception {
+ RestObjectMapperFactory.setDefaultRestObjectMapper(new
RestObjectMapperWithStringMapper());
+ RestObjectMapperFactory.setConsumerWriterMapper(new
RestObjectMapperWithStringMapperNotWriteNull());
+
Log4jUtils.init();
BeanUtils.init();
- RestObjectMapperFactory.setDefaultRestObjectMapper(new
RestObjectMapperWithStringMapper());
}
}
diff --git
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultModelService.java
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultModelService.java
new file mode 100644
index 000000000..7296a0970
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultModelService.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.server.pojoDefault;
+
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+
+@RestSchema(schemaId = "DefaultModelService")
+@Path("DefaultModelService")
+public class DefaultModelService {
+ @Path("/model")
+ @POST
+ public DefaultResponseModel errorCode(DefaultRequestModel request) {
+ DefaultResponseModel model = new DefaultResponseModel();
+ model.setIndex(request.getIndex());
+ model.setAge(request.getAge());
+ model.setName(request.getName());
+ model.setDesc(null);
+ return model;
+ }
+}
diff --git
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultRequestModel.java
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultRequestModel.java
new file mode 100644
index 000000000..0cc535703
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultRequestModel.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.server.pojoDefault;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Null;
+
+public class DefaultRequestModel {
+ @Min(20)
+ @Max(2000)
+ @Null
+ private Integer age = 200;
+
+ @Min(2)
+ @Max(30)
+ @Null
+ private String name = "World";
+
+ private int index;
+
+ private String desc;
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ public int getIndex() {
+ return index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ @Override
+ public String toString() {
+ return "index=" + index + ";name=" + name + ";age=" + age;
+ }
+}
diff --git
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
new file mode 100644
index 000000000..bf4288a28
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/pojoDefault/DefaultResponseModel.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.server.pojoDefault;
+
+import javax.validation.constraints.Max;
+import javax.validation.constraints.Min;
+import javax.validation.constraints.Null;
+
+public class DefaultResponseModel {
+ @Min(20)
+ @Max(2000)
+ @Null
+ private Integer age = 200;
+
+ @Min(2)
+ @Max(30)
+ @Null
+ private String name = "World";
+
+ private int index;
+
+ private String desc;
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+
+ public int getIndex() {
+ return index;
+ }
+
+ public void setIndex(int index) {
+ this.index = index;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ @Override
+ public String toString() {
+ return "index=" + index + ";name=" + name + ";age=" + age;
+ }
+}
diff --git
a/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationService.java
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationService.java
new file mode 100644
index 000000000..732466957
--- /dev/null
+++
b/demo/demo-jaxrs/jaxrs-server/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationService.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.server.validation;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.QueryParam;
+
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+
+@RestSchema(schemaId = "ValidationService")
+@Path("ValidationService")
+public class ValidationService {
+ @Path("/validate")
+ @POST
+ public ValidationModel errorCode(@Valid ValidationModel request) {
+ return request;
+ }
+
+ @Path("/validateQuery")
+ @GET
+ public String queryValidate(@NotNull @QueryParam("name") String name) {
+ return name;
+ }
+}
diff --git
a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapperNotWriteNull.java
b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapperNotWriteNull.java
new file mode 100644
index 000000000..9eacb22bb
--- /dev/null
+++
b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/RestObjectMapperWithStringMapperNotWriteNull.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
+
+/**
+ * Demonstrate how to using String as raw type when using RestTemplate to
invoke a service that use POJO. e.g.
+ * <p/>
+ * Provider: <p/>
+ * <code>
+ * public Response errorCodeWithHeader(MultiRequest request)
+ * </code>
+ * <p/>
+ * Consumer: <p/>
+ * <code>
+ * String stringRequest = "{\"key\":\"testValue\"}";
+ * template.postForEntity(url, stringRequest, MultiResponse200.class);
+ * </code>
+ * <p/>
+ * <b>Caution:</b> json will convert String to object based on String
constructor, using this feature will make default
+ * conversion change. You must write convertValue to check possible types
using.
+ */
+public class RestObjectMapperWithStringMapperNotWriteNull extends
RestObjectMapperWithStringMapper {
+ private static final long serialVersionUID = 4279371572149490560L;
+
+ private static Logger LOGGER =
LoggerFactory.getLogger(RestObjectMapperWithStringMapper.class);
+
+ public RestObjectMapperWithStringMapperNotWriteNull() {
+ super();
+ setSerializationInclusion(Include.NON_NULL);
+ }
+}
diff --git
a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationModel.java
b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationModel.java
new file mode 100644
index 000000000..09e26129b
--- /dev/null
+++
b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/jaxrs/server/validation/ValidationModel.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.demo.jaxrs.server.validation;
+
+import java.util.List;
+
+import javax.validation.constraints.NotNull;
+
+public class ValidationModel {
+ @NotNull
+ private Integer age;
+
+ @NotNull
+ private List<String> members;
+
+ @NotNull
+ private String name;
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public List<String> getMembers() {
+ return members;
+ }
+
+ public void setMembers(List<String> members) {
+ this.members = members;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git
a/demo/demo-schema/src/main/resources/microservices/jaxrs/compute.yaml
b/demo/demo-schema/src/main/resources/microservices/jaxrs/compute.yaml
index fcca77c24..66eb476c5 100644
--- a/demo/demo-schema/src/main/resources/microservices/jaxrs/compute.yaml
+++ b/demo/demo-schema/src/main/resources/microservices/jaxrs/compute.yaml
@@ -197,3 +197,4 @@ definitions:
properties:
name:
type: string
+ x-java-class: "org.apache.servicecomb.demo.compute.Person"
diff --git a/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
b/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
index d7c6a0a65..985fcb71e 100644
--- a/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
+++ b/demo/demo-schema/src/main/resources/microservices/pojo/server.yaml
@@ -215,3 +215,4 @@ definitions:
type: integer
index:
type: number
+ x-java-class: "org.apache.servicecomb.demo.server.User"
diff --git
a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
index 2bd333013..3e1ea7822 100644
---
a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
+++
b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-client/src/main/java/org/apache/servicecomb/springboot/jaxrs/client/JaxrsClient.java
@@ -19,6 +19,7 @@
import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
+import
org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;
import org.apache.servicecomb.demo.TestMgr;
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb;
@@ -30,10 +31,10 @@
public class JaxrsClient {
public static void main(String[] args) throws Exception {
+ RestObjectMapperFactory.setDefaultRestObjectMapper(new
RestObjectMapperWithStringMapper());
+ RestObjectMapperFactory.setConsumerWriterMapper(new
RestObjectMapperWithStringMapperNotWriteNull());
Log4jUtils.init();
SpringApplication.run(JaxrsClient.class, args);
-
- RestObjectMapperFactory.setDefaultRestObjectMapper(new
RestObjectMapperWithStringMapper());
org.apache.servicecomb.demo.jaxrs.client.JaxrsClient.run();
TestMgr.summary();
}
diff --git
a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
index 5b4add3f3..fc133f62e 100644
---
a/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
+++
b/demo/demo-spring-boot-provider/demo-spring-boot-jaxrs-server/src/main/java/org/apache/servicecomb/springboot/jaxrs/server/JaxrsServer.java
@@ -19,6 +19,7 @@
import org.apache.servicecomb.common.rest.codec.RestObjectMapperFactory;
import org.apache.servicecomb.demo.RestObjectMapperWithStringMapper;
+import
org.apache.servicecomb.demo.RestObjectMapperWithStringMapperNotWriteNull;
import org.apache.servicecomb.foundation.common.utils.Log4jUtils;
import org.apache.servicecomb.springboot.starter.provider.EnableServiceComb;
import org.springframework.boot.SpringApplication;
@@ -28,8 +29,9 @@
@EnableServiceComb
public class JaxrsServer {
public static void main(final String[] args) throws Exception {
+ RestObjectMapperFactory.setDefaultRestObjectMapper(new
RestObjectMapperWithStringMapper());
+ RestObjectMapperFactory.setConsumerWriterMapper(new
RestObjectMapperWithStringMapperNotWriteNull());
Log4jUtils.init();
SpringApplication.run(JaxrsServer.class, args);
- RestObjectMapperFactory.setDefaultRestObjectMapper(new
RestObjectMapperWithStringMapper());
}
}
diff --git
a/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/microservices/pojo/server.yaml
b/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/microservices/pojo/server.yaml
index 903bf15c9..3fa0fdab0 100644
---
a/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/microservices/pojo/server.yaml
+++
b/demo/demo-spring-boot-transport/demo-spring-boot-pojo-server/src/main/resources/microservices/pojo/server.yaml
@@ -194,3 +194,4 @@ definitions:
type: number
index:
type: number
+ x-java-class: "org.apache.servicecomb.demo.server.User"
\ No newline at end of file
diff --git
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index a555fc9b5..37aa87054 100644
---
a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++
b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -325,6 +325,9 @@ private static void testSpringMvcDefaultValues(RestTemplate
template, String mic
result = template.getForObject(cseUrlPrefix + "/query3?a=30&b=2",
String.class);
TestMgr.check("Hello 302", result);
+ result = template.getForObject(cseUrlPrefix + "/query3?a=30",
String.class);
+ TestMgr.check("Hello 30null", result);
+
//input values
headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
@@ -360,6 +363,9 @@ private static void
testSpringMvcDefaultValuesJavaPrimitive(RestTemplate templat
TestMgr.check("Hello", result);
result = template.postForObject(cseUrlPrefix + "/javaprimitivecomb", null,
String.class);
- TestMgr.check("Hello 00.0", result);
+ TestMgr.check("Hello nullnull", result);
+
+ result = template.postForObject(cseUrlPrefix + "/allprimitivetypes", null,
String.class);
+ TestMgr.check("Hello false,0,0,0,0,0,0.0,0.0,null", result);
}
}
diff --git
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
index 1c99505ae..d6b33ebe4 100644
---
a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
+++
b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/SpringMvcDefaultValues.java
@@ -52,7 +52,8 @@ public String query(@RequestParam(name = "a", defaultValue =
"20") int a,
}
@GetMapping("/query2")
- public String query2(@RequestParam(name = "e", required = false) int e,
@RequestParam(name = "a", defaultValue = "20") int a,
+ public String query2(@RequestParam(name = "e", required = false) int e,
+ @RequestParam(name = "a", defaultValue = "20") int a,
@RequestParam(name = "b", defaultValue = "bobo") String b,
@RequestParam(name = "c", defaultValue = "40") Integer c,
@Min(value = 20) @Max(value = 30) @RequestParam(name = "d", required =
false) int d) {
@@ -71,21 +72,44 @@ public String springJavaPrimitiveInt(@RequestParam(name =
"a", required = false)
}
@PostMapping("/javaprimitivenumber")
- public String springJavaPrimitiveNumber(@RequestParam(name = "a", required =
false) float a, @RequestParam(name = "b", required = false) boolean b) {
+ public String springJavaPrimitiveNumber(@RequestParam(name = "a", required =
false) float a,
+ @RequestParam(name = "b", required = false) boolean b) {
return "Hello " + a + b;
}
@PostMapping("/javaprimitivestr")
- public String springJavaPrimitiveStr(@RequestParam(name = "a", required =
false) int a, @RequestParam(name = "b", required = false) String b) {
+ public String springJavaPrimitiveStr(@RequestParam(name = "a", required =
false) int a,
+ @RequestParam(name = "b", required = false) String b) {
if (b == null || b.equals("")) {
return "Hello";
}
return "Hello " + b + a;
-
}
@PostMapping("/javaprimitivecomb")
- public String springJavaPrimitiveCombination(@RequestParam(name = "a",
required = false) Integer a, @RequestParam(name = "b", required = false) Float
b) {
+ public String springJavaPrimitiveCombination(@RequestParam(name = "a",
required = false) Integer a,
+ @RequestParam(name = "b", required = false) Float b) {
return "Hello " + a + b;
}
+
+ @PostMapping("/allprimitivetypes")
+ public String allprimitivetypes(@RequestParam(name = "pBoolean", required =
false) boolean pBoolean,
+ @RequestParam(name = "pChar", required = false) char pChar,
+ @RequestParam(name = "pByte", required = false) byte pByte,
+ @RequestParam(name = "pShort", required = false) short pShort,
+ @RequestParam(name = "pInt", required = false) int pInt,
+ @RequestParam(name = "pLong", required = false) long pLong,
+ @RequestParam(name = "pFloat", required = false) float pFloat,
+ @RequestParam(name = "pDouble", required = false) double pDouble,
+ @RequestParam(name = "pDoubleWrap", required = false) Double
pDoubleWrap) {
+ return "Hello " + pBoolean + ","
+ + pChar + ","
+ + pByte + ","
+ + pShort + ","
+ + pInt + ","
+ + pLong + ","
+ + pFloat + ","
+ + pDouble + ","
+ + pDoubleWrap;
+ }
}
diff --git
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
index 8698585c7..376a1b316 100644
---
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
+++
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGenerator.java
@@ -277,13 +277,13 @@ protected void scanMethodParameters() {
Type[] parameterTypes = providerMethod.getGenericParameterTypes();
for (int paramIdx = 0; paramIdx < parameterTypes.length; paramIdx++) {
int swaggerParamCount = providerParameters.size();
+ Type type = parameterTypes[paramIdx];
// 根据annotation处理
Annotation[] paramAnnotations = allAnnotations[paramIdx];
- processByParameterAnnotation(paramAnnotations, paramIdx);
+ processByParameterAnnotation(paramAnnotations, paramIdx, type);
if (isArgumentNotProcessed(swaggerParamCount)) {
- Type type = parameterTypes[paramIdx];
// 是否需要根据参数类型处理,目标场景:httpRequest之类
processByParameterType(type, paramIdx);
}
@@ -299,7 +299,8 @@ private boolean isArgumentNotProcessed(int
swaggerParamCount) {
return swaggerParamCount == providerParameters.size();
}
- protected void processByParameterAnnotation(Annotation[] paramAnnotations,
int paramIdx) {
+ @SuppressWarnings({"rawtypes", "unckecked"})
+ protected void processByParameterAnnotation(Annotation[] paramAnnotations,
int paramIdx, Type parameterType) {
String defaultValue = null;
Parameter parameter = null;
for (Annotation annotation : paramAnnotations) {
@@ -319,23 +320,16 @@ protected void processByParameterAnnotation(Annotation[]
paramAnnotations, int p
if (defaultValue != null) {
((AbstractSerializableParameter<?>)
parameter).setDefaultValue(defaultValue);
} else if ((((AbstractSerializableParameter<?>)
parameter).getDefaultValue() == null)
- && (!((AbstractSerializableParameter<?>) parameter).getRequired()))
{ //if required false then only take java primitive values as defaults
- String type = ((AbstractSerializableParameter<?>) parameter).getType();
- switch (type) {
- case "integer":
- defaultValue = "0";
- break;
- case "number":
- defaultValue = "0.0";
- break;
- case "string":
- defaultValue = "";
- break;
- case "boolean":
- defaultValue = "false";
- break;
- default:
- defaultValue = null;
+ && (!((AbstractSerializableParameter<?>) parameter)
+ .getRequired())) { //if required false then only take java primitive
values as defaults
+ if (parameterType instanceof Class && ((Class)
parameterType).isPrimitive()) {
+ switch (parameterType.getTypeName()) {
+ case "boolean":
+ defaultValue = "false";
+ break;
+ default:
+ defaultValue = "0";
+ }
}
((AbstractSerializableParameter<?>)
parameter).setDefaultValue(defaultValue);
}
diff --git
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMetaMapper.java
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMetaMapper.java
new file mode 100644
index 000000000..e3577114f
--- /dev/null
+++
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponseMetaMapper.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.swagger.invocation.response;
+
+import java.util.Map;
+
+public interface ResponseMetaMapper {
+ default int getOrder() {
+ return 0;
+ }
+
+ Map<Integer, ResponseMeta> getMapper();
+}
diff --git
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
index 09b96dab5..5c5337569 100644
---
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
+++
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/response/ResponsesMeta.java
@@ -23,9 +23,11 @@
import javax.ws.rs.core.Response.Status;
+import org.apache.servicecomb.foundation.common.utils.SPIServiceUtils;
import org.apache.servicecomb.swagger.converter.SwaggerToClassGenerator;
import org.apache.servicecomb.swagger.invocation.context.HttpStatus;
import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
+import org.apache.servicecomb.swagger.invocation.exception.ExceptionFactory;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.SimpleType;
@@ -35,7 +37,12 @@
import io.swagger.models.Response;
public class ResponsesMeta {
- private static final JavaType COMMON_EXCEPTION_JAVATYPE =
SimpleType.constructUnsafe(CommonExceptionData.class);
+ private static final JavaType COMMON_EXCEPTION_JAVA_TYPE =
SimpleType.constructUnsafe(CommonExceptionData.class);
+
+ private static final JavaType OBJECT_JAVA_TYPE =
SimpleType.constructUnsafe(Object.class);
+
+ private static final ResponseMetaMapper GLOBAL_DEFAULT_MAPPER =
SPIServiceUtils
+ .getPriorityHighestService(ResponseMetaMapper.class);
private Map<Integer, ResponseMeta> responseMap = new HashMap<>();
@@ -46,6 +53,8 @@
// 如果不传return类型进来,完全以swagger为标准,会导致生成的class不等于return
public void init(SwaggerToClassGenerator swaggerToClassGenerator, Operation
operation, Type returnType) {
initSuccessResponse(returnType);
+ initInternalErrorResponse();
+ initGlobalDefaultMapper();
for (Entry<String, Response> entry : operation.getResponses().entrySet()) {
if ("default".equals(entry.getKey())) {
@@ -55,14 +64,15 @@ public void init(SwaggerToClassGenerator
swaggerToClassGenerator, Operation oper
}
Integer statusCode = Integer.parseInt(entry.getKey());
- ResponseMeta responseMeta = responseMap.computeIfAbsent(statusCode, k ->
new ResponseMeta());
- responseMeta.init(swaggerToClassGenerator, entry.getValue());
+ ResponseMeta codeMeta = new ResponseMeta();
+ codeMeta.init(swaggerToClassGenerator, entry.getValue());
+ ResponseMeta responseMeta = responseMap.put(statusCode, codeMeta);
}
if (defaultResponse == null) {
// swagger中没有定义default,加上default专用于处理exception
ResponseMeta responseMeta = new ResponseMeta();
- responseMeta.setJavaType(COMMON_EXCEPTION_JAVATYPE);
+ responseMeta.setJavaType(OBJECT_JAVA_TYPE);
defaultResponse = responseMeta;
}
@@ -74,6 +84,22 @@ protected void initSuccessResponse(Type returnType) {
responseMap.put(Status.OK.getStatusCode(), successResponse);
}
+ protected void initInternalErrorResponse() {
+ ResponseMeta internalErrorResponse = new ResponseMeta();
+ internalErrorResponse.setJavaType(COMMON_EXCEPTION_JAVA_TYPE);
+ responseMap.put(ExceptionFactory.CONSUMER_INNER_STATUS_CODE,
internalErrorResponse);
+ responseMap.put(ExceptionFactory.PRODUCER_INNER_STATUS_CODE,
internalErrorResponse);
+ }
+
+ protected void initGlobalDefaultMapper() {
+ if (GLOBAL_DEFAULT_MAPPER != null) {
+ Map<Integer, ResponseMeta> mappers = GLOBAL_DEFAULT_MAPPER.getMapper();
+ if (mappers != null) {
+ responseMap.putAll(mappers);
+ }
+ }
+ }
+
public ResponseMeta findResponseMeta(int statusCode) {
ResponseMeta responseMeta = responseMap.get(statusCode);
if (responseMeta == null) {
diff --git
a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java
b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java
index 6b03522cd..695504094 100644
---
a/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java
+++
b/swagger/swagger-invocation/invocation-core/src/test/java/org/apache/servicecomb/swagger/invocation/response/TestResponsesMeta.java
@@ -19,7 +19,6 @@
import org.apache.servicecomb.swagger.converter.SwaggerToClassGenerator;
import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
import
org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;
-import org.apache.servicecomb.swagger.invocation.exception.CommonExceptionData;
import org.junit.Assert;
import org.junit.Test;
@@ -55,10 +54,13 @@ public void test() {
meta.init(swaggerToClassGenerator, operation, int.class);
ResponseMeta resp = meta.findResponseMeta(200);
- Assert.assertEquals(int.class, resp.getJavaType().getRawClass());
+ // Response is based on swagger type and is Integer type.
+ Assert.assertEquals(Integer.class, resp.getJavaType().getRawClass());
resp = meta.findResponseMeta(201);
- Assert.assertEquals(int.class, resp.getJavaType().getRawClass());
+ // Response is based on swagger type and is Integer type. For this test
case there is one problem need to discuss.
+ // If SUCCESS family, do we should use OK response type?
+ Assert.assertEquals(Integer.class, resp.getJavaType().getRawClass());
resp = meta.findResponseMeta(400);
Assert.assertEquals(String.class, resp.getJavaType().getRawClass());
@@ -68,6 +70,7 @@ public void test() {
Assert.assertEquals(Integer.class,
resp.getHeaders().get("h1").getRawClass());
resp = meta.findResponseMeta(500);
- Assert.assertEquals(CommonExceptionData.class,
resp.getJavaType().getRawClass());
+ // changed to Object for new version to keep user defined error data not
lose and can be parsed.
+ Assert.assertEquals(Object.class, resp.getJavaType().getRawClass());
}
}
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 7d540784a..60921c506 100644
---
a/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
+++
b/transports/transport-rest/transport-rest-client/src/main/java/org/apache/servicecomb/transport/rest/client/http/DefaultHttpClientFilter.java
@@ -23,13 +23,13 @@
import org.apache.servicecomb.common.rest.RestConst;
import org.apache.servicecomb.common.rest.codec.produce.ProduceProcessor;
+import
org.apache.servicecomb.common.rest.codec.produce.ProduceProcessorManager;
import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
import org.apache.servicecomb.common.rest.filter.HttpClientFilter;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.OperationMeta;
import org.apache.servicecomb.foundation.vertx.http.HttpServletRequestEx;
import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
-import org.apache.servicecomb.swagger.invocation.InvocationType;
import org.apache.servicecomb.swagger.invocation.Response;
import org.apache.servicecomb.swagger.invocation.response.ResponseMeta;
import org.slf4j.Logger;
@@ -74,6 +74,8 @@ protected Response extractResponse(Invocation invocation,
HttpServletResponseEx
RestOperationMeta swaggerRestOperation =
operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
ProduceProcessor produceProcessor =
findProduceProcessor(swaggerRestOperation, responseEx);
if (produceProcessor == null) {
+ // This happens outside the runtime such as Servlet filter response.
Here we give a default json parser to it
+ // and keep user data not get lose.
String msg =
String.format("method %s, path %s, statusCode %d, reasonPhrase %s,
response content-type %s is not supported",
swaggerRestOperation.getHttpMethod(),
@@ -81,8 +83,8 @@ protected Response extractResponse(Invocation invocation,
HttpServletResponseEx
responseEx.getStatus(),
responseEx.getStatusType().getReasonPhrase(),
responseEx.getHeader(HttpHeaders.CONTENT_TYPE));
- LOGGER.error(msg);
- return Response.createFail(InvocationType.CONSUMER, msg);
+ LOGGER.warn(msg);
+ produceProcessor = ProduceProcessorManager.DEFAULT_PROCESSOR;
}
try {
diff --git
a/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestDefaultHttpClientFilter.java
b/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestDefaultHttpClientFilter.java
index 3279ab393..d14bc1da4 100644
---
a/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestDefaultHttpClientFilter.java
+++
b/transports/transport-rest/transport-rest-client/src/test/java/org/apache/servicecomb/transport/rest/client/http/TestDefaultHttpClientFilter.java
@@ -31,6 +31,7 @@
import org.apache.servicecomb.common.rest.definition.RestOperationMeta;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.foundation.common.utils.JsonUtils;
import org.apache.servicecomb.foundation.vertx.http.HttpServletResponseEx;
import org.apache.servicecomb.foundation.vertx.http.ReadStreamPart;
import org.apache.servicecomb.swagger.invocation.Response;
@@ -48,6 +49,7 @@
import io.vertx.core.buffer.impl.BufferImpl;
import io.vertx.core.http.CaseInsensitiveHeaders;
import mockit.Expectations;
+import mockit.Injectable;
import mockit.Mock;
import mockit.MockUp;
import mockit.Mocked;
@@ -172,29 +174,38 @@ ProduceProcessor findProduceProcessor(RestOperationMeta
restOperation, HttpServl
public void testAfterReceiveResponseNullProduceProcessor(@Mocked Invocation
invocation,
@Mocked HttpServletResponseEx responseEx,
@Mocked OperationMeta operationMeta,
- @Mocked RestOperationMeta swaggerRestOperation) {
+ @Mocked RestOperationMeta swaggerRestOperation,
+ @Injectable ResponseMeta responseMeta) throws Exception {
+ CommonExceptionData data = new CommonExceptionData("abcd");
new Expectations() {
{
invocation.getOperationMeta();
result = operationMeta;
operationMeta.getExtData(RestConst.SWAGGER_REST_OPERATION);
result = swaggerRestOperation;
+ operationMeta.findResponseMeta(403);
+ result = responseMeta;
+ responseMeta.getJavaType();
+ result = SimpleType.constructUnsafe(CommonExceptionData.class);
responseEx.getStatus();
- result = 200;
+ result = 403;
+ responseEx.getStatusType();
+ result = Status.FORBIDDEN;
+ responseEx.getBodyBuffer();
+ result = Buffer.buffer(JsonUtils.writeValueAsString(data).getBytes());
}
};
Response response = filter.afterReceiveResponse(invocation, responseEx);
- Assert.assertEquals(490, response.getStatusCode());
- Assert.assertEquals(ExceptionFactory.CONSUMER_INNER_REASON_PHRASE,
response.getReasonPhrase());
+ Assert.assertEquals(403, response.getStatusCode());
+ Assert.assertEquals("Forbidden", response.getReasonPhrase());
Assert.assertEquals(InvocationException.class,
response.<InvocationException>getResult().getClass());
InvocationException invocationException = response.getResult();
Assert.assertEquals(
- 490,
+ 403,
invocationException.getStatusCode());
Assert.assertEquals(
- "CommonExceptionData [message=method null, path null, statusCode 200,
reasonPhrase null, "
- + "response content-type null is not supported]",
+ "CommonExceptionData [message=abcd]",
invocationException.getErrorData().toString());
}
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
> Provide a way to decode user's custom error data
> ------------------------------------------------
>
> Key: SCB-847
> URL: https://issues.apache.org/jira/browse/SCB-847
> Project: Apache ServiceComb
> Issue Type: New Feature
> Components: Java-Chassis
> Reporter: liubao
> Assignee: liubao
> Priority: Major
>
> Now ServiceComb can only decode two types of response:
> # specified in service
> # CommonExceptionData
> Users may need to return custom response error data.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)