You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2018/07/05 06:39:35 UTC
[incubator-servicecomb-docs] branch master updated: 数据类型object支持和servlet path补充文档说明
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-servicecomb-docs.git
The following commit(s) were added to refs/heads/master by this push:
new 216bf49 数据类型object支持和servlet path补充文档说明
216bf49 is described below
commit 216bf49ff718b121dbc0e60b622d52459b0b8155
Author: liubao <ba...@huawei.com>
AuthorDate: Thu Jul 5 14:32:03 2018 +0800
数据类型object支持和servlet path补充文档说明
---
.../zh_CN/build-provider/interface-constraints.md | 23 ++++++++++++++++++----
.../build-provider/protocol/rest-over-servlet.md | 11 +++++++++++
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/java-chassis-reference/zh_CN/build-provider/interface-constraints.md b/java-chassis-reference/zh_CN/build-provider/interface-constraints.md
index a6b4a43..48a693d 100644
--- a/java-chassis-reference/zh_CN/build-provider/interface-constraints.md
+++ b/java-chassis-reference/zh_CN/build-provider/interface-constraints.md
@@ -2,7 +2,7 @@
## 接口定义的要求
-ServiceComb-Java-Chassis对于接口定义的要求建立在一个简单的原则上:接口定义即接口使用说明,不用通过查看代码实现,就能识别如何调用这个接口。可以看出,我们是站在使用者这边的,以更容易被使用作为参考。
+ServiceComb-Java-Chassis建议接口定义遵循一个简单的原则:接口定义即接口使用说明,不用通过查看代码实现,就能识别如何调用这个接口。可以看出,这个原则站在使用者这边,以更容易被使用作为参考。ServiceComb会根据接口定义生成接口契约,符合这个原则的接口,生成的契约也是用户容易阅读的。
举个例子:
@@ -14,7 +14,7 @@ public class Person {String name;}
显然调用接口一,我们知道要传递一个String类型的id参数,返回值是一个Person类型,Person里面存在String类型的name参数。调用接口二,我们不知道怎么处理返回值,必须参考服务提供者的文档说明。这个视角是熟练的RPC开发者的视角。
-当我们要将接口发布为REST接口的时候,可以通过使用swagger文件,指定id使用RequestParam或者PathVariable或者RequestBody进行传递,也可以使用SpringMVC或者JAX RS提供的标签来描述。
+当我们要将接口发布为REST接口的时候,可以指定接口参数和HTTP协议的映射关系,比如:
```java
public Person query(@RequestParam String id);
@@ -40,6 +40,9 @@ ResponseType methodName(RequestType...)
开发者不能在接口定义的时候使用如下类型:
* 抽象的数据结构: java.lang.Object, net.sf.json.JsonObject等
+
+ **备注:** 最新版本可以使用java.lang.Object作为参数和返回值。它的运行时类型可以是int、String、Map等。尽管如此,建议开发者不要使用抽象数据结构,以及第三方提供的非POJO类作为接口的参数和返回值。这些类型包括java.math.BigDecimal、org.joda.time.JodaTime等。这些类型会给开发者带来很大的困扰。比如开发者可能以为BidDecimal会以数字传输,实际不然,并且在某些内部状态没正确计算的情况下,得到的并不是用户预期的值。
+
* 接口或者抽象类
```java
public interface IPerson {//...}
@@ -56,8 +59,6 @@ ResponseType methodName(RequestType...)
开发者不用担心记不住这些约束,程序会在启动的时候检查不支持的类型,并给与错误提示。
-除了上面一些类型,开发者尽可能不要使用一些包含特殊内部状态的类型,这些类型会给开发者代码很大的困扰。比如java.math.BigDecimal,开发者可能以为他会以一个数字传输,实际不然,并且在某些内部状态没正确计算的情况下,得到的并不是用户预期的值。
-
总之,数据结构需要能够使用简单的数据类型进行描述,一目了然就是最好的。这个在不同的语言,不同的协议里面都支持的很好,长期来看,可以大大减少开发者联调沟通和后期重构的成本。
### 关于数据结构和接口变更
@@ -143,3 +144,17 @@ public Generic getHolderListArea() {
> ***说明:***
> 虽然 ServiceComb-Java-Chassis 支持REST泛型参数,但是我们更加推荐用户使用实体类作为参数,以获得更加明确的接口语义。
+
+## 其他常见问题
+
+* 使用RestTemplate传递raw json
+假设服务端定义了接口
+```
+Person test(Person input)
+```
+用户期望使用RestTemplate自行拼接json字符串,然后进行传递:
+```
+ String personStr = JsonUtils.writeValueAsString(input);
+ result = template.postForObject(cseUrlPrefix + "sayhello", personStr, Person.class);
+```
+ServiceComb不推荐开发者这样使用,里面的处理逻辑存在大量歧义。如果必须使用,需要满足几个约束:Person必须包含带String类型的构造函数;provider/consumer都必须存在这个Person类型。
\ No newline at end of file
diff --git a/java-chassis-reference/zh_CN/build-provider/protocol/rest-over-servlet.md b/java-chassis-reference/zh_CN/build-provider/protocol/rest-over-servlet.md
index e4795b6..5e08543 100644
--- a/java-chassis-reference/zh_CN/build-provider/protocol/rest-over-servlet.md
+++ b/java-chassis-reference/zh_CN/build-provider/protocol/rest-over-servlet.md
@@ -1,3 +1,5 @@
+# REST over Servlet
+
## 配置说明
REST over Servlet对应使用web容器模式部署运行,需要新建一个servlet工程将微服务包装起来,加载到web容器中启动运行,包装微服务的方法有两种,一种完全使用web.xml配置文件配置,另一种仅在web.xml文件中配置listener,在microservice.yaml文件中配置urlPattern,两种方式任选一种即可,配置方式如下所示:
@@ -112,5 +114,14 @@ servicecomb:
timeout: 3000
```
+## 对外发布的Path
+由于将应用部署到Servlet,Servlet会在用户访问的URL上追加context和servlet pattern,比如/mywebapp/rest。在接口定义的时候声明path=/appliation,实际用户需要通过/mywebapp/rest/application来访问服务。通过ServiceComb的API,可以屏蔽部署差异,使用者可以使用一致的URL来访问,比如: restTemplate.getForObject("cse://serviceName/application"...)。因此后续用户将应用改造为独立部署,或者修改context,使用者的代码都可以不需要修改。
+
+对于一些遗留系统改造,用户期望继续使用restTemplate.getForObject("cse://serviceName/mywebapp/rest/application"...),这个时候,用户必须将接口定义的path定位为: /mywebapp/rest/application,例如:
+```
+@RestSchema(schemaId = "test")
+@RequestMapping(path = "/mywebapp/rest/application")
+```
+尽管如此,仍然推荐使用部署形态无关的方式来编码,可以减少后续由于部署形态变化,带来的频繁修改客户端代码问题。