java 发送 http 请求练习两年半(HttpURLConnection)
Posted 64gdrifbottle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 发送 http 请求练习两年半(HttpURLConnection)相关的知识,希望对你有一定的参考价值。
1、起一个 springboot 程序做 http 测试:
@GetMapping("/http/get") public ResponseEntity<String> testHttpGet(@RequestParam("param") String param) System.out.println(param); return ResponseEntity.ok("---------> revive http get request --------->"); @PostMapping("/http/post") public ResponseEntity<String> testHttpPost(@RequestBody List<Object> body) System.out.println(body); return ResponseEntity.ok("---------> receive http post request --------->");
2、写一个 HttpURLConnection 自定义客户端
import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ConnectException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Map; public class MyHttpClient private final HttpURLConnection connection; private MyHttpClient(String url, Map<String, String> params) throws IOException connection = buildConnection(url, params); private MyHttpClient(String url, Map<String, String> params, String jsonBody) throws IOException connection = buildConnection(url, params); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json;charset=utf-8"); connection.setDoOutput(true); try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) outputStream.writeBytes(jsonBody); outputStream.flush(); public static MyHttpClient get(String url, Map<String, String> params) throws IOException return new MyHttpClient(url, params); public static MyHttpClient post(String url, Map<String, String> params, String jsonBody) throws IOException return new MyHttpClient(url, params, jsonBody); /** * 创建 http 连接 * * @param url 请求路径 * @param params 请求参数,可以为空 * @return http 连接 */ private HttpURLConnection buildConnection(String url, Map<String, String> params) throws IOException String requestParams = getParamsString(params); return (HttpURLConnection) new URL(requestParams != null ? url + "?" + requestParams : url).openConnection(); /** * 获取 http 请求响应结果 * * @return 响应结果,失败抛异常 */ public String getResponse() throws IOException int responseCode = connection.getResponseCode(); if (responseCode >= HttpURLConnection.HTTP_OK && responseCode < HttpURLConnection.HTTP_MULT_CHOICE) BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String inputLine; StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) response.append(inputLine); in.close(); connection.disconnect(); return response.toString(); else connection.disconnect(); InputStream errorStream = connection.getErrorStream(); if (errorStream == null) throw new ConnectException("request fail"); throw new ConnectException(new String(errorStream.readAllBytes(), StandardCharsets.UTF_8)); /** * 拼接请求参数 * * @param params 参数 map * @return 请求参数字符串 */ public static String getParamsString(Map<String, String> params) if (params == null || params.isEmpty()) return null; StringBuilder result = new StringBuilder(); for (Map.Entry<String, String> entry : params.entrySet()) result.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8)); result.append("="); result.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8)); result.append("&"); String resultString = result.toString(); return resultString.length() > 0 ? resultString.substring(0, resultString.length() - 1) : resultString;
3、测试 get 和 post 请求
public static void main(String[] args) throws IOException MyHttpClient myHttpClient = MyHttpClient.get("http://127.0.0.1:8083/springboot/http/get", Map.of("param", "1")); String resultGet = myHttpClient.getResponse(); System.out.println(resultGet); MyHttpClient httpClient = MyHttpClient.post("http://127.0.0.1:8083/springboot/http/post", null, "[1,2,3,4,5]"); String resultPost = httpClient.getResponse(); System.out.println(resultPost);
4、控制台输出结果
---------> revive http get request --------->
---------> receive http post request --------->
Process finished with exit code 0
中间遇到一些坑,经常以为 http 会有方法像 openfeign 那样传入请求参数,忽略了路径拼接,
启动的 springboot 接收的 post 的请求体为 List 类型,且 Content-Type 是 json,在测试 post 请求时一直报错,看了 spring 控制台才发现 json 转对象封装 没对上。
http
1.将表格中的数据动态加入表格中,js脚本中拼接了css,html,script,练习
1 const http = require("http"); 2 const urlTool = require("url");
//1,浏览器向node服务发送了一个请求,返回了一个表格的html
//2.然后在想浏览器发送一个css.java的请求,返回css,
//3.浏览器对不标准的html也会解析
3 4 5 const server = http.createServer((request, response)=>{ 6 //获取参数 7 let method = request.method.toUpperCase(); 8 let pathname = urlTool.parse(request.url).pathname; 9 //检测路径 10 if(method === ‘GET‘ && pathname === ‘/users‘){ //如果报文路径和文件路径没关联,可以自定义url 11 //1. 乱码问题 12 response.setHeader("content-type",‘text/html;charset=utf-8‘); 13 const arr = [ 14 {name: ‘knight‘, age: 18}, 15 {name: ‘xiaoming‘, age: 20}, 16 {name: ‘xiaoning‘, age: 28}, 17 {name: ‘xiaotian‘, age: 18}, 18 {name: ‘xiaohigh‘, age: 20}, 19 ]; 20 //返回一个表格 21 let str = ` 22 <link rel="stylesheet" href="/css.java"> 23 <script src="/app.js"></script> 24 <table border="1"><tr><td>姓名</td> <td>年龄</td></tr>`; 25 for(let i=0;i<arr.length;i++){ 26 str += `<tr><td>${arr[i].name}</td><td>${arr[i].age}</td></tr>`; 27 } 28 str += `</table>`; 29 30 response.end(str); 31 }else if(method === ‘GET‘ && pathname === ‘/css.java‘){ 32 response.end(` 33 body{ 34 background:pink; 35 } 36 `); 37 }else{ 38 response.end("OK"); 39 } 40 }); 41 42 server.listen(8000, ()=>{ 43 console.log(‘server is running.. 8000 端口监听......‘); 44 })
二,登录表单,服务响应练习
表单
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>登录</title> 8 <link href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"> 9 </head> 10 11 <body> 12 <div class="container"> 13 <div class="col-xs-4 col-xs-offset-4"> 14 <h2 class="page-header">用户登录</h2> 15 <form method="POST" action="/login"> 16 <div class="form-group"> 17 <label for="exampleInputEmail1">用户名</label> 18 <input type="text" class="form-control" name="username"> 19 </div> 20 <div class="form-group"> 21 <label for="exampleInputPassword1">密码</label> 22 <input type="password" class="form-control" name="password"> 23 </div> 24 <hr> 25 <button type="submit" class="btn btn-primary btn-block">登录</button> 26 </form> 27 </div> 28 </div> 29 </body> 30 31 </html>
js脚本
1 const http = require(‘http‘); 2 const urlTool = require("url"); 3 const fs = require(‘fs‘); 4 const qs = require(‘querystring‘); 5 //1.浏览器想发送一个get,/login的请求,然后node服务器返回一个login.html(一个表单)给浏览器 6 // 2.然后浏览器将表单内容填写了,发送了post,/login的请求,服务器返回了请求体的数据 7 8 9 // function getClientIp(req) { 10 // return req.headers[‘x-forwarded-for‘] || // 判断是否有反向代理 IP 11 // req.connection.remoteAddress || // 判断 connection 的远程 IP 12 // req.socket.remoteAddress || // 判断后端的 socket 的 IP 13 // req.connection.socket.remoteAddress; 14 // } 15 16 17 const server = http.createServer((request, response) => { 18 //获取 方法和路径 19 let method = request.method.toUpperCase(); 20 let pathname = urlTool.parse(request.url).pathname; 21 //如果 GET /login 则返回一个表单页面 22 if (method === ‘GET‘ && pathname === ‘/login‘) { 23 fs.readFile(__dirname + ‘/login.html‘, (err, data) => { 24 response.end(data); 25 }); 26 // POST /login 处理表单的数据 27 } else if (method === ‘POST‘ && pathname === ‘/login‘) { 28 //请求体数据提取 29 //1. 声明变量 30 let body = ‘‘; 31 //2. 绑定 data 事件 32 request.on(‘data‘, chunk => { 33 body += chunk; 34 }) 35 //3. 绑定 end 事件 36 request.on(‘end‘, () => { 37 console.log(body); 38 //将请求体的字符串形式 转为对象形式 39 let data = qs.parse(body); 40 // fs.writeFile("./access.log", body + ‘--ip:‘+ getClientIp(request)+‘ ‘, (err) => { 41 // console.log(data); 42 // response.end(body); 43 // }) 44 45 console.log(data); 46 response.end(body); 47 48 }) 49 }else { 50 response.end("404"); 51 } 52 }); 53 54 server.listen(80, () => { 55 console.log("服务已经启动, 80 端口监听中...."); 56 })
以上是关于java 发送 http 请求练习两年半(HttpURLConnection)的主要内容,如果未能解决你的问题,请参考以下文章