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 plain copy 在CODE上查看代码片 派生到我的代码片
  1. String path = "/jia20003/article/details/16908661";  
  2. SocketAddress dest = new InetSocketAddress(this.host, this.port);  
  3. socket.connect(dest);  
  4. OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());  
  5. bufferedWriter = new BufferedWriter(streamWriter);  
  6. bufferedWriter.write("GET " + path + " HTTP/1.1\r\n");  
  7. bufferedWriter.write("Host: " + this.host + "\r\n");  
  8. bufferedWriter.write("\r\n");  
  9. 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 plain copy 在CODE上查看代码片 派生到我的代码片
  1. package com.gloomyfish.http.client;  
  2.   
  3. import java.io.BufferedInputStream;  
  4. import java.io.BufferedReader;  
  5. import java.io.BufferedWriter;  
  6. import java.io.IOException;  
  7. import java.io.InputStreamReader;  
  8. import java.io.OutputStreamWriter;  
  9. import java.net.InetSocketAddress;  
  10. import java.net.Socket;  
  11. import java.net.SocketAddress;  
  12. import java.net.URLEncoder;  
  13.   
  14. public class TestDemo {  
  15.     private int port;  
  16.     private String host;  
  17.     private Socket socket;  
  18.     private BufferedReader bufferedReader;  
  19.     private BufferedWriter bufferedWriter;  
  20.     public TestDemo(String host, int port) {  
  21.         socket = new Socket();  
  22.         this.host = host;  
  23.         this.port = port;  
  24.     }  
  25.       
  26.     public void sendGet() throws IOException  
  27.     {  
  28.         String path = "/zhigang/getDemo.php";  
  29.         SocketAddress dest = new InetSocketAddress(this.host, this.port);  
  30.         socket.connect(dest);  
  31.         OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream());  
  32.         bufferedWriter = new BufferedWriter(streamWriter);  
  33.           
  34.         bufferedWriter.write("GET " + path + " HTTP/1.1\r\n");  
  35.         bufferedWriter.write("Host: " + this.host + "\r\n");  
  36.         bufferedWriter.write("\r\n");  
  37.         bufferedWriter.flush();  
  38.           
  39.         BufferedInputStream streamReader = new BufferedInputStream(socket.getInputStream());  
  40.         bufferedReader = new BufferedReader(new InputStreamReader(streamReader, "utf-8"));  
  41.         String line = null;  
  42.         while((line = bufferedReader.readLine())!= null)  
  43.         {  
  44.             System.out.println(line);  
  45.         }  
  46.         bufferedReader.close();  
  47.         bufferedWriter.close();  
  48.         socket.close();  
  49.     }  
  50.       
  51.     public void sendPost() throws IOException  
  52.     {  
  53.         String path = "/zhigang/postDemo.php";  
  54.         String data = URLEncoder.encode("name""utf-8") + "=" + URLEncoder.encode("gloomyfish""utf-8") + "&" +  
  55.                         URLEncoder.encode("age""utf-8") + "=" + URLEncoder.encode("32""utf-8");  
  56.         // String data = "name=zhigang_jia";  
  57.         SocketAddress dest = new InetSocketAddress(this.host, this.port);  
  58.         socket.connect(dest);  
  59.         OutputStreamWriter streamWriter = new OutputStreamWriter(socket.getOutputStream(), "utf-8");  
  60.         bufferedWriter = new BufferedWriter(streamWriter);  
  61.           
  62.         bufferedWriter.write("POST " + path + " HTTP/1.1\r\n");  
  63.         bufferedWriter.write("Host: " + this.host + "\r\n");  
  64.         bufferedWriter.write("Content-Length: " + data.length() + "\r\n");  
  65.         bufferedWriter.write("Content-Type: application/x-www-form-urlencoded\r\n");  
  66.         bufferedWriter.write("\r\n");  
  67.         bufferedWriter.write(data);  
  68.         bufferedWriter.flush();  
  69.         bufferedWriter.write("\r\n");  
  70.         bufferedWriter.flush();  
  71.           
  72.         BufferedInputStream streamReader = new BufferedInputStream(socket.getInputStream());  
  73.         bufferedReader = new BufferedReader(new InputStreamReader(streamReader, "utf-8"));  
  74.         String line = null;  
  75.         while((line = bufferedReader.readLine())!= null)  
  76.         {  
  77.             System.out.println(line);  
  78.         }  
  79.         bufferedReader.close();  
  80.         bufferedWriter.close();  
  81.         socket.close();  
  82.     }  
  83.       
  84.     public static void main(String[] args)  
  85.     {  
  86.         TestDemo td = new TestDemo("127.0.0.1",8099);  
  87.         try {  
  88.             // td.sendGet(); //send HTTP GET Request  
  89.               
  90.             td.sendPost(); // send HTTP POST Request  
  91.         } catch (IOException e) {  
  92.             // TODO Auto-generated catch block  
  93.             e.printStackTrace();  
  94.         }  
  95.     }  
  96.   
  97. <span style="font-size:18px;">}</span>  
想要成为支持HTTPS客户端, 只要在创建Socket的时候如下:
[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="font-size:18px;">socket = (SSLSocket)((SSLSocketFactory)SSLSocketFactory.getDefault()).createSocket(this.host, port);</span>  
所以有时候离开apache的HTTP Client等第三方Jar,程序员也是一样活!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是用 Java 实现一个简单的 HTTP 服务器端,可以接收客户端的 GET 和 POST 请求的代码示例: ```java import java.io.*; import java.net.*; public class HTTPServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(8080); // 创建一个服务器端的Socket对象,监听端口号为8080 System.out.println("Server is listening on port 8080..."); while (true) { Socket clientSocket = serverSocket.accept(); // 接收客户端请求 System.out.println("A new client is connected : " + clientSocket); // 读取客户端发送HTTP请求数据 BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { if (inputLine.isEmpty()) break; // 当读取到空行时,表示HTTP请求头已经读取完毕 System.out.println(inputLine); } // 响应客户端请求 PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); out.println("HTTP/1.1 200 OK"); out.println("Content-Type: text/html"); out.println("\r\n"); out.println("<h1>Hello World!</h1>"); // 关闭流和Socket对象 in.close(); out.close(); clientSocket.close(); } } catch (IOException e) { e.printStackTrace(); } } } ``` 上面的代码会创建一个服务器端的 Socket 对象,监听端口号为 8080,然后通过 `accept()` 方法接收客户端的连接请求。当客户端连接成功后,服务器端会读取客户端发送HTTP 请求头数据,然后响应客户端请求,最后关闭连接。 如果客户端发送的是 GET 请求,那么请求数据会包含在 HTTP 请求头的第一行中,例如: ``` GET / HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1 ``` 如果客户端发送的是 POST 请求,那么请求数据会包含在 HTTP 请求头的第二行后面,例如: ``` POST / HTTP/1.1 Host: localhost:8080 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 13 Connection: keep-alive Upgrade-Insecure-Requests: 1 username=admin&password=123456 ``` 在上面的代码示例中,服务器端只是简单地响应客户端请求,返回一个固定的字符串。如果需要根据客户端请求动态生成响应数据,可以在响应的代码中编写相应的逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值