what is 全局刷新?
整个浏览器被新的数据覆盖,在网络中传输大量的数据。浏览器需要加载,渲染页面。
what is 局部刷新?
浏览器的内部发起请求,获取数据,改变页面的部分内容,其余的页面无需加载。浏览器的数据没有全部发生变化,比如样式、图片、URL地址栏都没有改变,即需要什么获取什么。比如:一个简单的搜索框出现的联想搜索。网络中传输的数据量少。(和服务器发生了交互)
what is Ajax?what do we use it for?
Ajax:Asynchronous JavaScript and XML,异步的JavaScript和XML。
Ajax是实现局部刷新的一种方式,使用核心对象是异步对象(XMLHttpRequest),这个异步对象是存在浏览器内存中的,使用JavaScript语法创建和使用XMLHttpRequest。
Ajax包含的技术主要有JavaScript,dom,css,XML。核心是JavaScript和XML
JavaScript:负责创建异步对象,发送请求,更新页面的dom对象。Ajax请求需要服务端的数据。
XML:网络中传输的数据格式。现在使用JSON替换了。(so应该叫Ajaj?)
var xmlHttp= new XMLHttpRequest();
- 当异步对象发起请求,获取数据了,都会触发这个时间。这个事件需要指定一个函数,在函数中处理状态的变化。
xmlHttp.onreadystatechange=function(){
//处理请求的状态变化
}
每当 readyState 发生变化时,异步对象就会自动调用 onreadystatechange 的回调函数。
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4) {
//处理请求的状态变化
}
}
status属性:网络的状态,和Http的状态码对应
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//处理请求的状态变化
}
}
初始请求的参数,执行open()方法.
xmlHttp.open(请求方式get|post, “服务器端的访问地址”, 同步|异步请求(默认是true,异步请求))
xmlHttp.open("get", "loginServlet?name=zs&pwd=123",true);
使用异步对象向服务器发送请求,执行xmlHttp.send()
获取服务器端返回的数据, 使用异步对象的属性 responseText。
使用例子:xmlHttp.responseText
xmlHttp.onreadystatechange = function () {
// 当 readyState 等于 4 且状态为 200 时,表示响应已就绪
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//从服务器端获取了数据,更新当前页面的dom对象,完成请求的处理
var data = xmlHttp.responseText;
//更新dom对象
document.getElementById("name").value = data;
}
}
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0">
<servlet>
<servlet-name>BmiServletservlet-name>
<servlet-class>com.study.controller.BmiServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>BmiServletservlet-name>
<url-pattern>/bmiServleturl-pattern>
servlet-mapping>
web-app>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>全局刷新title>
head>
<body>
<p>全局刷新计算p>
<form action="bmiServlet" method="get">
姓名:<input type="text" name="name"><br/>
体重(公斤):<input type="text" name="weight"><br/>
身高(米):<input type="text" name="height"><br/>
<input type="submit" value="提交">
form>
body>
html>
3.创建BmiServlet
package com.study.controller;
import java.io.IOException;
/*servlet包不可用解决方案
1.添加tomcat服务器
2.项目结构->模块->添加依赖->library->tomcat
*/
public class BmiServlet extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//接收请求参数
String strName = request.getParameter("name");
String height = request.getParameter("height");
String weight = request.getParameter("weight");
//计算bmi
float h = Float.parseFloat(height);
float w = Float.parseFloat(weight);
float bmi = w / (h * h);
//判断bmi
String msg = "";
if (bmi <= 18.5) {
msg = "您比较瘦";
} else if (bmi > 18.5 && bmi <= 23.9) {
msg = "正常水平";
} else if (bmi > 24 && bmi <= 27) {
msg = "您比较胖";
} else {
msg = "您严重肥胖";
}
System.out.println("msg=" + msg);
msg = "您好," + strName + "先生/女士,您的bmi值是" + bmi + "," + msg;
//数据存入到request
request.setAttribute("msg",msg);
//转发到新的页面
request.getRequestDispatcher("/result.jsp").forward(request,response);
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>结果页面title>
head>
<body>
<p>显示bmi结果p>
<h3>${msg}h3>
body>
html>
新增一个BmiServlet,使用response直接输出,该方式不需要跳转页面,直接在原有页面显示
部分修改的代码如下
msg = "您好," + strName + "先生/女士,您的bmi值是" + bmi + "," + msg;
//使用HttpServletResponse输出数据
response.setContentType("text/html;charset=utf-8");
//获取PrintWriter
PrintWriter pw=response.getWriter();
//输出数据
pw.println(msg);
//清空缓存,使数据立即输出到浏览器
pw.flush();
pw.close();
以下工作,最终在浏览器获取到了服务器传输的数据。
通过使用button的异步对象
使用XMLHttpRequest发送请求和接收数据,不会影响整个页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>局部刷新-ajaxtitle>
<script type="text/javascript">
//使用内存中的异步对象,代替浏览器发送请求。异步对象使用js创建和管理
function doAjax() {
//1.创建
var xmlHttp=new XMLHttpRequest();
//2.绑定事件
xmlHttp.onreadystatechange=function () {
if(xmlHttp.readyState==4&&xmlHttp.status==200){
alert(xmlHttp.responseText);
}
}
//3.初始请求数据
xmlHttp.open("get","bmiAjax",true);
//4.发送请求
xmlHttp.send();
}
script>
head>
<body>
<p>局部刷新ajax-计算bmip>
<div>
姓名:<input type="text" id="name"/><br/>
体重(公斤):<input type="text" name="weight"><br/>
身高(米):<input type="text" name="height"><br/>
<input type="button" value="计算bmi" onclick="doAjax()">
div>
body>
html>
package com.study.controller;
import java.io.IOException;
import java.io.PrintWriter;
/*servlet包不可用解决方案
1.添加tomcat服务器
2.项目结构->模块->添加依赖->library->tomcat
*/
public class BmiAjaxServlet extends javax.servlet.http.HttpServlet {
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
}
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
System.out.println("-----------------------------------");
PrintWriter pw=response.getWriter();
pw.println("HelloAjax");
pw.flush();
pw.close();
}
}
//接收请求参数
String strName = request.getParameter("name");
String height = request.getParameter("height");
String weight = request.getParameter("weight");
//计算bmi
float h = Float.parseFloat(height);
float w = Float.parseFloat(weight);
float bmi = w / (h * h);
//判断bmi
String msg = "";
if (bmi <= 18.5) {
msg = "您比较瘦";
} else if (bmi > 18.5 && bmi <= 23.9) {
msg = "正常水平";
} else if (bmi > 24 && bmi <= 27) {
msg = "您比较胖";
} else {
msg = "您严重肥胖";
}
msg = "您好," + strName + "先生/女士,您的bmi值是" + bmi + "," + msg;
//使用HttpServletResponse输出数据
//设置编码
response.setContentType("text/html;charset=utf-8");
//获取PrintWriter
PrintWriter pw=response.getWriter();
//输出数据
pw.println(msg);
//清空缓存,使数据立即输出到浏览器
pw.flush();
pw.close();
关键在于value的获取,xhr的四个步骤,url参数拼接
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>局部刷新-ajaxtitle>
<script type="text/javascript">
//使用内存中的异步对象,代替浏览器发送请求。异步对象使用js创建和管理
function doAjax() {
//1.创建
var xmlHttp=new XMLHttpRequest();
//2.绑定事件
xmlHttp.onreadystatechange=function () {
if(xmlHttp.readyState==4&&xmlHttp.status==200){
alert(xmlHttp.responseText);
}
}
//3.初始请求数据
//获取dom对象的value值
var name = document.getElementById("name").value;
var weight=document.getElementById("weight").value;
var height=document.getElementById("height").value;
//传递参数拼接,很重要!!!
var param="name="+name+"&"+"weight="+weight+"&"+"height="+height;
//alert(param);
xmlHttp.open("get","bmiAjax?"+param,true);
//4.发送请求
xmlHttp.send();
}
script>
head>
<body>
<p>局部刷新ajax-计算bmip>
<div>
姓名:<input type="text" id="name"/><br/>
体重(公斤):<input type="text" id="weight"><br/>
身高(米):<input type="text" id="height"><br/>
<input type="button" value="计算bmi" onclick="doAjax()">
div>
body>
html>
需要实现的有:在页面有一个搜索框,点击搜索按钮,下面的搜索按钮会出现相应的名字
很久没用sql忘了语法了,键名不是单引号而是~键下面的符号;但注释和其它字符串是单引号
CREATE TABLE `province`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL COMMENT '省份名称',
`jiancheng` varchar(255) DEFAULT NULL COMMENT '简称',
`shenghui` varchar(255) DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;
CREATE TABLE `city`(
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`provinceid` varchar(255) DEFAULT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
INSERT INTO `province` VALUES ('1','河北','冀','石家庄');
INSERT INTO `province` VALUES ('2','山西','晋','太原');
INSERT INTO `province` VALUES ('3','内蒙古','蒙','呼和浩特');
INSERT INTO `province` VALUES ('4','辽宁','辽','沈阳');
INSERT INTO `province` VALUES ('5','江苏','苏','南京');
INSERT INTO `province` VALUES ('6','浙江','浙','杭州');
INSERT INTO `province` VALUES ('7','安徽','皖','合肥');
INSERT INTO `province` VALUES ('8','福建','闽','福州');
INSERT INTO `province` VALUES ('9','江西','赣','南昌');
INSERT INTO `city` VALUES ('1','石家庄市','1');
INSERT INTO `city` VALUES ('2','秦皇岛','1');
INSERT INTO `city` VALUES ('3','保定市','1');
INSERT INTO `city` VALUES ('4','张家口','1');
INSERT INTO `city` VALUES ('5','南昌市','9');
INSERT INTO `city` VALUES ('6','九江市','9');
INSERT INTO `city` VALUES ('7','宜春市','9');
INSERT INTO `city` VALUES ('8','福州市','8');
INSERT INTO `city` VALUES ('9','厦门市','8');
INSERT INTO `city` VALUES ('10','泉州市','8');
INSERT INTO `city` VALUES ('11','龙岩市','8');
INSERT INTO `city` VALUES ('12','太原','2');
INSERT INTO `city` VALUES ('13','大同','2');
INSERT INTO `city` VALUES ('14','呼和浩特','3');
INSERT INTO `city` VALUES ('15','包头','3');
INSERT INTO `city` VALUES ('16','呼伦贝尔','3');
附带一些连接mysql的cmd
启动mysql服务 net start mysql
停止mysql服务 net stop mysql
启动mysql后连接数据库 mysql -u root -p,回车后提示你输密码
记录一下我的密码是12345,防止我忘了
以下是controller和dao层
一些错误
- Error:java: 错误: 不支持发行版本 5 解决方法https://blog.csdn.net/m0_48462648/article/details/106980860
- java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
jdbc8是com.mysql.cj.jdbc.Driver- jar包在引入后记得在项目结构中添加依赖
关于调试
不必每次都重新启动应用程序
只需要idea左下角更新应用程序后,浏览器清除缓存(firefox是ctrl+shift+del)再刷新页面
controller层:QueryProvinceServlet.java
一个问题:
当name属性存在,但是没有值的时候后台用request.getParameter(“name”)获得的是空字符串""。
一个非常古怪的bug出现了,事实上,我测试当text中的value是好几个空格的时候,依然获得的是空字符串。不知道为什么会是这样,但它不应该是这样,他应该获取到空格的。
用了几个小时自己测试解决了。当浏览器发送get请求时,get请求的最后一个参数不能为空格或者是几个连续的空格。但是postman可以。
package com.studyAjax.controller;
import com.studyAjax.dao.ProvinceDao;
import java.io.IOException;
import java.io.PrintWriter;
public class QueryProvinceServlet extends javax.servlet.http.HttpServlet {
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//处理get请求
String strProid=request.getParameter("proid");
System.out.println("proid =--->"+strProid+"<---");
String name="默认没有数据";
//调用dao方法,访问数据库
if (!(strProid.trim()).equals("")){
ProvinceDao dao=new ProvinceDao();
System.out.println(name+"aaa");
name=dao.queryProvinceNameById(Integer.parseInt(strProid));
System.out.println(name+"aaa");
}
//使用response响应数据
response.setContentType("text/html;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.write(name);
pw.flush();
pw.close();
}
}
dao层:ProvinceDao.java
package com.studyAjax.dao;
import java.sql.*;
//使用jdbc访问数据库
public class ProvinceDao {
//根据id获取名称
public String queryProvinceNameById(Integer provinceId){
Connection conn=null;
PreparedStatement pst=null;
ResultSet res=null;
String sql="";
String url="jdbc:mysql://localhost:3306/ajax_1";
String username="root";
String password="12345";
String name="";
//加载驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
try {
conn= DriverManager.getConnection(url,username,password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
sql="select name from province where id = ?";
try {
//创建prepareStatement
pst =conn.prepareStatement(sql);
//设置参数值
pst.setInt(1,provinceId);
//执行sql语句
res=pst.executeQuery();
//遍历res
/*
while (res.next()){//当res中有多条记录时
name=res.getString("name");
}*/
if (res.next()){
name=res.getString("name");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
try {
if(res!=null){
res.close();
}
if (pst!=null){
pst.close();
}
if (conn!=null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return name;
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>ajax根据省份id获取名称title>
<script type="text/javascript">
function search() {
//1.创建异步对象
var xmlHttp = new XMLHttpRequest();
//2.绑定事件
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
//更新页面,即更新dom对象
document.getElementById("proname").value = xmlHttp.responseText;
}
}
//3.初始化异步对象
var proid = document.getElementById("proid").value;
//alert("--->"+proid+"<---");
var param = "proid=" + proid;
xmlHttp.open("get", "queryProvince?" + param, true);
//4.发送请求
xmlHttp.send();
}
script>
head>
<body>
<p>ajax根据省份id获取名称p>
<table border="1px">
<tr>
<td>省份编号:td>
<td>
<input type="text" id="proid"/>
<input type="button" value="搜索" onclick="search()">
td>
tr>
<tr>
<td>省份名称:td>
<td>
<input type="text" id="proname"/>
td>
tr>
table>
body>
html>
主要流程
- 在服务器端:将java对象转换为json格式的字符串
使用ObjectMapper.writeValueAsString( Object ob));
再使用printWriter传输给浏览器- 在js中,使用eval()函数将json格式的字符串转为json对象,然后使用 . 操作符访问该json对象的属性.当然这里的操作肯定都是在xmlHttp.onreadystatechange绑定的函数里面
ObjectMapper.writeValueAsString( Object ob))的使用例子
public static void main(String[] args) throws JsonProcessingException {
Province province = new Province();
province.setId(1);
province.setName("江苏");
province.setJiancheng("苏");
province.setShenghui("南京");
ObjectMapper om = new ObjectMapper();
String s = om.writeValueAsString(province);
System.out.println(s);//{"id":1,"name":"江苏","jiancheng":"苏","shenghui":"南京"}
}
案例的各个文件
package com.studyAjax.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.studyAjax.Entity.Province;
import com.studyAjax.dao.ProvinceDao;
import java.io.IOException;
import java.io.PrintWriter;
public class QueryJsonServlet extends javax.servlet.http.HttpServlet {
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
//处理get请求
String strProid = request.getParameter("proid");
//默认值,{ }表示json格式的数据
String json = "{}";
//调用dao方法,访问数据库
if (!(strProid.trim()).equals("")) {
Province province = new Province();
ProvinceDao dao = new ProvinceDao();
province = dao.queryProvinceById(Integer.parseInt(strProid));
//使用ObjectMapper把province对象转换成json
ObjectMapper om = new ObjectMapper();
json = om.writeValueAsString(province);
}
//使用response响应数据,并指定为json格式
response.setContentType("text/json;charset=utf-8");
PrintWriter pw = response.getWriter();
pw.write(json);//输出的数据会赋给ajax中的responseText属性
pw.flush();
pw.close();
}
}
//根据id获取province对象
public Province queryProvinceById(Integer provinceId){
Connection conn=null;
PreparedStatement pst=null;
ResultSet res=null;
String sql="";
String url="jdbc:mysql://localhost:3306/ajax_1";
String username="root";
String password="12345";
Province province=null;
//加载驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver");
try {
conn= DriverManager.getConnection(url,username,password);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
sql="select id,name,jiancheng,shenghui from province where id = ?";
try {
//创建prepareStatement
pst =conn.prepareStatement(sql);
//设置参数值
pst.setInt(1,provinceId);
//执行sql语句
res=pst.executeQuery();
//遍历res
/*
while (res.next()){//当res中有多条记录时
name=res.getString("name");
}*/
if (res.next()){
//从数据库中获取数据,并赋值给实体对象
province=new Province();
province.setId(res.getInt("id"));
province.setName(res.getString("name"));
province.setJiancheng(res.getString("jiancheng"));
province.setShenghui(res.getString("shenghui"));
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
try {
if(res!=null){
res.close();
}
if (pst!=null){
pst.close();
}
if (conn!=null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return province;
}
package com.studyAjax.Entity;
public class Province {
Integer id;
String name;
String jiancheng;
String shenghui;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getJiancheng() {
return jiancheng;
}
public void setJiancheng(String jiancheng) {
this.jiancheng = jiancheng;
}
public String getShenghui() {
return shenghui;
}
public void setShenghui(String shenghui) {
this.shenghui = shenghui;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>使用ajax传输json格式的数据title>
<script type="text/javascript">
function doSearch() {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function () {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
var data = xmlHttp.responseText;
//获取到的data为json格式的字符串 {"id":1,"name":"河北","jiancheng":"冀","shenghui":"石家庄"}
var jsonObj = eval("(" + data + ")");
//alert(jsonObj);//[object Object]
//更新dom对象,可以定义一个函数来处理 callback(jsonObj)
callback(jsonObj)
}
}
//初始化异步对象的请求参数
var proid = document.getElementById("proid").value;
//初始化异步对象
xmlHttp.open("get", "queryJson?proid=" + proid, true);
xmlHttp.send();
}
function callback(jsonObj) {
document.getElementById("proname").value = jsonObj.name;
document.getElementById("projiancheng").value = jsonObj.jiancheng;
document.getElementById("proshenghui").value = jsonObj.shenghui;
}
script>
head>
<body>
<p>ajax根据省份id获取名称p>
<table border="1px">
<tr>
<td>省份编号:td>
<td>
<input type="text" id="proid"/>
<input type="button" value="搜索" onclick="doSearch()">
td>
tr>
<tr>
<td>省份名称:td>
<td>
<input type="text" id="proname"/>
td>
tr>
<tr>
<td>简称:td>
<td>
<input type="text" id="projiancheng"/>
td>
tr>
<tr>
<td>省会:td>
<td>
<input type="text" id="proshenghui"/>
td>
tr>
table>
body>
html>