背景
在java体系的应用中,需要调用一些外部的接口,http协议是一种常用的协议。基于springboot体系的工程与普通工程都是有这种需求的,基于这种背景,研究一下java发http请求是非常有必要的。基本就是四种套路:java原生(URLConnection系列),独立低封装度jar包(okhttp,httpclient等),spring自带(resttemplate),高封装度jar包(forest)。对这四种套路进行一波整理。
参考资料
https://www.jb51.net/article/206762.htm JAVA发送HTTP请求的四种方式总结(主要是原生+依赖) https://zhuanlan.zhihu.com/p/364017444 httpclient https://blog.csdn.net/itguangit/article/details/78825505 resttemplate http://forest.dtflyx.com/ forest官网 https://okhttps.ejlchina.com/ okhttp
案例与解决方案
java原生
使用JDK原生提供的net,无需其他jar包。HttpURLConnection是URLConnection的子类,提供更多的方法,使用更方便。
package httpURLConnection;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class HttpURLConnectionHelper {
public static String sendRequest(String urlParam,String requestType) {
HttpURLConnection con = null;
BufferedReader buffer = null;
StringBuffer resultBuffer = null;
try {
URL url = new URL(urlParam);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod(requestType);
con.setRequestProperty("Content-Type", "application/json;charset=GBK");
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
int responseCode = con.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
InputStream inputStream = con.getInputStream();
resultBuffer = new StringBuffer();
String line;
buffer = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
while ((line = buffer.readLine()) != null) {
resultBuffer.append(line);
}
return resultBuffer.toString();
}
}catch(Exception e) {
e.printStackTrace();
}
return "";
}
public static void main(String[] args) {
String url ="http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=120.79.75.96";
System.out.println(sendRequest(url,"POST"));
}
}
使用JDK原生提供的net,无需其他jar包。建议使用HttpURLConnection。
package uRLConnection;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
public class URLConnectionHelper {
public static String sendRequest(String urlParam) {
URLConnection con = null;
BufferedReader buffer = null;
StringBuffer resultBuffer = null;
try {
URL url = new URL(urlParam);
con = url.openConnection();
con.setRequestProperty("Content-Type", "application/json;charset=GBK");
con.setDoOutput(true);
con.setDoInput(true);
con.setUseCaches(false);
InputStream inputStream = con.getInputStream();
resultBuffer = new StringBuffer();
String line;
buffer = new BufferedReader(new InputStreamReader(inputStream, "GBK"));
while ((line = buffer.readLine()) != null) {
resultBuffer.append(line);
}
return resultBuffer.toString();
}catch(Exception e) {
e.printStackTrace();
}
return "";
}
public static void main(String[] args) {
String url ="http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=120.79.75.96";
System.out.println(sendRequest(url));
}
}
使用JDK原生提供的net,无需其他jar包,使用起来有点麻烦。
package socket;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.URLEncoder;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
public class SocketForHttpTest {
private int port;
private String host;
private Socket socket;
private BufferedReader bufferedReader;
private BufferedWriter bufferedWriter;
public SocketForHttpTest(String host,int port) throws Exception{
this.host = host;
this.port = port;
socket = (SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault()).createSocket(this.host, this.port);
}
public void sendGet() throws IOException{
String requestUrlPath = "/";
OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());
bufferedWriter = new BufferedWriter(streamWriter);
bufferedWriter.write("GET " + requestUrlPath + " HTTP/1.1\r\n");
bufferedWriter.write("Host: " + this.host + "\r\n");
bufferedWriter.write("\r\n");
bufferedWriter.flush();
BufferedInputStream streamReader = new BufferedInputStream(socket.getInputStream());
bufferedReader = new BufferedReader(new InputStreamReader(streamReader, "utf-8"));
String line = null;
while((line = bufferedReader.readLine())!= null){
System.out.println(line);
}
bufferedReader.close();
bufferedWriter.close();
socket.close();
}
public void sendPost() throws IOException{
String path = "/";
String data = URLEncoder.encode("name", "utf-8") + "=" + URLEncoder.encode("张三", "utf-8") + "&" +
URLEncoder.encode("age", "utf-8") + "=" + URLEncoder.encode("32", "utf-8");
System.out.println(">>>>>>>>>>>>>>>>>>>>>"+data);
OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream(), "utf-8");
bufferedWriter = new BufferedWriter(streamWriter);
bufferedWriter.write("POST " + path + " HTTP/1.1\r\n");
bufferedWriter.write("Host: " + this.host + "\r\n");
bufferedWriter.write("Content-Length: " + data.length() + "\r\n");
bufferedWriter.write("Content-Type: application/x-www-form-urlencoded\r\n");
bufferedWriter.write("\r\n");
bufferedWriter.write(data);
bufferedWriter.write("\r\n");
bufferedWriter.flush();
BufferedInputStream streamReader = new BufferedInputStream(socket.getInputStream());
bufferedReader = new BufferedReader(new InputStreamReader(streamReader, "utf-8"));
String line = null;
while((line = bufferedReader.readLine())!= null)
{
System.out.println(line);
}
bufferedReader.close();
bufferedWriter.close();
socket.close();
}
public static void main(String[] args) throws Exception {
SocketForHttpTest forHttpTest = new SocketForHttpTest("www.baidu.com", 443);
try {
forHttpTest.sendGet();
} catch (IOException e) {
e.printStackTrace();
}
}
}
独立jar包半原生
这部分主要针对的是httpclient,okhttp这种封装的还可以的jar包。
httpclient
导入依赖文件
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
使用jar的功能。
package httpClient;
import java.io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class HttpClientHelper {
public static String sendPost(String urlParam) throws HttpException, IOException {
HttpClient httpClient = new HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(15000);
PostMethod postMethod = new PostMethod(urlParam);
postMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 60000);
postMethod.addRequestHeader("Content-Type", "application/json");
httpClient.executeMethod(postMethod);
String result = postMethod.getResponseBodyAsString();
postMethod.releaseConnection();
return result;
}
public static String sendGet(String urlParam) throws HttpException, IOException {
HttpClient httpClient = new HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(15000);
GetMethod getMethod = new GetMethod(urlParam);
getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, 60000);
getMethod.addRequestHeader("Content-Type", "application/json");
httpClient.executeMethod(getMethod);
String result = getMethod.getResponseBodyAsString();
getMethod.releaseConnection();
return result;
}
public static void main(String[] args) throws HttpException, IOException {
String url ="http://int.dpool.sina.com.cn/iplookup/iplookup.php?ip=120.79.75.96";
System.out.println(sendPost(url));
System.out.println(sendGet(url));
}
}
okhttp
案例代码,直接看官网最好,使用过程十分优雅。
HTTP http = HTTP.builder()
.baseUrl("http://api.example.com")
.addMsgConvertor(new GsonMsgConvertor());
.build();
List<User> users = http.sync("/users")
.get()
.getBody()
.toList(User.class);
http.async("/users/1")
.setOnResponse((HttpResult res) -> {
User user = res.getBody().toBean(User.class);
})
.get();
独立jar包高度封装
这里指的是forest,官网地址,只需要声明接口,就可以使用。具体的使用方式看官网,案例十分详细,项目中我是采用这种方式的。
public interface MyClient {
@Request(url = "http://localhost:8080/hello")
String helloForest();
}
spring体系自带RestTemplate
@RequestMapping("get2/{id}")
public UserEntity getById(@PathVariable(name = "id") String id) {
UserEntity userEntity = restTemplate.getForObject("http://localhost/get/{id}", UserEntity.class, id);
return userEntity;
}
@RequestMapping("getForEntity/{id}")
public UserEntity getById2(@PathVariable(name = "id") String id) {
ResponseEntity<UserEntity> responseEntity = restTemplate.getForEntity("http://localhost/get/{id}", UserEntity.class, id);
UserEntity userEntity = responseEntity.getBody();
return userEntity;
}
这里只是举了两个例子,具体的学习,参看参考资料中的博客即可。
|