1.什么是ajax?
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。
2.ajax的作用
通过在后台与服务器进行少量数据交换,Ajax 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个网页页面。
如果提交的数据错误会避免整个数据都会消失而重新写的那种情况用户名是否已经存在的校验
同步:同步是直接向服务器发送请求,然后接受在相应生成页面,中间有空白时间
异步:是通过一个中间层称为XMLHTTPRequest(AJAX的核心对象),请求只用发到他上面,而不用直接发送到服务器上,这样的过程为异步
3ajax入门程序:
步骤:
- 1.创建一个核心对象 XMLHttpRequest
- 2.编写一个回调函数
- 3.编写请求方式和请求的路径(open操作)
- 4.发送请求(send操作)
代码实现:步骤1:
新建一个Hello.jsp文件(省略公共部分)
<body>
<input type="button" value="点我" οnclick="btnClick()">
</body>
<script type="text/javascript">
function btnClick(){
//1.创建核心对象(该步骤可以去W3c中找,了解,直接拿来)
xmlhttp=null;
if (window.XMLHttpRequest)
{// code for Firefox, Opera, IE7, etc.
xmlhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject)
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}//2.编写回调函数
xmlhttp.onreadystatechange=function(){
//响应的内容eg://alert(xmlhttp.readyState);
}
//3.open 设置请求的方式和请求路径
xmlhttp.open("get","${pageContext.request.contextPath}/ajax");
//4.send 发送请求
xmlhttp.send();
}
</script>
步骤2:
新建servlet并把路径改为ajax
重写doget:
System.out.println("请求来了");
实现效果:“
点击三次后,路径没有改变
结果分析:
不断的发请求,但是页面是没有刷新的,这就是异步的请求的实现
4.ajax-api详解
1. 常用属性:
- 1.onreadystatechange:用来检测readyState状态的改变
- 2readyState:ajax核心对象的状态(一共五种)
0:核心对象创建
1:调用了open方法
2:调用了send方法
3:部分响应已经生成(没有意义)
4:响应已经完成(使用的是这个状态)
- 3.status:状态码
一般用法: if(xmlhttp.readyState==4 && xmlhttp.status==200){正常响应
}
- 4responseText:响应回来的文本
xmlhttp.responseText
2. 常用方法:
注意:[ ]代表里面的东西可有可无
- open("请求方式","请求路径"[,"是否异步"]):
作用:设置请求的方式和请求的路径
- send(["参数"]):
作用:发送请求 (如果写参数的话是post的,get的是放在地址栏上的,也就是请求路径上)
eg:xmlhttp.open("get","/day15/ajax2?username=张三");
- setRequestHeader("content-type","form表单enctype属性"):设置post请求的参数的类型 必须放在send方法之前.
key-value的形式
测试get请求:
步骤1:get.jsp
<script type="text/javascript">
function btnClick(){
//核心对象//编写回调函数,如果正常响应则.....alert
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
alert(xmlhttp.responseText);
}
}
//open
xmlhttp.open("get","/day09/ajax2?username=张三");
//send
xmlhttp.send();
}
</script>
步骤2:
新建servlet,url为ajax2
public class Ajax2Servlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 接受参数
String username = request.getParameter("username");
username = new String(username.getBytes("iso8859-1"), "utf-8");//设置编码
System.out.println(username);// 响应数据
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("姓名:" + username);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request,response);}
}
post请求测试:
1.新建post.jsp
<script type="text/javascript">
function btnClick(){
//1 .创建核心对象
.......//2.编写回调函数
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
alert(xmlhttp.responseText);
}
}
//3.open
xmlhttp.open("post","/day09/ajax3");
//4.设置请求头
xmlhttp.setRequestHeader("content-type", "application/x-www-form-urlencoded");
//5.send
xmlhttp.send("username=张三");
}
</script>
步骤2:
新建servlet url为ajax3
重写dopost
//设置编码(可以用第二种方式)
request.setCharacterEncoding("utf-8");
// 接受参数
String username = request.getParameter("username");// 响应数据
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("post姓名:" + username);
内容分析:
假如和get一样的话把张三的数据放在地址栏上,最后的结果会出现乱码,为什么?
解决:
post是将参数放到地址栏上,地址栏参数肯定的乱,因为不是在请求体中的,所以得把参数放在send的post中,并且加上请求头像这样:
//4.设置请求头
xmlhttp.setRequestHeader("content-type", "application/x-www-form-urlencoded");//设置文件的mime类型 这个类型参数(不用记)是form表单中enctype的类型,可直接拿过来用
//5.send
xmlhttp.send("username=张三");
5.Jquery的ajax:
1.使用方式
方式1:
jquery对象.load(url , params , function(数据) {} );
用到的请求方式不确定:
方式2:get方式★★★
$.get (url ,params , function( 数据 ) { } ,type );//type可有可无
$.get(url,params,function(d){ //d是一个object
alert(d)
});
方式3:post方式★★★
$.post (url ,params , function( 数据 ) { } ,type );//加上type为jason格式
$.post(url,params,function(d){
alert(d.msg);
},"json");假如说在servlet中获取到的字符串形式是json格式的
eg;
//{"result":"success","msg":"成功"}
String s="{\"result\":\"postsuccess\",\"msg\":\"成功\"}";
//响应数据
response.setContentType("text/html;charset=utf-8");
response.getWriter().print(s);
获取的就是对象
获取对象的内容:只用d.msg即可输出
总结: 若结果为json格式, 打印返回值的时候是一个对象
例如若json为 {"result":"success","msg":"成功"}
获取msg 只需要 参数.msg
方式4:
$.ajax([选项]);//用的少
选项的可选值:
url:请求路径
type:请求方法
data:发送到服务器的数据
success:fn 成功以后的回调
error:fn 异常之后的回调
dataType:返回内容格式 经常使用json
async:设置是否是异步请求
使用:
$.ajax({
url:"/day09/demo1",
type:"post",
data:"username=tom",
success:function(d){
alert(d.msg);
},
error:function(){},
dataType:"json"
});
2.jquery的ajax实现判断用户名是否被占用:
步骤1:新建一个jsp文件demo1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>//★★★不要忘记导入jquery的jar包
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.11.3.min.js"></script>
<title>Insert title here</title>
<script type="text/javascript">
$(function(){
//给username派发一个失去焦点事件 发送ajax请求★★★
$("input[name='username']").blur(function(){
//获取输入的值★★★
var $value=$(this).val();
//alert($value);
//★★★
$.get("/day09/check","username="+$value,function(d){
//alert(d);
if(d==1){
$("#usename_msg").html("<font color='green'>用户名可以使用</font>");
}else{
$("#usename_msg").html("<font color='red'>用户名已被使用</font>");
}
});
});
})
</script>
</head>
<body>
<form method="post" action="#">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
<td><span id="usename_msg"></span></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="text" name="password"></td>
<td></td>
</tr>
<tr>
<td colspan='3'><input type="submit" id="sub"></td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
//失去焦点 发送ajax
</script>
</html>
新建servlet url为check
package com.javaweb.servlet;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.javaweb.domain.User;
import com.javaweb.service.UserService;
/**
*
*/
public class CheckServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0.设置编码
//1.接受用户名
String username=request.getParameter("username");
username=new String(username.getBytes("iso-8859-1"),"utf-8");
System.out.println(username);
User user=null;
//2.调用service 完成查询 返回值 user
try {
user = new UserService().checkUserName4Ajax(username);//★★★
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//3.判断user 写回信息
if(user == null){
response.getWriter().println("1");//★★★
}else{
response.getWriter().println("0");//★★★
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
新建service
package com.javaweb.service;
import java.sql.SQLException;
import com.javaweb.dao.UserDao;
import com.javaweb.domain.User;
public class UserService {
public User checkUserName4Ajax(String username) throws SQLException {
return new UserDao().getUserNameByAjax(username);//★★★
}
}
新建dao
package com.javaweb.dao;
import java.sql.SQLException;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import com.javaweb.domain.User;
import com.javaweb.utils.DataSourceUtils;
public class UserDao {
public User getUserNameByAjax(String username) throws SQLException {
QueryRunner qr=new QueryRunner(DataSourceUtils.getDataSource());
String sql="select * from user where username = ? limit 1";
return qr.query(sql,new BeanHandler<>(User.class),username);//★★★
}
}
//注意limit 1(分开)
//注意qr.query最后一个参数,他是从String username传进啦的,细节问题
我们来对比一下和原生ajax判断用户名是否被占用(只对比jsp页面中的其他的是一样的)
可见下面的还是比较多的
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!-- 不提交所以不用路径 -->
<form method="post" action="#">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username" onblur='checkUsername(this)'></td>
<td><span id="usename_msg"></span></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="text" name="password"></td>
<td></td>
</tr>
<tr>
<td colspan='3'><input type="submit" id="sub"></td>
</tr>
</table>
</form>
</body>
<script type="text/javascript">
function checkUsername(obj){
//创建核心对象★★★
xmlhttp=null;
if (window.XMLHttpRequest)
{// code for IE7, Firefox, Opera, etc.
xmlhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject)
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
//编写回调函数★★★
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
//xmlhttp.responseText;
if(xmlhttp.responseText==1){
document.getElementById("usename_msg").innerHTML="<font color='green'>用户名可以使用</font>";
document.getElementById("sub").disabled=false;//★★★
}else{
document.getElementById("usename_msg").innerHTML="<font color='red'>用户名已被占用</font>";
document.getElementById("sub").disabled=true;
}
}
}
//open操作★★★
xmlhttp.open("get","${pageContext.request.contextPath}/check?username="+obj.value);
//send★★★
xmlhttp.send();
}
</script>
</html>
3.模仿百度实现搜索框:
步骤1:
新建一个jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.11.3.min.js"></script> <script type="text/javascript"> $(function(){ //文本框keyup的时候发送ajax $("#tid").keyup(function(){//★★★ //获取文本框的值 var $value=$(this).val();//★★★ //内容为空的时候不发送ajax if($value!= null && $value!=''){ //清空div $("#did").html("");//★★★ $.post("/day09/searchKw","kw="+$value,function(d){//★★★ //不为空的时候切割字符串 if(d!=''){ var arr=d.split(","); $(arr).each(function(){ //alert(this); //可以将每一个值放入一个div 将其内部插入到id为did的div中 $("#did").append($("<div>"+this+"</div>"));//★★★ }); //将div显示 $("#did").show(); } }); }else{ //内容为空的时候 将div隐藏 $("#did").hide(); } }); }) </script> <title>Insert title here</title> </head> <body> <center> <div> <h1>Biu搜索</h1> <div> <input name="kw" id="tid"><input type="button" value="Biu一下"> </div> <div id="did" style="border: 1px solid red;width: 171px;position:relative;left:-34px;display:none"></div> </div> </center> </body> </html>
步骤2:
新建一个servlet url改为searchKw
package com.javaweb.servlet; import java.io.IOException; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.javaweb.domain.User; import com.javaweb.service.UserService; /** * */ public class CheckServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //0.设置编码 //1.接受用户名 String username=request.getParameter("username"); username=new String(username.getBytes("iso-8859-1"),"utf-8"); System.out.println(username); User user=null; //2.调用service 完成查询 返回值 user try { user = new UserService().checkUserName4Ajax(username);//★★★ } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } //3.判断user 写回信息 if(user == null){ response.getWriter().println("1"); }else{ response.getWriter().println("0"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
步骤三;新建一个service 名字为 KeyWordService
package com.javaweb.service; import java.sql.SQLException; import java.util.List; import com.javaweb.dao.KeyWordDao; public class KeyWordService { /** * 通过关键词查询 * @param kw * @return * @throws SQLException */ public List<Object> findKw4Ajax(String kw) throws SQLException {//★★★ return new KeyWordDao().findKw4Ajax(kw); } }
步骤4.新建一个dao 名称为 KeyWordDao
package com.javaweb.dao; import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.ColumnListHandler; import com.javaweb.utils.DataSourceUtils; public class KeyWordDao { public List<Object> findKw4Ajax(String kw) throws SQLException { QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource()); String sql="select kw from keyword where kw like ? limit 5"; return qr.query(sql, new ColumnListHandler("kw"), "%"+kw+"%");//★★★ } }
实现效果:
4.ajax的省市联动
1.步骤分析:
1.表
2.页面上有两个下拉选 省份的下拉选一般是固定的 页面加载的时候读取所有的省份
3.当省份改变的时候,获取省份的信息,发送一个ajax请求,去市的表中查询相应省份的所有市,然后将他们加载到市下拉选上
4.selectProServlet selectCityServlet
技术分析:
json
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。
json格式:
格式1:value可以为任意值
{"key":value,"key1":value1}
格式2:e可以为任意值
[e1,e2]
jsonlib工具类,可以使对象转换成json数据
1.导入jar包
2.使用api
JSONArray.fromObject(对象) 数组和list
JSONObject.fromObject(对象) bean和map
代码实现
step1:新建一个jsp页面demo.jsp构出省市联动的图形
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript"
src="${pageContext.request.contextPath }/js/jquery-1.11.3.min.js"></script>★★★
<script type="text/javascript">
$(function(){
//页面加载成功 查询所有的省
$.get("/day09/selectPro",function(d){//★★★
//
var $pro=$("#proId");
$(d).each(function(){
$pro.append($("<option value="+this.provinceid+">"+this.name+"</option>"));
});
},"json");//★★★
//给省份下拉选派发change事件
$("#proId").change(function(){
//获取省份id
var $pid=$(this).val();
//alert($pid);
//发送ajax请求 查询所有的市
$.get("/day09/selectCity",{"pid":$pid},function(obj){//★★★
//alert(obj);
var $city=$("#cityId");
//清空
$city.html("<option>-请选择-</option>");//★★★
if(obj!=null){
//不为空遍历
$(obj).each(function(){//★★★
$city.append($("<option value='"+this.cityid+"'>"+this.name+"</option>"));
});
}
},"json");
});
})
</script>
<title>省市联动</title>
</head>
<body>
<select id="proId" name="province">
<option>-省份-</option>
<!--
<option value="1">北京</option>
-->
</select>
<select id="cityId" name="city">
<option>-请选择-</option>
</select>
</body>
</html>
step2:下拉选造成change()事件先跳转到查询selectProServlet
新建一个selectPro
//省略只写get
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.调用service 查询所有的省份★★★
List<Province> list=null;
try {
list =new ProvinceService().findAll();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//2.将所有的省份写回去★★★
response.setContentType("text/html;charset=utf-8");
if(list!=null && list.size()>0){
response.getWriter().println(JSONArray.fromObject(list));★★★
}
}
step3:省份service层
public List<Province> findAll() throws SQLException {
return new ProvinceDao().findAll();
}
step4:省份dao
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
String sql="select * from province";
return qr.query(sql, new BeanListHandler<>(Province.class));
完成之后省份中会有对应的id,然后再市的下拉选中获取省份的id
又回到step1: 跳转到servletCity中,所以新建servletCity
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//0.设置编码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//1.获取省份id
String pid=request.getParameter("pid");★★
//2.调用service 查询所有的市 返回 list★★★
List<City> list=null;
try {
list = new CityService().findCitiesByPid(pid);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//3.将list转换成json 返回页面
if(list!=null && list.size()>0){
response.getWriter().println(JSONArray.fromObject(list));★★★
}
}
step2市service层
public List<City> findCitiesByPid(String pid) throws SQLException {
return new CityDao().findCitiesByPid(pid);
}
step3市dao层
public List<City> findCitiesByPid(String pid) throws SQLException {
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
String sql="select * from city where provinceid = ?";
return qr.query(sql, new BeanListHandler<>(City.class),pid);
}
结果展示: