如何更方便快捷的调用restful服务
2016-04-15 19:31
253 查看
这里我提供我一个restful服务,地址http://restful.wozsz.com/service/application.wadl
我们如何调用这个服务呢,常规方式当然是用httpclient了,它的弊端是对于符合要求的请求json需要自己封装,对于响应的json需要自己解析拿数据,而且不能太过于复杂,不然解析起来相当费劲,一层层的。
package com.somnus.http;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.Validate;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.somnus.exception.HttpStatusException;
/**
* @ClassName: HttpClientUtils.java
* @Description: TODO
* @author Somnus
* @version V1.0
* @Date 2016年10月13日 下午3:40:17
*/
public class HttpClientUtils {
private transient static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);
/**
* @param url
* @param param
* @return
* @throws HttpHostConnectException
* 连接不可用
* @throws IOException
* 网络传输出错
*/
public static String doJsonPost(String url, Map<String,String> param) throws HttpHostConnectException, IOException{
Validate.notNull(url, "url is required.");
Validate.notEmpty(param);
return doJsonPost(url,JSON.toJSONString(param));
}
/**
* @param url
* @param json
* @return
* @throws HttpHostConnectException
* 连接不可用
* @throws IOException
* 网络传输出错
*/
public static String doJsonPost(String url, String json) throws HttpHostConnectException, IOException{
Validate.notNull(url, "url is required.");
Validate.notNull(json, "json is required.");
//创建HttpClient对象
CloseableHttpClient httpclient = HttpConnectionManager.getHttpClient();
String resultString = "";
CloseableHttpResponse httpResponse = null;
try {
// 创建HttpPost对象
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(json,ContentType.APPLICATION_JSON));
// 开始执行http请求
long startTime = System.currentTimeMillis();
httpResponse = httpclient.execute(httpPost);
long endTime = System.currentTimeMillis();
// 获得响应状态码
int statusCode = httpResponse.getStatusLine().getStatusCode();
log.info("statusCode:" + statusCode);
log.info("调用API 花费时间(单位:毫秒):" + (endTime - startTime));
// 取出应答字符串
HttpEntity httpEntity = httpResponse.getEntity();
resultString = EntityUtils.toString(httpEntity,Charset.forName("UTF-8"));
// 判断返回状态是否为200
if (statusCode != HttpStatus.SC_OK) {
throw new HttpStatusException(String.format("\n\tStatus:%s\n\tError Message:%s", statusCode,resultString));
}
} finally{
if(httpResponse != null){
httpResponse.close();
}
httpclient.close();
}
return resultString;
}
}
但是也有人肯定也知道基于jersey的api也是可以调用的
基于jersey的api调用,它需要你提供服务的接口java文件,请求和响应java文件,当然这需要服务提供方,额外进行打包抽取出自己服务相关的的接口到jar包中提供给调用者,这对于以httpclient调用的方式来说确实麻烦了点,不过在技术可行上来说,抽取工作相当方便,根本无需人工复制粘贴,只需用maven插件进行抽取。
这是我作为服务方给调用者提供的jar包
我已经打包好,并上传到nexus,http://maven.wozsz.com
写到这里,读者肯定会说,这有什么嘛,我要基于jersey的api调,也要对其封装啊,而且服务方多了抽取工作,调用者还得额外添加api-jar包
可是如果我已经提供了一个组件给你呢,专门用来调用jersey服务的
并且在spring项目中你可以以bean的形式把服务添加到项目中呢,比如这样
现在我们再次调用我提供的服务,你只需注入bean就可以了
比如
如果不是spring项目呢,可以用这个组件吗,回答是当然可以了,且看
POST方式
1、http://restful.wozsz.com/service/com.somnus.resource.RestfulResource/getAccount
2、http://restful.wozsz.com/service/com.somnus.resource.RestfulResource/getAccount2
GET方式
3、http://restful.wozsz.com/service/com.somnus.resource.RestfulResource/getAccount3/admin/123456
4、http://restful.wozsz.com/service/com.somnus.resource.RestfulResource/getAccount4?username=admin&password=123456
我们如何调用这个服务呢,常规方式当然是用httpclient了,它的弊端是对于符合要求的请求json需要自己封装,对于响应的json需要自己解析拿数据,而且不能太过于复杂,不然解析起来相当费劲,一层层的。
package com.somnus.http;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.Validate;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.somnus.exception.HttpStatusException;
/**
* @ClassName: HttpClientUtils.java
* @Description: TODO
* @author Somnus
* @version V1.0
* @Date 2016年10月13日 下午3:40:17
*/
public class HttpClientUtils {
private transient static Logger log = LoggerFactory.getLogger(HttpClientUtils.class);
/**
* @param url
* @param param
* @return
* @throws HttpHostConnectException
* 连接不可用
* @throws IOException
* 网络传输出错
*/
public static String doJsonPost(String url, Map<String,String> param) throws HttpHostConnectException, IOException{
Validate.notNull(url, "url is required.");
Validate.notEmpty(param);
return doJsonPost(url,JSON.toJSONString(param));
}
/**
* @param url
* @param json
* @return
* @throws HttpHostConnectException
* 连接不可用
* @throws IOException
* 网络传输出错
*/
public static String doJsonPost(String url, String json) throws HttpHostConnectException, IOException{
Validate.notNull(url, "url is required.");
Validate.notNull(json, "json is required.");
//创建HttpClient对象
CloseableHttpClient httpclient = HttpConnectionManager.getHttpClient();
String resultString = "";
CloseableHttpResponse httpResponse = null;
try {
// 创建HttpPost对象
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(json,ContentType.APPLICATION_JSON));
// 开始执行http请求
long startTime = System.currentTimeMillis();
httpResponse = httpclient.execute(httpPost);
long endTime = System.currentTimeMillis();
// 获得响应状态码
int statusCode = httpResponse.getStatusLine().getStatusCode();
log.info("statusCode:" + statusCode);
log.info("调用API 花费时间(单位:毫秒):" + (endTime - startTime));
// 取出应答字符串
HttpEntity httpEntity = httpResponse.getEntity();
resultString = EntityUtils.toString(httpEntity,Charset.forName("UTF-8"));
// 判断返回状态是否为200
if (statusCode != HttpStatus.SC_OK) {
throw new HttpStatusException(String.format("\n\tStatus:%s\n\tError Message:%s", statusCode,resultString));
}
} finally{
if(httpResponse != null){
httpResponse.close();
}
httpclient.close();
}
return resultString;
}
}
@Test public void doJsonPost(){ try { String url = "http://120.26.68.243:8080/restful/service/com.somnus.resource.RestfulResource/getAccount"; Map<String,String> param = new HashMap<String, String>(); param.put("username", "admin"); param.put("password", "123456"); System.out.println("body:" + HttpClientUtils.doJsonPost(url, param)); } catch (HttpStatusException e){ log.error(e.getMessage(),e); } catch (HttpHostConnectException e) { log.error(e.getMessage(),e); } catch (IOException e) { log.error(e.getMessage(),e); } }
但是也有人肯定也知道基于jersey的api也是可以调用的
package com.somnus.support; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response.Status; import org.junit.Test; import com.somnus.domain.Request; import com.somnus.domain.Response; import com.somnus.resource.RestfulResource; import com.somnus.rest.core.client.RESTfulJsonClientFactory; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; public class ClientCase { /** * <p></p> * @author:Somnus * @param args */ public static void main(String[] args) { Client client = Client.create(); WebResource webResource = client.resource("http://120.26.68.243:8080/restful/service/com.somnus.resource.RestfulResource/getAccount"); ClientResponse response = webResource.entity(new Request("admin","123456"), MediaType.APPLICATION_JSON).post(ClientResponse.class); System.out.println(response.getStatus()); if(response.getStatus() == Status.OK.getStatusCode()){ Response r = response.getEntity(Response.class); System.out.println(r); } }
基于jersey的api调用,它需要你提供服务的接口java文件,请求和响应java文件,当然这需要服务提供方,额外进行打包抽取出自己服务相关的的接口到jar包中提供给调用者,这对于以httpclient调用的方式来说确实麻烦了点,不过在技术可行上来说,抽取工作相当方便,根本无需人工复制粘贴,只需用maven插件进行抽取。
这是我作为服务方给调用者提供的jar包
我已经打包好,并上传到nexus,http://maven.wozsz.com
<!-- 指定Maven仓库 --> <repositories> <!-- oschina的maven仓库 --> <repository> <id>repository</id> <name>local private nexus</name> <url>http://maven.wozsz.com:88/content/groups/public/</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>
<dependency> <groupId>com.somnus</groupId> <artifactId>ruo</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency>
写到这里,读者肯定会说,这有什么嘛,我要基于jersey的api调,也要对其封装啊,而且服务方多了抽取工作,调用者还得额外添加api-jar包
可是如果我已经提供了一个组件给你呢,专门用来调用jersey服务的
<dependency> <groupId>com.somnus.rest.core</groupId> <artifactId>rest-core</artifactId> <version>3.2.0</version> </dependency>
并且在spring项目中你可以以bean的形式把服务添加到项目中呢,比如这样
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="restfulResource" class="com.somnus.rest.core.spring.RestfulJsonFactoryBean"> <property name="serviceInterface" value="com.somnus.resource.RestfulResource" /> <property name="serviceUrl" value="http://120.26.68.243:8080/restful/service/"/> </bean> </beans>
现在我们再次调用我提供的服务,你只需注入bean就可以了
比如
package com.somnus.support; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.somnus.domain.Request; import com.somnus.domain.Response; import com.somnus.resource.RestfulResource; @Service public class TestServiceImpl { @Autowired private RestfulResource restfulResource; public void rest(){ Response response = restfulResource.getAccount(new Request("admin","123456")); System.out.println(response); } }
如果不是spring项目呢,可以用这个组件吗,回答是当然可以了,且看
package com.somnus.support; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response.Status; import org.junit.Test; import com.somnus.domain.Request; import com.somnus.domain.Response; import com.somnus.resource.RestfulResource; import com.somnus.rest.core.client.RESTfulJsonClientFactory; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; public class ClientCase { private static final String BASE_URL = "http://120.26.68.243:8080/restful/service/"; RestfulResource resource = RESTfulJsonClientFactory.createClient(RestfulResource.class, BASE_URL); @Test public void rest(){ Response response = resource.getAccount(new Request("admin","123456")); System.out.println(response); } }
POST方式
1、http://restful.wozsz.com/service/com.somnus.resource.RestfulResource/getAccount
{ "username": "admin", "password": "123456" }
2、http://restful.wozsz.com/service/com.somnus.resource.RestfulResource/getAccount2
<?xml version="1.0" encoding="utf-8"?> <xml> <username>admin</username> <password>123456</password> </xml>
GET方式
3、http://restful.wozsz.com/service/com.somnus.resource.RestfulResource/getAccount3/admin/123456
4、http://restful.wozsz.com/service/com.somnus.resource.RestfulResource/getAccount4?username=admin&password=123456
相关文章推荐
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- Hadoop初识--Hadoop单机模式安装和环境配置
- PAT1003.我要通过!(20)(简单的c语言风格c++解法)
- iOS个人整理39-cocoaPods的使用
- 在Eclipse环境下编写ABAP程序
- 网站的email地址
- ArcGIS Runtime SDK for iOS(三) --- Callout的自定义属性展示
- JavaSE学习小笔记(2)
- Training Deep Neural Networks
- CFA. Co-prime Array
- Android的.so文件、ABI和CPU的关系
- 汉诺塔
- android一些常用事件
- nginx 访问路径配置