annotation与httpclient -- HttpClient使用Annotation和Proxy

HttpClient使用AnnotationProxy

1.     ObjectProxy

在数据库领域,通常使用ORM方式映射数据模型和数据库表,在XML领域也有OXM方式,将对象与数据模型映射。此外还有另外一种思路,就是通过代理的方式生成映射,例如mybatis等。

我们期望有一种映射模型,能够映射一套完整的Http请求,用户通过配置就可以完成Http请求的编写,分离业务逻辑和Http请求系统逻辑间的耦合。

使用Object模式,用户需要对每一个Http请求创建一个Model,使用Proxy方式,可以将同一类的Http请求在一个接口中定义,接口中的不同方法表示不同的Http请求。

对于Http请求,返回值主要有两种,一种是StringJSONXML),一种是byte流(文件等),为了简化设计,只提供了Stringbyte[]两种类型的返回值。

2.     层次设计和内部逻辑

前面分别介绍了HttpClientRestTemplateAnnotation+Proxy的用法,结合先前的介绍,可以得到如下关于HttpClient的设计模型:

如上图所示,当需要一个新的Http请求时,用户通过编写接口和在接口上标记相应的信息即可,不需要关心底层具体使用何种方式实现,屏蔽了业务逻辑和系统逻辑的细节。在运行时,MapperProxy创建代理,并实现了InvocationHandler接口,当外部调用具体接口时,会触发MapperProxy中实现的invoke方法,在invoke方法内部会创建MapperMethod,之后会调用其execute方法。MapperMethod负责分析Annotation的配置和值,组织相应的参数,并通过template将信息继续传递,template封装了HttpClient的请求,实现了MapperMethod层与HttpClient层间的隔离,如果最终HttpClient的实现方式被替换掉,也不会影响到代理层和业务逻辑层的代码实现。最终template调用RestClient,完成Http请求。RestClient中封装了一个多线程的HttpClient池,用于最终完成请求。

3.     关于Http请求的Interface and annotation设计

对于一个Http请求的参数主要是urlqueryheadbody。请求方式主要是PostGetPutHeadDelete等。

我们通过举例子的方式,描述相应的主要功能。

例如,我们定义请求接口如下:

@URL("http://api.m.renren.com/api")

@ParamDefaults({

    @ParamDefault(paramname="v",value="1.0",type=ParamType.BODY),

    @ParamDefault(paramname="format",type=ParamType.BODY,value="JSON")})

publicinterface RenRenHttpDao {

 

    @Post("/photos/uploadbin")

    @ParamDefaults({

       @ParamDefault(paramname="voice_rate",value="44100",type=ParamType.BODY),

       @ParamDefault(paramname="default_album_switch",value="2",type=ParamType.BODY),

       @ParamDefault(paramname="from",value="2080686",type=ParamType.BODY)

    })

    public String share(

           @ParamBody("access_token") String accessToken,

           @ParamBody("call_id") String callId,

           @ParamBody("caption") String caption,

           @ParamFile("data") HttpFile data,

           @ParamFile("voicedata") HttpFile voiceData,

           @ParamBody("voice_length") long voiceLength,

           @ParamBody("voice_size") long voiceSize,

           @ParamBody("sig") String sig

           );

   

}

首先,@URL指明了这个接口内部所有方法要访问的web服务的地址公共部分,类上的@ParamDefaults定义接口内部所有方法都会使用到的默认参数。@Post@Get@Put@Delete@Header分别表示不同的请求类型,并且可以带有请求url的子路径。标记在方法上的@ParamDefaults表示这个方法调用过程中使用的默认参数。最后@ParamBody表明Http消息体内部需要承载的消息(@ParamFile是消息体内的文件消息)。

又比如:

@URL("https://api.weibo.com/2")

publicinterface WeiBoHttpDao {

 

    @Get("/short_url/shorten.json")

    public String getshortUrl(@ParamQuery("access_token") String accessToken,

           @ParamQuery("source") long source,

           @ParamQuery("url_long") String urlLong);

}

getshortUrl是访问微博的一个接口,根据接口的描述,最终访问的url应当是https://api.weibo.com/2/short_url/shorten.json @ParamQuery表示Url后面带的query参数,因此最终的访问应当是:

https://api.weibo.com/2/short_url/shorten.jsonaccess_token=**& source=**&url_long=**

最后给出一个访问天气的接口:

@URL("http://m.weather.com.cn/data/{city}.html")

publicinterface WeatherDao {

 

    @Get

    String getWeather(@ParamUrl("city") int cityCode);

}

从接口上能够看出访问的url@ParamUrl指明了Url中需要替换的信息。

我们应当如何使用接口能,答案很简单,如下是一个获取北京天气的例子:

       WeatherDao weather = MapperProxy.newMapperProxy(WeatherDao.class, new DefaultHttpTemplate());//获取proxy

       System.out.println(weather.getWeather(101010100));//调用方法

4.     与spring的结合

如果需要与spring结合可以实现SpringFactoryBean接口,之后就可以通过xml方式配置Proxy。进一步工作是使用Scan扫描Proxy

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值