第三方API的使用心得

  几乎每个系统都要与第三方进行交互。一般来说第三方API都会提供json或xml供系统使用。

  我们的目标是把api集成到系统中,并降低api对系统的影响。但是随着编码的进行,有太多的坏味道散落到系统中,比如Copy的代码满天飞;配置信息分散各处;无法有效地组织API。

  面对这些问题,系统应该主动地把api封装起来,形成独立的模块供上层系统调用。

  

  该模块涉及到的模式为[Template Method+Callack],[Factory],涉及到的元素如下

    1、client:Template Method的实现者;定义了与第三方交互的过程;从Callback获取数据组装成适合第三方的信息。

    2、callback:每一个api,都要实现callback,它提供方法名,参数,Url等数据给client使用

    3、config:各种配置信息,如appkey,加密参数等等

    4、factory:对象工厂。比如每调用第三方,系统给需要生成交易码,就可以把生成的任务委托给factory

    5、model:参数的封装类,利用model,可以生成json数据,也可以生成xml数据给client使用;同时也可以根据业务参数,利用factory生成各种model  

  以上就是模块中的各个元素。

 

  他们之间的调用情况如下:

    1、client 依靠 callback 与 第三方交互

    2、callback 结合 model 创建一个完整的apiCallback

    3、factory从config获取信息并结合业务要求,创建model

  一个的调用过程如下:

Model model  = ModelFactory.getXXXModel(xx,bb,cc)
ApiCallback back = new ApiCallback(model);
Client.doClient(back);

 

  这样的设计方式解决那些问题,如何解决.

    Q1.第三方提供新的API

    A1.增加一个新的Model,实现一个ApiCallback,调用doClient方法

    Q2.第三方系统getName函数名称变动为getUserName

    A2.进入getName对应的GetNameCallback,修改方法名

    Q3.加密密钥放生变化

    Q4.找到对应Config,修改密钥

   

  给一个demo,让大家参考一下,案例已经过缩减,不足之处,多多包涵

public interface  JsonCallback
{
public String getMethodName();
   public String getUrl();
public
JsonRequest getJsonRequest();
public Object onResultReceived(AccountSmsResult result);

}

 

public class JsonClient
{
public static final int CONN_SERVICETOKEN_TIMEOUT = 20000;
private static final Logger logger = LoggerFactory.getLogger(JsonClientHelper.class);
private static final Gson gson = new Gson();

/**
* 方法表述: 与远服务器进行交互,未授权
*/
public static Object doUnsafeClient(JsonCallback callback) throws CException
{
HttpClient httpClient = new HttpClient();
// 创建Post方法
PostMethod method = createUnSafePostMethod(callback);
// 配置参数
configParams(httpClient);
return executeMethod(httpClient, method, callback);
}

/**
* 方法表述:创建未授权的Post方法
*/
private static PostMethod createUnSafePostMethod(JsonCallback callback)
{
String url = callback.getUrl() + callback.getMethodName();
PostMethod method = new PostMethod(url);
method.addRequestHeader("Content-Type", "application/json");
method.setRequestEntity(wrapToRequestEntity(callback));
return method;
}

/**
* 方法表述:配置参数
*/
private static void configParams(HttpClient httpClient)
{
HttpConnectionManagerParams conParams = httpClient.getHttpConnectionManager().getParams();
conParams.setConnectionTimeout(CONN_SERVICETOKEN_TIMEOUT);
conParams.setSoTimeout(CONN_SERVICETOKEN_TIMEOUT);
}
/**
* 方法表述: 执行Post方法
*/
private static Object executeMethod(HttpClient httpClient, PostMethod method, JsonCallback callback)
throws CException
{
Object resultObject = null;
try
{
int result = httpClient.executeMethod(method);
if (result == HttpStatus.SC_OK)
{
String response = method.getResponseBodyAsString();


if (!StringUtil.isNullString(response))
{

resultObject = doResponseReceived(response, callback);
}
}
}
catch (Exception e){
logger.debug(e);
}
finally
{
if (method != null)
method.releaseConnection();

}
return resultObject;
}

/**
* 把Json请求对象转化为字符串,并封装到RequestEntity
*/
protected static RequestEntity wrapToRequestEntity(JsonCallback callback)
{
String req = gson.toJson(callback.getJsonRequest(), JsonRequest.class);
if (logger.isDebugEnabled())
logger.debug(callback.getMethodName() + " req:" + req);
try
{
return new StringRequestEntity(req, null, "utf8");
}
catch (UnsupportedEncodingException e)
{
logger.error("create StringRequestEntity failed for UnsupportedEncodingException.");
throw new RuntimeException("create StringRequestEntity failed for UnsupportedEncodingException.");
}

}

/**
* 方法表述:当收到服务器传递过来的信息时,如何处理
*/
public static Object doResponseReceived(String response, JsonCallback callback) throws CException
{
AccountSmsReturn rsp = gson.fromJson(response, AccountSmsReturn.class);
if (rsp != null && rsp.result != null && rsp.result.resultCode.equals("0"))
{
return callback.onResultReceived(rsp.result);
}
else
{
throw rsp.result.CException;
}
}



 

 

posted on 2011-12-19 22:25  small.ming  阅读(4888)  评论(0编辑  收藏  举报

导航