持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情
Java 实现 Http 访问
开发过程中需要调用http 访问第三方接口。
一般有如下方式:
- 通过JDK网络类Java.net.HttpURLConnection
- 通过common封装好的HttpClient;
- 通过Apache封装好的CloseableHttpClient;
一个http 调用过程一般如下:
get
1、创建远程连接
String path ="";//
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
2、设置连接方式(get、post、put。。。)
conn.setRequestMethod("GET"); //设置本次请求的方式 , 默认是GET方式, 参数要求都是大写字母
3、设置连接超时时间
conn.setConnectTimeout(5000);//设置连接超时
conn.setDoInput(true);//是否打开输入流 , 此方法默认为true
conn.setDoOutput(true);//是否打开输出流, 此方法默认为false
conn.connect();//表示连接
int code = conn.getResponseCode(); //可以用来判断是否连接成功
4、设置响应读取时间
5、发起请求
6、获取请求数据
InputStream is = conn.getInputStream();
String name = path.substring(path.lastIndexOf("/")+1);
System.out.println("name = " + name);
fos = new FileOutputStream("C:\\pro\\"+name);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer))!=-1) {
fos.write(buffer, 0, len);
]
7、关闭连接
Post 请求
1、创建远程连接
2、设置连接方式(get、post、put。。。)与 get 不一样的是设置 Post
3、设置连接超时时间
4、设置响应读取时间
5、当向远程服务器传送数据/写数据时,需要设置为true(setDoOutput)
6、当前向远程服务读取数据时,设置为true,该参数可有可无(setDoInput)
7、设置传入参数的格式:(setRequestProperty)
8、设置鉴权信息:Authorization:(setRequestProperty)
9、设置参数
10、发起请求
11、获取请求数据
12、关闭连接
JDK HttpURLConnection Get/Post完整的例子
public static String toUrl(String path, String method, String data) {
System.out.println(path);
System.out.println(data);
StringBuilder sb = new StringBuilder();
try {
URL url = new URL(path);
//打开和url之间的连接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
/**设置URLConnection的参数和普通的请求属性****start***/
//设置是否向httpUrlConnection输出,设置是否从httpUrlConnection读入,此外发送post请求必须设置这两个
conn.setDoOutput(true);
conn.setDoInput(true);
//GET和POST必须全大写
conn.setRequestMethod(method);
// 设置不用缓存
conn.setUseCaches(false);
conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
// 设置文件字符集:
conn.setRequestProperty("Charset", "UTF-8");
byte[] tmp = new byte[0];
if ("POST".equals(method) && data != null && data.length() > 0) {
//转换为字节数组
tmp = data.getBytes();
// 设置文件长度
conn.setRequestProperty("Content-Length", String.valueOf(tmp.length));
}
// 设置文件类型:
conn.setRequestProperty("contentType", "application/json");
/**设置URLConnection的参数和普通的请求属性****end***/
/**GET方法请求*****start*/
/**
* 如果只是发送GET方式请求,使用connet方法建立和远程资源之间的实际连接即可;
* 如果发送POST方式的请求,需要获取URLConnection实例对应的输出流来发送请求参数。
* */
conn.connect();
/**GET方法请求*****end*/
/***POST方法请求****start*/
if ("POST".equals(method) && data != null && data.length() > 0) {
//获取URLConnection对象对应的输出流
OutputStream out = conn.getOutputStream();
//发送请求参数即数据
out.write(tmp);
out.flush();
out.close();
}
/***POST方法请求****end*/
// 请求返回的状态
if (conn.getResponseCode() == 200) {
System.out.println("连接成功");
//获取URLConnection对象对应的输入流
InputStream is = conn.getInputStream();
//构造一个字符流缓存
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String str = "";
while ((str = br.readLine()) != null) {
//解决中文乱码问题
str = new String(str.getBytes(), "UTF-8");
sb.append(str);
System.out.println(str);
}
//关闭流
is.close();
}
//断开连接,最好写上,disconnect是在底层tcp socket链接空闲时才切断。如果正在被其他线程使用就不切断。
//固定多线程的话,如果不disconnect,链接会增多,直到收发不出信息。写上disconnect后正常一些。
conn.disconnect();
System.out.println("完整结束");
} catch (Exception e) {
e.printStackTrace();
}
return sb.toString();
}
通过Apache封装好的CloseableHttpClient;
完整代码示例:
import com.alibaba.druid.support.json.JSONUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.util.HashMap;
import java.util.Map;
/**
* HttpClient工具类
*/
public class HttpClientUtil {
/**请求编码*/
private static final String DEFAULT_CHARSET = "UTF-8";
/**
* 执行HTTP POST请求
* @param url url
* @param param 参数
* @return
*/
public static String httpPostWithJSON(String url, Map<String, ?> param) {
CloseableHttpClient client = null;
try {
if(url == null || url.trim().length() == 0){
throw new Exception("URL is null");
}
HttpPost httpPost = new HttpPost(url);
client = HttpClients.createDefault();
if(param != null){
StringEntity entity = new StringEntity(JSONUtils.toJSONString(param), DEFAULT_CHARSET);//解决中文乱码问题
entity.setContentEncoding(DEFAULT_CHARSET);
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
HttpResponse resp = client.execute(httpPost);
if(resp.getStatusLine().getStatusCode() == 200) {
return EntityUtils.toString(resp.getEntity(), DEFAULT_CHARSET);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(client);
}
return null;
}
/**
* 执行HTTP GET请求
* @param url url
* @param param 参数
* @return
*/
public static String httpGetWithJSON(String url, Map<String, ?> param) {
CloseableHttpClient client = null;
try {
if(url == null || url.trim().length() == 0){
throw new Exception("URL is null");
}
client = HttpClients.createDefault();
if(param != null){
StringBuffer sb = new StringBuffer("?");
for (String key : param.keySet()){
sb.append(key).append("=").append(param.get(key)).append("&");
}
url = url.concat(sb.toString());
url = url.substring(0, url.length()-1);
}
HttpGet httpGet = new HttpGet(url);
HttpResponse resp = client.execute(httpGet);
if(resp.getStatusLine().getStatusCode() == 200) {
return EntityUtils.toString(resp.getEntity(), DEFAULT_CHARSET);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
close(client);
}
return null;
}
/**
* 关闭HTTP请求
* @param client
*/
private static void close(CloseableHttpClient client){
if(client == null){
return;
}
try {
client.close();
} catch (Exception e) {
}
}
public static void main(String[] args) throws Exception {
Map param = new HashMap();
param.put("userName", "admin");
param.put("password", "mao2080");
String result = httpGetWithJSON("https://www.baidu.com/", param);
System.out.println("result:"+result);
}
}