Rop开发手册(5):最简单的服务开放平台框架
Rop相关资源:
1.github:https://github.com/itstamen/rop
2.群组:http://rop.group.iteye.com/
目录
1.快速了解Rop
2.请求服务模型
3.应用授权及验证
4.服务会话管理
5.错误处理模型
6.响应报文控制
7.文件上传
8.服务安全控制
9.拦截器及事件体系
10.性能调优
11.开发客户端SDK
12.参考资料
错误模型概述
对于服务开放平台来说,不管发生了什么错误,都必须返回相应的错误报文,以便客户端应用能够根据错误报文做出相应的响应。每个服务都可能存在各种错误,如服务参数不合法、访问权限不足、版本不正确、访问超限等等。如果需要开发者自行设计这套错误模型并处理所有这些错误,那将是一项艰巨的工程。
Rop参考TOP建立了一个完整的错误模型,该错误模型拥有强大的表达能力和扩展性,很多错误自动于Rop负责处理,对于业务性的错误,开发者按错误模型构造即可。Rop将开发者从服务错误处理的荆棘丛中解放出来,从而可以将精力集中于具体的业务逻辑的处理上。
Rop的错误模型分为主错误和子错误两个层级,每个错误报文都会对应一个主错误和若干个子错误,主错误描述错误的类型,子错误说明错误的原因。子错误根据责任归属可以划分为ISP(Internet Service Provider)和ISV(Independent Software Vendors)两种类型的错误。如下图所示:
[img]http://dl.iteye.com/upload/attachment/0072/7375/6baa1f54-0640-3f6a-9fa6-09c12e40f22d.jpg[/img]
图1
ISP代表平台服务提供商一方,如服务内部异常、服务端数据库资源不可用等错误,其责任归属于ISP,这类错误称为ISP错误。ISP错误的错误编码以“isp.”为前缀,如isp.xxx-service-unavailable、isp.xxx-service-timeout等。
ISV代表基于平台服务开发应用的开发者一方,这类错误产生的原因是由于开发者造成的。ISV错误的错误编码以“isv.”为前缀,如isv.invalid-permission、isv.missing-parameter:xxx等。
当服务发生错误时,Rop将返回统一格式的错误报文,它由一个主错误和若干个子错误组成。下面即是一个完整的错误报文:
<?xml version="1.0" encoding="utf-8" standalone="yes"?><error code="33"> <message>非法的参数</message> <solution>请查看根据服务接口对参数格式的要求</solution> <subErrors> <subError code="isv.invalid-paramete:salary"> <message>参数salary无效,格式不对、非法值、越界等</message> </subError> <subError code="isv.invalid-paramete:userName"> <message>参数userName无效,格式不对、非法值、越界等</message> </subError> </subErrors></error>
<?xml version="1.0" encoding="utf-8" standalone="yes"?><error code="1"> <message>Service Currently Unavailable</message> <solution>Service Currently Unavailable</solution> <subErrors> <subError code="isp.user-getSession-service-unavailable"> <message>call the back-end service user.getSession thrownexception:java.lang.IllegalArgumentException, the service is unavailable. exception info is :…</message> </subError> </subErrors></error>
<rop:annotation-driven service-timeout-seconds="10"/>
@ServiceMethod(method = "user.timeout", version = "1.0", timeout = 1) ①public RopResponse timeoutService(CreateUserRequest request) throws Throwable {Thread.sleep(2000); ②CreateUserResponse response = new CreateUserResponse();response.setCreateTime("20120101010102");response.setUserId("2");return response;}<?xml version="1.0" encoding="utf-8" standalone="yes"?><error code="1"> <message>服务不可用</message> <solution>服务目前无法使用</solution> <subErrors> <subError code="isp.user-timeout-service-timeout"> <message>调用user.timeout服务超时,该服务的超时限制为1秒,请和服务平台提供商联系。</message> </subError> </subErrors></error>
@ServiceMethod(method = "user.get", version = "1.0", httpAction = HttpAction.GET)public RopResponse getUser(RopRequest request) throws Throwable {String userId = request.getRopRequestContext().getParamValue("userId");if("9999".equals(userId)){ ①return new NotExistErrorResponse("user","userId","9999",request.getRopRequestContext().getLocale());}else{CreateUserResponse response = new CreateUserResponse();//add creaet new user here...response.setCreateTime("20120101010102");response.setUserId(userId);response.setFeedback("user.get");return response;}}<?xml version="1.0" encoding="utf-8" standalone="yes"?><error code="33"> <message>Invalid Arguments</message> <solution>check the Required application parameter is valid(refer the subError message)</solution> <subErrors> <subError code="isv.user-not-exist:invalid-userId"> <message>cant find userId by 9999</message> </subError> </subErrors></error>
public BusinessServiceErrorResponse(String serviceName, String errorCode, Locale locale, Object... params)
@ServiceMethod(method = "user.add", version = "1.0")public RopResponse addUser(CreateUserRequest request) {if (reservesUserNames.contains(request.getUserName())) { return new BusinessServiceErrorResponse( request.getRopRequestContext().getMethod(), "USER_NAME_RESERVED", request.getRopRequestContext().getLocale(), request.getUserName()); ①} else {CreateUserResponse response = new CreateUserResponse(); response.setCreateTime("20120101010101");response.setUserId("1");return response;}}<?xml version="1.0" encoding="utf-8" standalone="yes"?><error code="9"> <message>业务逻辑出错</message> <solution>请了解服务调用的前置条件,检查是否满足业务逻辑</solution> <subErrors> <subError code="isv.user-add-service-error:USER_NAME_RESERVED"> <message>jhon 是预留的用户,请选择其它的用户名.</message> </subError> </subErrors></error>