背景
近期,由于项目的要求需要在自己的webservice中调用远程的WebAPI(Restful format)。自己的webservice程序是用Java编码写的,所以需要在其中实现一个Client来调用远程的Restful接口。
选型
其实在自己的项目里面也有类似的调用,当时使用的是“JAXRSClientFactory”获得静态代理client。 由于这种方式需要依赖于远程调用的webservice接口(需要引入别人的jar包)。这就造成了高耦合。因此不适用。
所以需要以一种低耦合的方式来实现。便有了选型的想法。
在网上搜索一番后,基本定型为两种方式:
1.HttpClient
2.RestTemplate
接下来就分别列出两种方式的实现代码
HttpClient
import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HttpClientUtil { private static final Logger log = LoggerFactory.getLogger(HttpClientUtil.class); private CloseableHttpClient httpClient = HttpClients.createDefault(); public static String executePost(String url, String tdfBase64) throws Exception { String result = null; HttpPost httpPost = new HttpPost(url); httpPost.setEntity(new HttpEntity(tdfBase64)); HttpResponse response = httpClient.execute(httpPost); if (response != null) { HttpEntity resEntity = response.getEntity(); if (resEntity != null) { result = EntityUtils.toString(resEntity, "utf-8"); } } return result; } } public static void main(String[] args) { // TODO Auto-generated method stub String url = "http://169.8.160.201:8080/xx/Webservice/Submit"; String base64Tdf = "MS4wMToxMzIdMS4wMjowMjAxHTEuMDM6MR8wMR4yHzAwHTEuMDQ6SVJRHTEuMDU6MjAxNjA1MDQdMS4wNjoxHTEuMDc6Q09HRU5UHTEuMDg6VEhBSUxBTkQdMS4wOTpTRVFVRU5DRU5PMTIzNB0xLjExOjE5LjY5HTEuMTI6MTkuNjkcMi4wMDE6MzEdMi4wMDI6MDAdMi4xNzY6MDA3MDA5HA=="; HttpClientUtil client = new HttpClientUtil(); String result=client.executePost(url, base64Tdf, ""); System.out.println(result); }
RestTemplate
package com.biolive.client; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpEntity; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; public class RestTemplateClient { private static final Logger log = LoggerFactory.getLogger(RestTemplateClient.class); private static final int connectTimeout= 5000; private static final int readTimeOut=5000; private RestTemplate restTemplate; public RestTemplateClient(){ SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); requestFactory.setConnectTimeout(connectTimeout); requestFactory.setReadTimeout(readTimeOut); restTemplate = new RestTemplate(requestFactory); } public String executePost(String url, String base64Tdf){ String result = null; HttpEntityrequest = new HttpEntity (base64Tdf); try{ result=restTemplate.postForObject(url, request, String.class); }catch(RestClientException ex){ ex.printStackTrace(); log.info("call post interface error: " + ex.getMessage()); } return result; } public static void main(String[] args) { // TODO Auto-generated method stub String url = "http://169.8.160.201:8080/xx/Webservice/Submit"; String base64Tdf = "MS4wMToxMzIdMS4wMjowMjAxHTEuMDM6MR8wMR4yHzAwHTEuMDQ6SVJRHTEuMDU6MjAxNjA1MDQdMS4wNjoxHTEuMDc6Q09HRU5UHTEuMDg6VEhBSUxBTkQdMS4wOTpTRVFVRU5DRU5PMTIzNB0xLjExOjE5LjY5HTEuMTI6MTkuNjkcMi4wMDE6MzEdMi4wMDI6MDAdMi4xNzY6MDA3MDA5HA=="; RestTemplateClient client = new RestTemplateClient(); String result=client.executePost(url, base64Tdf); System.out.println(result); } }
总结
首先,用两种方法都可以在只知道url和方法类型(GET/POST/PUT/UPDATE)的情况下完成任务,调用的方式也非常类似。
RestTemplate是Spring官方封装和推荐的client, 它优化了一些底层操作,使得我们可以更简单的使用。此外,也可以根据自己的需要和Spring进行结合以及配置。
附录
RestTemplate的使用
RestTemplate有两个构造方法,分别是:
public RestTemplate() {
/**
...初始化过程
*/
}
public RestTemplate(ClientHttpRequestFactory requestFactory) { this(); setRequestFactory(requestFactory); }
其中,第二个构造方法中可以传入ClientHttpRequestFactory参数,第一个进行默认初始化,因为我们经常需要对请求超时进行设置并能够对超时进行后续处理,而第一个构造方法,我们无法控制超时时间,第二个构造中的ClientHttpRequestFactory接口的实现类中存在timeout属性,因此选用第二个构造方法。
在spring配置文件中进行如下配置:
"httpClientFactory" class="org.springframework.http.client.SimpleClientHttpRequestFactory">
"connectTimeout" value="${connectTimeout}"/> "readTimeout" value="${readTimeout}"/> "restTemplate" class="org.springframework.web.client.RestTemplate"> "httpClientFactory"/>
当然也可以直接使用:
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(1000);
requestFactory.setReadTimeout(1000);
RestTemplate restTemplate = new RestTemplate(requestFactory);
注意:ClientHttpRequestFactory 接口有4个实现类,分别是:
- AbstractClientHttpRequestFactoryWrapper 用来装配其他request factory的抽象类。
- CommonsClientHttpRequestFactory 允许用户配置带有认证和http连接池的httpclient,已废弃,推荐用HttpComponentsClientHttpRequestFactory。
- HttpComponentsClientHttpRequestFactory 同2.
- SimpleClientHttpRequestFactory 接口的一个简单实现,可配置proxy,connectTimeout,readTimeout等参数
参考
http://www.cnblogs.com/softidea/p/5977375.html
http://blog.csdn.net/zpf336/article/details/73480810