这篇文章主要是用来总结自己写代码以来,使用java http客户端的历程,从最开始的原生方式到
httpclient4再到okhttp到现在的unirest,在此只是记录一些demo,没有按使用习惯进行封装。
方式一:首先来的是原生的方式,这种调用方式不需要引用其他的jar包。
可以看得出这种调用方式非常传统,连参数都要自己x=x&y=y这种方式来拼字符串传入。
package httptest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.Map;
/**
*/
public class HttpConnectRequest {
/**
* 向指定URL发送GET方法的请求
*
* @param url
* 发送请求的URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return URL 所代表远程资源的响应结果
*/
public static String sendGet(String url, String param) {
String result = "";
BufferedReader in = null;
try {
String urlNameString = url + "?" + param;
URL realUrl = new URL(urlNameString);
// 打开和URL之间的连接
URLConnection connection = realUrl.openConnection();
// 设置通用的请求属性
connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 建立实际的连接
connection.connect();
// 获取所有响应头字段
Map<String, List<String>> map = connection.getHeaderFields();
// 遍历所有的响应头字段
for (String key : map.keySet()) {
System.out.println(key + "--->" + map.get(key));
}
// 定义 BufferedReader输入流来读取URL的响应
in = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送GET请求出现异常!" + e);
e.printStackTrace();
}
// 使用finally块来关闭输入流
finally {
try {
if (in != null) {
in.close();
}
} catch (Exception e2) {
e2.printStackTrace();
}
}
return result;
}
/**
* 向指定 URL 发送POST方法的请求
*
* @param url
* 发送请求的 URL
* @param param
* 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
* @return 所代表远程资源的响应结果
*/
public static String sendPost(String url, String param) {
PrintWriter out = null;
BufferedReader in = null;
String result = "";
try {
URL realUrl = new URL(url);
// 打开和URL之间的连接
URLConnection conn = realUrl.openConnection();
// 设置通用的请求属性
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
// 发送POST请求必须设置如下两行
conn.setDoOutput(true);
conn.setDoInput(true);
// 获取URLConnection对象对应的输出流
out = new PrintWriter(conn.getOutputStream());
// 发送请求参数
out.print(param);
// flush输出流的缓冲
out.flush();
// 定义BufferedReader输入流来读取URL的响应
in = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
System.out.println("发送 POST 请求出现异常!"+e);
e.printStackTrace();
}
//使用finally块来关闭输出流、输入流
finally{
try{
if(out!=null){
out.close();
}
if(in!=null){
in.close();
}
}
catch(IOException ex){
ex.printStackTrace();
}
}
return result;
}
public static void main(String[] args) {
//发送 GET 请求
String s=sendGet("http://localhost/getReq", "key=123&v=456");
System.out.println(s);
//发送 POST 请求
String sr=sendPost("http://localhost/postReq", "key=123&v=456");
System.out.println(sr);
}
}
方式二:用httpclient4进行http请求,这个需要引入相应的jar包,同时封装度较低,但是代码结构清晰。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
package httptest;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
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.DefaultHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class HttpClientRequest {
/**
* 发送Get请求
* @param url
* @param params
* @return
*/
public static String get(String url, List<NameValuePair> params) {
HttpClient httpClient = HttpClients.createDefault();
String body = null;
try {
// Get请求
HttpGet httpget = new HttpGet(url);
// 设置参数
String str = EntityUtils.toString(new UrlEncodedFormEntity(params));
httpget.setURI(new URI(httpget.getURI().toString() + "?" + str));
// 发送请求
HttpResponse httpresponse = httpClient.execute(httpget);
// 获取返回数据
HttpEntity entity = httpresponse.getEntity();
body = EntityUtils.toString(entity);
if (entity != null) {
entity.consumeContent();
}
} catch (ParseException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (URISyntaxException e) {
e.printStackTrace();
}
return body;
}
/**
* 发送 Post请求
* @param url
* @param reqXml
* @return
*/
public static String post(String url, String reqXml) {
HttpClient httpClient = HttpClients.createDefault();
String body = null;
try {
httpClient.getParams().setParameter("http.protocol.content-charset",HTTP.UTF_8);
httpClient.getParams().setParameter(HTTP.CONTENT_ENCODING, HTTP.UTF_8);
httpClient.getParams().setParameter(HTTP.CHARSET_PARAM, HTTP.UTF_8);
httpClient.getParams().setParameter(HTTP.DEFAULT_PROTOCOL_CHARSET,HTTP.UTF_8);
// Post请求
HttpPost httppost = new HttpPost(url);
//设置post编码
httppost.getParams().setParameter("http.protocol.content-charset",HTTP.UTF_8);
httppost.getParams().setParameter(HTTP.CONTENT_ENCODING, HTTP.UTF_8);
httppost.getParams().setParameter(HTTP.CHARSET_PARAM, HTTP.UTF_8);
httppost.getParams().setParameter(HTTP.DEFAULT_PROTOCOL_CHARSET, HTTP.UTF_8);
// 设置参数
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("$xmldata", reqXml));
httppost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
StringEntity entity1 = new StringEntity(getUTF8XMLString(reqXml), "UTF-8");
entity1.setContentType("text/xml;charset=UTF-8");
entity1.setContentEncoding("UTF-8");
httppost.setEntity(entity1);
//设置报文头
httppost.setHeader("Content-Type", "text/xml;charset=UTF-8");
// 发送请求
HttpResponse httpresponse = httpClient.execute(httppost);
// 获取返回数据
HttpEntity entity = httpresponse.getEntity();
body = EntityUtils.toString(entity);
if (entity != null) {
entity.consumeContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return body;
}
}
方式三:使用okhttp进行调用,这个是目前比较流行的库,特别是在移动端,因为其常用的方式一般是回调,这种比较适合UI类程序用于触发响应。
在代码中展示了同步和异步两种调用方式。
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.6.0</version>
</dependency>
package httptest;
import okhttp3.*;
import java.io.IOException;
/**
* Created by lsz on 2017/2/26.
*/
public class OkhttpReqest {
public static void testGet(){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://baidu.com").build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
System.out.println("This is Error resp!");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
System.out.println(response.body().string());
}
});
}
public static void testPost() throws IOException {
String url = "http://baidu.com";
OkHttpClient client = new OkHttpClient();
//表单数据
FormBody.Builder builder = new FormBody.Builder();
builder.add("xwdoor","xwdoor");
RequestBody formBody = builder.build();
Request request = new Request.Builder()
.url(url)
.post(formBody)
.build();
Response response = client.newCall(request).execute();
if(response.isSuccessful())
{
String str = response.body().string();
System.out.println("服务器响应为: " + str);
}else {
System.out.println("服务器访问错误");
System.out.println(response.body().string());
}
}
public static void main(String[] args) throws IOException {
testGet();
testPost();
}
}
方式四:unirest,是一个比较少见的类库,它是对httpclient4的一层封装,调用方式跟okhttp差不多。
unirest从它的名字,可以看得出,专门为了rest服务调用而生的。
它的一大特点是提供了,多种语言同样的调用语义。
node/python/java/c#/ruby/oc这些常用语言都有名为unirest的库,调用语义都大同小异。
另一大特点是直接集成了对json序列化和反序列化的支持,可以对json结果直接解析出对象或者是返回可操作的json对象。
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>
//get
HttpResponse<Book> bookResponse = Unirest.get("http://httpbin.org/books/1").asObject(Book.class);
Book bookObject = bookResponse.getBody();
//post
HttpResponse<JsonNode> jsonResponse = Unirest.post("http://httpbin.org/post")
.header("accept", "application/json")
.queryString("apiKey", "123")
.field("parameter", "value")
.field("foo", "bar")
.asJson();
方式五:使用hutool 进行http请求。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.5.2</version>
</dependency>
//GET请求
// 最简单的HTTP请求,可以自动通过header等信息判断编码,不区分HTTP和HTTPS
String result1= HttpUtil.get("https://www.baidu.com");
// 当无法识别页面编码的时候,可以自定义请求页面的编码
String result2= HttpUtil.get("https://www.baidu.com", CharsetUtil.CHARSET_UTF_8);
//可以单独传入http参数,这样参数会自动做URL编码,拼接在URL中
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
String result3= HttpUtil.get("https://www.baidu.com", paramMap);
//POST form表单请求
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
//链式构建请求
String result2 = HttpRequest.post(url)
.header(Header.USER_AGENT, "Hutool http")//头信息,多个头信息多次调用此方法即可
.form(paramMap)//表单内容
.timeout(20000)//超时,毫秒
.execute().body();
//POST RequestBody请求
String json = "{}";
String result2 = HttpRequest.post(url)
.body(json)
.execute().body();
本文基本是拿来主义,算是给自己做个笔记吧。记录下自己用过的client库。