加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

自己动手写淘宝开放平台:Rop(将WebService REST进行到底!!)

发布时间:2020-12-17 00:36:19 所属栏目:安全 来源:网络整理
导读:http://www.iteye.com/topic/1121252? 简介?? ?? 最近在开发自己公司网站的开放API服务,较深入地研究了 TOP(Taobao Open Platform:淘宝开放平台 http://api.taobao.com )。在接触过这么多的网站API中,发现TOP真的是做得非常不错,结构清晰明了,使用简单

http://www.iteye.com/topic/1121252?

简介??


?? 最近在开发自己公司网站的开放API服务,较深入地研究了 TOP(Taobao Open Platform:淘宝开放平台 http://api.taobao.com )。在接触过这么多的网站API中,发现TOP真的是做得非常不错,结构清晰明了,使用简单轻便。但是TOP没有开源,搞不到TOP的源码。所以只能“自己动手,丰衣足食”了。?
???? 我基于Spring MVC 3.0进行开发,居然3天就完工了,现在已经在公司中使用,大家的反映相当不错,现已整理了一份PPT文档,奉献给大家。同时,我将其命名为ROP(Rest Open Platform),已经在github中发布,地址是:?

??? https://github.com/itstamen/rop ?
?? iteye的Rop群组已经改变很大,最新消息请加入群中了解:http://rop.group.iteye.com/?

?? 欢迎大家讨论!?
?? ROP的快速开发完成,其实是借力于Spring MVC灵活的扩展性和其提供了各种好用且强大的工具类,ROP基于Spring MVC,在处理流程上进行了重新的组织,但是在实现上基本上直接利用Spring提供的工具类和组件,所以实现并不太难。?
???
?? 5分钟快速入门 ?? 以下是基于ROP开发Web Service的简单例子:?
例子说明: ?? 根据userName/password/salary这三个属性创建一个新用户。?
第1步:创建请求对象
Java代码??

收藏代码

  1. package?com.sample.rop.request;??
  2. import?com.stamen.rop.RopRequest;??
  3. import?org.springframework.format.annotation.NumberFormat;??
  4. import?javax.validation.constraints.DecimalMax;??
  5. import?javax.validation.constraints.DecimalMin;??
  6. import?javax.validation.constraints.Pattern;??
  7. ??
  8. public?class?CreateUserRequest?extends?RopRequest?{??
  9. @Pattern(regexp?=?"w{4,30}")//①?通过JSR303注解指定验证规则??
  10. private?String?userName;??
  11. @Pattern(regexp?=?"w{6,0)">//②??
  12. private?String?password;??
  13. @DecimalMin("1000.00")??
  14. @DecimalMax("100000.00")??
  15. @NumberFormat(pattern?=?"#,###.##")//③??
  16. private?long?salary;??
  17. //getter?and?setter...??
  18. }??

?? ①、②及③处通过JSR303注解指定请求参数的合法性规则,如果请求参数值违反了规则,ROP会产生相应的错误报文。?

第2步:创建响应对象 package?com.sample.rop;??
  • import?com.rop.RopResponse;??
  • import?javax.xml.bind.annotation.XmlAccessType;??
  • import?javax.xml.bind.annotation.XmlAccessorType;??
  • import?javax.xml.bind.annotation.XmlAttribute;??
  • import?javax.xml.bind.annotation.XmlRootElement;??
  • @XmlAccessorType(XmlAccessType.FIELD)?//①??
  • @XmlRootElement(name?=?"sampleRopResponse1")??
  • class?CreateUserResponse?implements?RopResponse{??
  • ????@XmlAttribute ????private?String?userId;??
  • private?String?createTime;??
  • ?????? ①、②及③处通过JAXB(即JSR222 已经包含在JDK6中)的注解对响应对象的流化规则进行设置,ROP会自动将响应的对象流化成相应的响应报文,支持XML和JSON格式,仅需通过format的参数进行指定返回格式即可。?
    第3步:创建服务方法
    import?com.rop.ApiMethod;??
  • import?com.sample.rop.request.CreateUserRequest;??
  • import?com.sample.rop.response.CreateUserResponse;??
  • import?org.springframework.stereotype.Service;??
  • @Service//①?服务方法所在的类必须标注成Bean??
  • class?UserRestService?{??
  • @ApiMethod("sample.user.add")//②指定对应的API方法??
  • public?RopResponse?addUser(CreateUserRequest?request)?{??
  • ????????CreateUserResponse?response?=?new?CreateUserResponse();??
  • ????????//add?creaet?new?user?here...??
  • ????????response.setCreateTime("20120101010101");??
  • ????????response.setUserId("1");??
  • ????????return?response;??
  • ????}??
  • ?? 首先,服务方法所在的类必须标注成Bean,如①所示,然后在服务方法中标注ROP的@ApiMethod注解,如②所示,这里的?
    @ApiMethod(" sample.user.add ")表示,addUser(...)将处理?method= &...的服务请求。?
    处理方法的签名规约如下:?
    ??
    • 入参必须继承于RopRequest父类,也可以为空(无入参);
    • 返回值必须实现RopResponse接口,由于一般的服务方法都拥有错误的可能,因此一般直接使用RopResponse作为返回类型,这样不管是正确的响应对象,还是错误的响应对象,都可以满足签名的要求。??
    ??
    ?? 这样,所有服务端的开发工作就完成了!下面来写客户端调用的代码。?
    编写调用的客户端 ?? 由于现在ROP还没有提供客户端调用包,所以我们直接使用Spring的RestTemplate来写:?
    import?com.rop.validation.DefaultRopValidator;??
  • import?org.springframework.util.LinkedMultiValueMap;??
  • import?org.springframework.util.MultiValueMap;??
  • import?org.springframework.web.client.RestTemplate;??
  • import?java.util.ArrayList;??
  • class?UserRestServiceClient?{??
  • static?void?main(String[]?args)?{??
  • ????????RestTemplate?restTemplate?=?new?RestTemplate();??
  • ????????MultiValueMap<String,?String>?form?=?new?LinkedMultiValueMap<String,?String>();??
  • ????????form.add("method",?"sample.user.add");//<--指定服务名??
  • ????????form.add("appKey",?"00001");//<--指定客户端应用的key,我们在rop.appSecret.properties??
  • ????????????????????????????????????//中预定义了两个appKey,服务端可通过实现AppSecretManager??
  • //定义自己的appKey管理策略。??
  • ????????form.add("v",?"1.0");??
  • ????????form.add("sessionId",?"test");//真实系统时,必须是真正的sessionId.??
  • ????????form.add("format",?"xml");??
  • ????????form.add("locale",?"en");??
  • ????????form.add("userName",?"tomson");??
  • ????????form.add("password",?"123456");??
  • ????????form.add("salary",?"2,500.00");??
  • //对请求参数进行签名,对于"00001"?appKey的密钥是"abcdeabcdeabcdeabcdeabcde"??
  • ????????String?sign?=?DefaultRopValidator.sign(new?ArrayList<String>(??
  • ????????????????????????????form.keySet()),?form.toSingleValueMap(),??
  • ????????????????????????????"abcdeabcdeabcdeabcdeabcde");??
  • ????????form.add("sign",?sign);??
  • //发送请求,调用服务??
  • ????????String?response?=?restTemplate.postForObject(??
  • ????????????????"http://localhost:9080/router",?form,?String.class);??
  • ????????System.out.println("response:n"?+?response);??
  • ?? 这里的系统级参数,我们直接模仿TOP设计,说明如下:?
    No parmName ?? paramType? required?? desc
    1. method ???????? String???? ???? Y?? API method name(sample.user.add)
    2. appKey ??? Y?? design to application's appKey,you can define in rop.appSecret.properties which is in classpath.
    3. v???? ????????? String???? ???? Y? API version,now only support:1.0。
    4. sign? ????????? String????? ??? Y? API parameters's sing,Use SHA1 encryption algorithm
    5. sessionId ????? String???? ???? N? use's sessionId.you can provide a rest api so client can? get it and maintain locally.
    6. format?? ?????? String???? Optional,designated response format. The default XML,currently? support for an XML format,json
    7. locale? ??????? String??? ????? N? locale,such lick cn_ZH,en...

    ? 参见: http://open.taobao.com/doc/detail.htm?id=111 ? 启用服务端的服务后,执行该测试,将返回:?
    Xml代码??

    收藏代码

      <?xml?version="1.0"?encoding="utf-8"?standalone="yes"?>??
    1. <sampleRopResponse1?createTime="20120101010101"?userId="1"/>??

  • ? 如果将format参数设置为json,则其返回的报文为:?
    Javascript代码??

    收藏代码

      {"sampleRopResponse1":{"userId":"1","createTime":"20120101010101"}}??

    ? 如果将salary参数改为"aaa",则将返回错误报文(假设format为xml):?
    error?solution="Invalid?Arguments"?message="Invalid?Arguments?"?code="34">??
  • ????subErrors ????????subError ????????????code>isv.parameters-mismatch:salary-and-aaa</message>incoming?parameter?salary?and?aaa?does?not?match,?both???
  • have?a?certain?correspondence?betweenerror>??
  • (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读