【網路】JAVA Socket 實現HTTP與HTTPS客戶端傳送POST與GET方式請求
JAVA Socket 實現HTTP與HTTPS客戶端傳送POST與GET方式請求
哇,一看標題怎麼這麼長啊,其實意思很簡單,哥討厭用HTTP Client做POST與GET提交
覺得那個畢竟是別人寫得API庫,所以我就自己實現了一個簡單的HTTP客戶端,支援POST
方式提交資料,GET方式查詢資料,是測試Restful API比較方便點,然後支援form與JSON兩
種方式提交資料,當然也支援返回資料為JSON格式.當然這些東西都是基於JAVA Socket直
接完成的,不借助任何第三方的庫,主要是JDK的API其實已經夠用啦. 當然我也沒有用
URLConnect這個東西,畢竟它在Socket基礎上又包裝了一下,有違我寫這篇文章的目的.
好啦,講完理由,下面就說說要怎麼樣才能實現啊,光說不練假把式啊!大致分了幾個步驟
一:當然是要知道HTTP協議,知道常用的HTTP請求頭,比如Host, Accept, Content-Type
知道HTTP協議支援的方法,常用有GET/POST/PUT/DELETE等
如果不知道,也不用擔心,我保證你讀完這篇文章,你就知道一些啦,當然有個最好的參考
文件就是HTTP相關的RFC文件,認真讀一下肯定解決你自己心中的HTTP那些疑惑
二: 知道傳送HTTP GET與POST格式很重要, 固定的格式如下:
[REQUEST]<SP><URL><SP>[HTTP VERSION]<CLRF>
[REQUEST HEADER: ]<SP>[VALUE]<CLRF>
可以有多個請求頭
最後<CLRF>
傳送完HTTP請求頭部以後, 針對不同請求如POST要傳送內容部分,傳送完成以後同樣
以<CLRF>結尾.
解釋: <SP>表示空格, <CLRF>表示回車換行JAVA中表示為”\r\n”
REQUEST表示HTTP請求命令,可以為POST, GET, PUT, DELETE等之一
HTTP VERSION的常見可能值為HTTP/1.1或者HTTP/1.0
三: 如果1與2的知識你都具備了,下面就來介紹一下JAVA Socket的相關知識
如何建立一個JAVA客戶端套接字Socket s = new Socket()如此即可,簡單吧!
如何連線到遠端的主機與埠, 當提供URL字串時候,可以這麼做
URL url = new URL(“http://blog.csdn.net/jia20003”);
String host = url.getHost;
int port = url.getDefaultPort();
SocketAddress dest = new InetSocketAddress(this.host, this.port);
s.connect(dest);
即可連線到遠端主機,下面就可以請求文章內容了, 也很容易的
[java] view plaincopyprint?- String path = "/jia20003/article/details/16908661";
- SocketAddress dest = new InetSocketAddress(this.host, this.port);
- socket.connect(dest);
- OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());
- bufferedWriter = new BufferedWriter(streamWriter);
- bufferedWriter.write("GET " + path + " HTTP/1.1\r\n");
- bufferedWriter.write("Host: " + this.host + "\r\n");
- bufferedWriter.write("\r\n");
- bufferedWriter.flush();
String path = "/jia20003/article/details/16908661";
SocketAddress dest = new InetSocketAddress(this.host, this.port);
socket.connect(dest);
OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());
bufferedWriter = new BufferedWriter(streamWriter);
bufferedWriter.write("GET " + path + " HTTP/1.1\r\n");
bufferedWriter.write("Host: " + this.host + "\r\n");
bufferedWriter.write("\r\n");
bufferedWriter.flush();
最後也是最重要的一點,字元編碼,儘量都用同一種字元編碼來發
送請求資料,推薦使用utf-8測試程式, 我寫兩個簡單的PHP檔案放
在wamp server上,完成對全部程式碼的測試
四:關於HTTP與HTTPS
HTTP協議是位於第四層協議TCP之上完成的應用層協議, 端到端都是明文傳送,別人一
旦網路抓包以後都可以看到你的提交與請求資料,這個好像不太安全. HTTP協議的預設
埠是80這個是RFC文件宣告的,屬於官方標準,沒什麼道理可以講.
HTTPS是基於SSL加密傳輸的,這樣別人截獲你的資料包破解的概率要小一點,比HTTP安
全一點,其預設埠是443, 好像QQ郵箱與谷歌的WEB Mail郵箱都是基於HTTPS. 但是
HTTPS通訊方式只是傳輸資料加密,都客戶端來說是透明的,它還是一樣要遵守HTTP協
議規範來發送POST與GET請求等.
完整的測試程式如下:
[java] view plaincopyprint?- package com.gloomyfish.http.client;
- 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.InetSocketAddress;
- import java.net.Socket;
- import java.net.SocketAddress;
- import java.net.URLEncoder;
- publicclass TestDemo {
- privateint port;
- private String host;
- private Socket socket;
- private BufferedReader bufferedReader;
- private BufferedWriter bufferedWriter;
- public TestDemo(String host, int port) {
- socket = new Socket();
- this.host = host;
- this.port = port;
- }
- publicvoid sendGet() throws IOException
- {
- String path = "/zhigang/getDemo.php";
- SocketAddress dest = new InetSocketAddress(this.host, this.port);
- socket.connect(dest);
- OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());
- bufferedWriter = new BufferedWriter(streamWriter);
- bufferedWriter.write("GET " + path + " 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();
- }
- publicvoid sendPost() throws IOException
- {
- String path = "/zhigang/postDemo.php";
- String data = URLEncoder.encode("name", "utf-8") + "=" + URLEncoder.encode("gloomyfish", "utf-8") + "&" +
- URLEncoder.encode("age", "utf-8") + "=" + URLEncoder.encode("32", "utf-8");
- // String data = "name=zhigang_jia";
- SocketAddress dest = new InetSocketAddress(this.host, this.port);
- socket.connect(dest);
- 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.flush();
- 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();
- }
- publicstaticvoid main(String[] args)
- {
- TestDemo td = new TestDemo("127.0.0.1",8099);
- try {
- // td.sendGet(); //send HTTP GET Request
- td.sendPost(); // send HTTP POST Request
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- <span style="font-size: 18px;">}</span>
package com.gloomyfish.http.client;
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.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.URLEncoder;
public class TestDemo {
private int port;
private String host;
private Socket socket;
private BufferedReader bufferedReader;
private BufferedWriter bufferedWriter;
public TestDemo(String host, int port) {
socket = new Socket();
this.host = host;
this.port = port;
}
public void sendGet() throws IOException
{
String path = "/zhigang/getDemo.php";
SocketAddress dest = new InetSocketAddress(this.host, this.port);
socket.connect(dest);
OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());
bufferedWriter = new BufferedWriter(streamWriter);
bufferedWriter.write("GET " + path + " 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 = "/zhigang/postDemo.php";
String data = URLEncoder.encode("name", "utf-8") + "=" + URLEncoder.encode("gloomyfish", "utf-8") + "&" +
URLEncoder.encode("age", "utf-8") + "=" + URLEncoder.encode("32", "utf-8");
// String data = "name=zhigang_jia";
SocketAddress dest = new InetSocketAddress(this.host, this.port);
socket.connect(dest);
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.flush();
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)
{
TestDemo td = new TestDemo("127.0.0.1",8099);
try {
// td.sendGet(); //send HTTP GET Request
td.sendPost(); // send HTTP POST Request
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
<span style="font-size:18px;">}</span>
想要成為支援HTTPS客戶端, 只要在建立Socket的時候如下:
[java] view plaincopyprint?- <span style="font-size: 18px;">socket = (SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault()).createSocket(this.host, port);</span>
<span style="font-size:18px;">socket = (SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault()).createSocket(this.host, port);</span>
所以有時候離開apache的HTTP Client等第三方Jar,程式設計師也是一樣活!