在 Java 不依赖第三方实现 HTTP GET 和 POST 请求 ( 一 ) 章节中,我们使用 java.net
和 java.io
包完成了一个 GET 请求,没做之前想起来是不是很复杂,实际动手写了之后才发现很简单
上一章节鉴于篇幅,我们并没有完成 HTTP POST 请求的实现,本章节,我们就把剩余的 MyPOSTRequest()
代码补起来
HTTP POST 请求 vs HTTP GET 请求
既然我们已经实现了 HTTP GET 请求,我们只要依葫芦画瓢实现 HTTP POST 请求就好了,的确,也可以这样,而且 java.net
包也是这么个逻辑
但,再次之前,我们必须了解 HTTP GET 请求和 HTTP POST 请求的区别,注意,我们说的是 HTTP 方面
- GET 请求的请求方法是
GET
、POST 的请求方法是POST
- 这是最大的差别了,也是唯一可以说的差别 - GET 和 POST 请求都可以把请求参数放到 URL 中,但是大小受 URL 大小限制,而 POST 请求还可以把请求参数放到请求正文中
除此意外,看看还有啥差别 ? 没有了... HTTP 方面就这些了,至于缓存之类的,都是浏览器中的 GET 请求和 POST 请求的差别,而幂等非幂是服务器段处理 HTTP 请求的差别
java.net 包实现 HTTP POST 请求的一般流程
既然知道了 HTTP GET 请求和 POST 请求的一般区别,我们就可以画出 HTTP POST 请求的一般流程了
- 使用
java.net.URL
类创建一个URL
类的实例urlForGetRequest
,参数为要请求的网址 - 调用
URL
实例的openConnection()
方法打开一个到远程服务器的连接conection
- 然后对连接
conection
设置一些属性,比如调用setRequestMethod()
设置请求方法,调用setRequestProperty()
添加一些查询参数 - 调用连接的
setDoOutput(true)
方法设置该请求有请求正文 - 接着调用连接的
getOutputStream()
方法打开正文输出流os
- 之后调用
os.write()
写入输出数据,调用os.flush()
刷新输出缓存和调用os.close()
关闭输出流 - 设置完了属性之后,就可以调用连接的
getResponseCode()
发起请求并返回请求的响应状态码 - 判断返回的响应状态吗,如果为
200
则表示成功,然后就可以调用连接的getInputStream()
获取输入流 - 有了输入流之后,就可以使用
java.io
包中的相关类读取响应的数据 - 其它的对响应数据的处理逻辑
可以看到,与 HTTP GET 请求不同的是,HTTP POST 请求添加了 4
、 5
、 6
三步
MyPOSTRequest()
接下来我们将完善 MyPOSTRequest()
方法向 https://jsonplaceholder.typicode.com/posts
提交一个帖子
帖子的内容是 JSON 格式,数据为
{ "userId": 101, "id": 101, "title": "Test Title", "body": "Test Body" }
MyPOSTRequest()
的全部代码如下
public static void MyPOSTRequest() throws IOException { // 要提交的数据 final String POST_PARAMS = "{\n" + "\"userId\": 101,\r\n" + " \"id\": 101,\r\n" + " \"title\": \"Test Title\",\r\n" + " \"body\": \"Test Body\"" + "\n}"; System.out.println(POST_PARAMS); // 1. 创建 URL 实例 URL obj = new URL("https://jsonplaceholder.typicode.com/posts"); // 2. 打开到远程服务器的连接 HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection(); // 3. 设置一些属性,比如设置请求方法和请求参数 postConnection.setRequestMethod("POST"); postConnection.setRequestProperty("userId", "a1bcdefgh"); // 因为提交的是 JSON 数据,所以需要设置请求类型 postConnection.setRequestProperty("Content-Type", "application/json"); // 4. 设置该请求有请求正文 postConnection.setDoOutput(true); // 5. 打开请求正文输出流 OutputStream os = postConnection.getOutputStream(); // 6. 写入输出数据,刷新缓存,关闭输出流 os.write(POST_PARAMS.getBytes()); os.flush(); os.close(); // 7. 发起请求并获取请求响应状态码 int responseCode = postConnection.getResponseCode(); System.out.println("POST Response Code : " + responseCode); System.out.println("POST Response Message : " + postConnection.getResponseMessage()); // 8. 判断请求状态响应码,如果为 201 则表示成功创建,因为服务器返回 201 ,其实返回 200 也是可以的 if (responseCode == HttpURLConnection.HTTP_CREATED) { //success BufferedReader in = new BufferedReader(new InputStreamReader( postConnection.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); // 9. 对响应数据的处理 while ((inputLine = in .readLine()) != null) { response.append(inputLine); } in .close(); // print result System.out.println(response.toString()); } else { System.out.println("POST NOT WORKED"); } }
然后我们使用 javac GetAndPost.java && java GetAndPost
输出结果如下
$ javac GetAndPost.java && java GetAndPost JSON String Result { "userId": 1, "id": 1, "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"} { "userId": 101, "id": 101, "title": "Test Title", "body": "Test Body" } POST Response Code : 201 POST Response Message : Created { "userId": 101, "id": 101, "title": "Test Title", "body": "Test Body"}
是不是很简单,最后附上完成后的所有源代码
import java.io.*; import java.net.*; public class GetAndPost { public static void MyGETRequest() throws IOException { // 1. 创建 URL 实例 URL urlForGetRequest = new URL("https://jsonplaceholder.typicode.com/posts/1"); String readLine = null; // 2. 打开到远程服务器的连接 HttpURLConnection conection = (HttpURLConnection) urlForGetRequest.openConnection(); // 3. 设置连接属性,比如请求方法和请求参数 conection.setRequestMethod("GET"); conection.setRequestProperty("userId", "a1bcdef"); // set userId its a sample here // 4. 发起请求并获取响应的状态码 int responseCode = conection.getResponseCode(); // 5. 根据状态码作出一些判断,如果为 200 则表示成功 if (responseCode == HttpURLConnection.HTTP_OK) { // 6. 使用 getInputStream() 获取输入流并读取输入流里的数据 BufferedReader in = new BufferedReader( new InputStreamReader(conection.getInputStream())); // 7. 其它处理逻辑,这里直接输出响应的数据 StringBuffer response = new StringBuffer(); while ((readLine = in .readLine()) != null) { response.append(readLine); } in.close(); System.out.println("JSON String Result " + response.toString()); } else { System.out.println("GET NOT WORKED"); } } public static void MyPOSTRequest() throws IOException { // 要提交的数据 final String POST_PARAMS = "{\n" + "\"userId\": 101,\r\n" + " \"id\": 101,\r\n" + " \"title\": \"Test Title\",\r\n" + " \"body\": \"Test Body\"" + "\n}"; System.out.println(POST_PARAMS); // 1. 创建 URL 实例 URL obj = new URL("https://jsonplaceholder.typicode.com/posts"); // 2. 打开到远程服务器的连接 HttpURLConnection postConnection = (HttpURLConnection) obj.openConnection(); // 3. 设置一些属性,比如设置请求方法和请求参数 postConnection.setRequestMethod("POST"); postConnection.setRequestProperty("userId", "a1bcdefgh"); // 因为提交的是 JSON 数据,所以需要设置请求类型 postConnection.setRequestProperty("Content-Type", "application/json"); // 4. 设置该请求有请求正文 postConnection.setDoOutput(true); // 5. 打开请求正文输出流 OutputStream os = postConnection.getOutputStream(); // 6. 写入输出数据,刷新缓存,关闭输出流 os.write(POST_PARAMS.getBytes()); os.flush(); os.close(); // 7. 发起请求并获取请求响应状态码 int responseCode = postConnection.getResponseCode(); System.out.println("POST Response Code : " + responseCode); System.out.println("POST Response Message : " + postConnection.getResponseMessage()); // 8. 判断请求状态响应码,如果为 201 则表示成功创建,因为服务器返回 201 ,其实返回 200 也是可以的 if (responseCode == HttpURLConnection.HTTP_CREATED) { //success BufferedReader in = new BufferedReader(new InputStreamReader( postConnection.getInputStream())); String inputLine; StringBuffer response = new StringBuffer(); // 9. 对响应数据的处理 while ((inputLine = in .readLine()) != null) { response.append(inputLine); } in .close(); // print result System.out.println(response.toString()); } else { System.out.println("POST NOT WORKED"); } } public static void main(String[] args) { try { GetAndPost.MyGETRequest(); // 用于实现 GET 请求 GetAndPost.MyPOSTRequest(); // 用于实现 POST 请求 } catch ( IOException e ) { System.out.println(e); } } }