通信协议 协议: 规范
协议的写法
简单协议的写法:
协议名称://主机:端口/资源/子资源?key1=value1&key2=value2
复杂协议的写法
主协议名称:子协议名称://主机:端口/资源/子资源?key1=value1&key2=value2
http://baidu.com:80/index.html
获取服务器数据的方式
同步获取数据: 页面有刷新,浏览器的地址栏会发生改变,用户体验不好
异步获取数据: 实现页面的局部更新,浏览器的地址栏不发生改变,用户体验很好,也是现在主流的请求数据的方式;一般我们使用ajax进行异步数据的获取
jdbc java database connection
使用jdbc连接数据库
java中的类库
jdbc进行CURD 添加数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.xzy;import java.sql.Connection;import java.sql.DriverManager;import java.sql.Statement;public class Ops1 { public static void main (String[] args) throws Exception { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/youdian?serverTimezone=Asia/Shanghai" ; String username = "root" ; String password = "root" ; Connection conn = DriverManager.getConnection(url, username, password); String sql = "insert into city(name,pid)values('庆阳市',2)" ; Statement statement = conn.createStatement(); int rows = statement.executeUpdate(sql); if (rows > 0 ) { System.out.println("添加数据成功" ); } statement.close(); conn.close(); } }
修改数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.xzy;import java.sql.Connection;import java.sql.DriverManager;import java.sql.Statement;public class Ops2 { public static void main (String[] args) throws Exception { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/youdian?serverTimezone=Asia/Shanghai" ; String username = "root" ; String password = "root" ; Connection conn = DriverManager.getConnection(url, username, password); String sql = "update city set name='庆阳市1' where id=204" ; Statement statement = conn.createStatement(); int rows = statement.executeUpdate(sql); if (rows > 0 ) { System.out.println("数据修改成功" ); } statement.close(); conn.close(); } }
删除数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package com.xzy;import java.sql.Connection;import java.sql.DriverManager;import java.sql.Statement;public class Ops3 { public static void main (String[] args) throws Exception { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/youdian?serverTimezone=Asia/Shanghai" ; String username = "root" ; String password = "root" ; Connection conn = DriverManager.getConnection(url, username, password); String sql = "delete from city where id=204" ; Statement statement = conn.createStatement(); int rows = statement.executeUpdate(sql); if (rows > 0 ) { System.out.println("数据删除改成功" ); } statement.close(); conn.close(); } }
查询数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 package com.xzy;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;public class Ops4 { public static void main (String[] args) throws Exception { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/youdian?serverTimezone=Asia/Shanghai" ; String username = "root" ; String password = "root" ; Connection conn = DriverManager.getConnection(url, username, password); String sql = "select * from city" ; Statement statement = conn.createStatement(); ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()) { System.out.println(resultSet.getInt("id" )); System.out.println(resultSet.getString("name" )); } resultSet.close(); statement.close(); conn.close(); } }
jdbc中的sql注入问题 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.xzy;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;public class Ops5 { public static void main (String[] args) throws Exception { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/youdian?serverTimezone=Asia/Shanghai" ; Connection conn = DriverManager.getConnection(url, "root" , "root" ); String username = "admin11111 ' or 1=1 -- " ; String password = "admin1231" ; Statement statement = conn.createStatement(); String sql = "select * from user where username='" + username + "' and password='" + password + "'" ; ResultSet resultSet = statement.executeQuery(sql); if (resultSet.next()) { System.out.println("登录成功" ); } else { System.out.println("登录失败" ); } } }
以上的sql在执行过程中存在很大的问题,sql注入问题;
解决sql注入问题 1 conn.createStatement();这种方式创建的statement都是存在sql注入问题,不建议使用
使用 ?
作为sql语句的占位符,结合PreparedStatement
来解决sql注入的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 package com.xzy;import java.sql.*;public class Ops5 { public static void main (String[] args) throws Exception { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/youdian?serverTimezone=Asia/Shanghai" ; Connection conn = DriverManager.getConnection(url, "root" , "root" ); String username = "admin" ; String password = "admin123" ; String sql = "select * from user where username=? and password=?" ; PreparedStatement statement = conn.prepareStatement(sql); statement.setString(1 ,username); statement.setString(2 ,password); ResultSet resultSet = statement.executeQuery(); if (resultSet.next()) { System.out.println("登录成功" ); } else { System.out.println("登录失败" ); } } }
jdbc中的事务操作 jdbc中的事务默认是自动提交的;
我们要向手动的控制事务的提交必须要设置: conn.setAutoCommit(false);
jdbc中的批处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 package com.xzy;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;public class Ops7 { public static void main (String[] args) throws Exception { Connection conn = null ; Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/youdian?serverTimezone=Asia/Shanghai" ; conn = DriverManager.getConnection(url, "root" , "root" ); PreparedStatement preparedStatementAdd = conn.prepareStatement("insert into user(username,password) values(?,?)" ); for (int i = 0 ; i < 100 ; i++) { preparedStatementAdd.setString(1 , "aaa" + i); preparedStatementAdd.setString(2 , "AAA" + i); preparedStatementAdd.addBatch(); } preparedStatementAdd.executeBatch(); } }
json数据格式介绍 现在主流的开发中数据的传输格式:
json数据格式
json对象的数据格式
1 2 3 4 5 { "id" : 100 , "name" : "小明" , "age" : 30 }
json数组的数据格式
1 2 3 4 5 6 7 8 9 10 11 12 [ { "id" : 100 , "name" : "小明" , "age" : 30 } , { "id" : 200 , "name" : "小花" , "age" : 20 } ]
注意: json中的key一定要包含双引号,value如果不是字符串类型,不加双引号;
js中的对象和json互相转换 1 2 3 4 const jsonStr = JSON.stringify(obj); console.log(JSON.parse(jsonStr))
Http协议 http(Hyper Text Transfer Protocol)超文本传输协议
http底层是基于tcp协议,但是http是短连接
;
Http协议为什么建立的是短连接? 长连接是非常耗费服务器的cpu资源的,web端的应用场景一般都是短连接
http协议的短连接病并不是说tcp协议第短连接,而是一次请求建立tcp连接,响应结束之后又会断开tcp连接
Http的版本
http1.0
http1.1(主流的版本),实现了同一会话的,固定时间之内的http连接的复用
目前主流的http的应用
http协议: 超文本传输协议,默认端口为80
https协议(基于http的一种加密协议),默认端口为 443
Http协议详解
请求数据包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #请求行 POST https://fanyi.baidu.com/v2transapi?from=zh&to=en HTTP/1.1 #请求头 Host : fanyi.baidu.comConnection : keep-aliveContent-Length : 146sec-ch-ua : " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"Accept : */*Content-Type : application/x-www-form-urlencoded; charset=UTF-8X-Requested-With : XMLHttpRequestsec-ch-ua-mobile : ?0User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.93 Safari/537.36sec-ch-ua-platform : "Windows"Origin : https://fanyi.baidu.comSec-Fetch-Site : same-originSec-Fetch-Mode : corsSec-Fetch-Dest : emptyReferer : https://fanyi.baidu.com/Accept-Encoding : gzip, deflate, brAccept-Language : zh-CN,zh;q=0.9,en;q=0.8Cookie : BIDUPSID=0FC1D9004EBF6C0ADC29F9CF859186AB; PSTM=1639567242; BAIDUID=0FC1D9004EBF6C0A855E532D592AC6C5:FG=1; BAIDUID_BFESS=0FC1D9004EBF6C0A855E532D592AC6C5:FG=1; delPer=0; PSINO=2; H_PS_PSSID=34448_35106_34584_35491_35329_35316_26350_35312; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; BA_HECTOR=a42ha58l842ha1a4nh1grjlu60q; Hm_lvt_64ecd82404c51e03dc91cb9e8c025574=1639569367; __yjs_duid=1_5cb244490827d2b8282bb8a7a21870c61639569368190; REALTIME_TRANS_SWITCH=1; FANYI_WORD_SWITCH=1; HISTORY_SWITCH=1; SOUND_SPD_SWITCH=1; SOUND_PREFER_SWITCH=1; Hm_lpvt_64ecd82404c51e03dc91cb9e8c025574=1639569384; ab_sr=1.0.1_Mjk1YzBjMzI3NmIxYzI0YzJmMzM3YmMwY2VlNDI2OTY4NmE5Njc1ZmQyZGFmYzY1MWFmOWJiZTE3Nzg0Nzg4YmQ1YTQ5NGVmZjc4YTY2MGZhZWM2MTYzZTg2MGQwMWFkOGExMDFlMmRhOWI3M2VjYWE1YTcwZDZjNDU4YWI2Y2JkZDY5MjZhNTMzMGU2Nzc5MDA0YmUyYzZhY2Y4NzAzZQ==; __yjs_st=2_NTBiYjQyZjBhODlmYTc4NzJiOTFkNDBjYjdmNzQwNmUyOTFjOTkzM2UxMDkxYmY3NjUzOGEzOTU1NDRkMDI0MGNiNjc0ZmQ1MWEyYjk5NWM0NGE0ZDE5ZjIxMDY0Y2NjYmU2MTkxYmJlNTZlMmFkZThhZDk5ZmZmM2ZkMzJjM2U1MjllZDM2MTcwMGU1ZDhjNGZlODZhZTQ2MTU5MDgxMWJlMmZiZWFmYzA3YjBmZjg0ZDA5NjM1N2FhMzNlMmYyOTBkZWRlZjY1NTExZTQ5NGE5YmM3NjM5ZjYwNDM3MTEwNTJhMDU1NGQzZjhiNjk1ZDI1NmEzOWQ5ZWVkOTY1Zl83XzczYmIwYTdh#请求实体 from =zh&to =en&query =%E4 %BD %A0 %E5 %A5 %BD &transtype =enter&simple_means_flag =3&sign =232427.485594&token =1082f914a7120fea0cb89c08e8b0ca0f&domain =common
注意:
请求数据包中的第一行就是请求行; 请求方式 请求地址 协议版本
第一行往后,空行之前都是请求头; key: value
空行往后开始都是请求实体;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #响应行 HTTP/1.1 200 OK#响应头 Cache-Control : no-cache, privateContent-Encoding : gzipContent-Type : application/jsonDate : Wed, 15 Dec 2021 11:57:24 GMTServer : ApacheTracecode : 34440933802685789194121519Vary : Accept-EncodingTransfer-Encoding : chunked#响应实体 eeb
注意:
响应数据包中的第一行为响应行; 协议版本 响应码 响应信息
第一行往后,空行之前都是响应头; key: value
空行往后都是响应实体; 页面上需要呈现的数据在响应实体中;
http的的请求方式 1 2 3 4 5 6 GET POST HEAD PUT DELETE OPTIONS
GET请求与其他请求的不同:
凡是在浏览器的地址栏输入地址,看到的页面使用的请求方式都是GET
,因为浏览器的地址栏不支持其他请求方式;
GET请求不能有请求实体的,所有的请求参数必须在url中携带;
1 http://localhost:8080?key1=value1&key2=value2
不同的浏览器对url的长度有不同的限制,google浏览器的限制 1024byte
GET请求的参数在URL地址栏中携带,是不安全的,POST请求的参数既可以在地址栏携带,也可以在请求实体中携带;
POST请求在请求实体中携带数据,是相对 安全
;
GET请求是可以做资源定位
;
Http中的响应码与相应信息 1 2 3 4 5 6 7 8 9 10 200 OK 400 Bad Request 401 Unauthorized 404 Not Found 405 Method Not Allowed 415 Unsupported Media Type 500 Internal Server Error 502 Bad Gateway 504 Gateway Time-out 505 HTTP Version not supported
MimeType媒体类型 1 2 3 4 5 6 7 text/plain 原生的文本类型 text/html html类型 text/css css类型 text/javascript js类型 application/json json类型 image/jpeg 图片类型 .....其他的用到再查
后端接口
大家先学会使用
学会调试接口 java -jar xxx.jar
获取城市列表接口 请求地址: http://localhost:8080/city/listAll
请求方式: GET
参数: 无
获取城市对应的学校列表接口 请求地址: http://localhost:8080/school/listByCid
请求方式: POST
请求参数: cid=xxx
接口调试
借助浏览器的地址栏进行接口的调试
优点: 简单
缺点: 浏览器的地址栏
只支持GET请求,不支持其他请求方式
借助接口调试工具(推荐使用的做法)
PostMan
PostWoman
Insomnia
同步请求与异步请求 同步请求:
在浏览器给服务器发送请求到接收响应的过程中,浏览器不能做其他的事,只能等等着服务器的响应,直到成功;
同步请求,浏览器的地址栏中的url会发生变化
eg:
1 <a href ="http://localhost:8080/city/listAll" > 获取城市列表</a >
以上的点击a标签之后,页面发生跳转,发送的是同步请求,浏览器的地址栏发生了变化;
异步请求:
在浏览器给服务器发送请求的过程中,浏览器还可以进行其他的业务操作
异步请求,浏览器的地址栏不会发生变化
原生的js中发送异步请求(ajax) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > 异步请求</title > </head > <body > <button id ="btnGetCityList" > 从服务器获取城市列表</button > </body > <script > window .onload = function ( ) { let btnCityList = document .querySelector ("#btnGetCityList" ); btnCityList.onclick = function ( ) { const xhr = new XMLHttpRequest (); xhr.open ("GET" , "http://localhost:8080/city/listAll" ); xhr.send (); xhr.onreadystatechange = function ( ) { if (xhr.readyState === 4 ) { const respText = xhr.responseText ; const respArray = JSON .parse (respText); respArray.forEach (city =>console .log (city)) } } } } </script > </html >
jQuery中的封装的ajax 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > jQuery中封装的ajax</title > <script src ="jquery-1.9.1.min.js" > </script > </head > <body > <button id ="btnCityList" > 点我获取城市列表</button > <button id ="btnSchoolList" > 点我获取学校列表</button > <script > $(function ( ) { $("#btnCityList" ).click (function ( ) { $.ajax ({ url : "http://localhost:8080/city/listAll" , type : "GET" , dataType : "json" , success : function (resp ) { console .log ("成功:" , resp) }, error : function (msg ) { console .log ("失败:" , msg) } }); }); $("#btnSchoolList" ).click (function ( ) { $.ajax ({ url : "http://localhost:8080/school/listByCid" , type : "POST" , data : { cid : 2 }, dataType : "json" , success (resp ) { console .log ("成功:" , resp) } }); }); }); </script > </body > </html >
基于jQuery的二级联动 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 <!DOCTYPE html > <html lang ="en" > <head > <meta charset ="UTF-8" > <title > 基于jQuery的二级联动</title > <style > #root { width : 400px ; height : 300px ; margin : 0 auto; display : flex; align-items : center; justify-content : center; } button { width : 120px ; letter-spacing : 3px ; } select, button { width : 130px ; height : 30px ; } select[name=citySelect] { } </style > <script src ="jquery-1.9.1.min.js" > </script > </head > <body > <div id ="root" > <select name ="citySelect" id ="citySelect" > </select > <select name ="schoolSelect" id ="schoolSelect" > </select > <button > 点击查询</button > <script > $(function ( ) { const citySelect = $("#citySelect" ) const schoolSelect = $("#schoolSelect" ) $.ajax ({ url : "http://localhost:8080/city/listAll" , success (resp ) { resp.forEach (city => { const optionStr = `<option value="${city.id} ">${city.name} </option>` ; citySelect.append (optionStr); }) renderSchoolListByCid (citySelect.val ()) } }); citySelect.change (function ( ) { renderSchoolListByCid (this .value ) }); $("button" ).click (function ( ) { console .log ("城市:" + citySelect.val (), "学校:" + schoolSelect.val ()) }); function renderSchoolListByCid (cid ) { $.ajax ({ url : "http://localhost:8080/school/listByCid" , type : "POST" , data : {cid}, dataType : "json" , success (resp ) { schoolSelect.empty (); resp.forEach (school => { const optionStr = `<option value="${school.id} ">${school.name} </option>` ; schoolSelect.append (optionStr); }) } }); } }); </script > </div > </body > </html >
axios Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
发送请求Get请求:
1 2 3 4 5 6 7 axios.get("http://localhost:8080/city/listAll" ) .then(function (resp) { console.log("成功:" , resp) }) .catch (function (msg) { console.log("失败:" , msg) })