JavaWeb学习笔记八:Ajax学习,使用Ajax引擎访问服务器,以及Servlet技术中乱码问题的再梳理
文章目录
1. JavaWeb学习笔记八:Ajax学习
1.1. 同步和异步理解
- 同步:一般出现在进程和线程里面,比如一个进程需要需要另一个进程的数据才能继续执行,那么该进程只能等待另一个进程执行完后才能执行,这就是同步,在网页上的现象有:点击一个连接后只有该连接响应了才能点击其他链接。
- 异步:异步和同步相反,就是该进程不需要等待另一个进程执行完,你可以继续执行其他事项,在网页上的现象有:当点击一个连接后,你不需要等待响应,你还可以点击其他连接。网页不会因为没有响应请求而卡死。
1.2. Ajax在web工程中充当的角色
- Ajax在web工程中充当中间人的角色,比如用户提交一个连接,并没有直接提交给浏览器,而是提交给了Ajax引擎,Ajax引擎再提交给浏览器,在这里充当了一个中介角色,这样做的好处就是实现了异步操作 ,用户提交连接后可以不必等待响应,可以再点击其他链接。Ajax通常被叫做异步访问,也被叫做局部刷新
1.3. 由js实现Ajax的创建
- 用js实现Ajax需要5个步骤:
第一: 创建Ajax引擎对象----所有操作都是通过引擎对象的。
第二: 绑定监听—监听服务器是否已经返回相应数据。
第三: 绑定地址。
第四: 发送请求。
第五: 接收相应数据。
1.3.1. 创建Ajax引擎对象
function fn1(){
//1.创建ajax引擎对象----- 所有的操作都是通过引擎对象
var xmlHttp =new XMLHttpRequest();
//2.绑定监听----监听服务器是否已经返回相应的数据
xmlHttp.onreadystatechange=function(){
if(xmlHttp.readyState==4&&xmlHttp.status==200){
//5.接收相应数据
var res=xmlHttp.responseText;
alert(res);
}
}
//3.绑定地址,true表示异步,false表示同步操作
xmlHttp.open("GET","/WEB/ajaxServlet",true);
//4.发送请求
xmlHttp.send();
}
1.3.2. 不使用Ajax访问服务器和使用Ajax访问服务器的区别
1.3.3. 乱码问题再理解
- 参考文章:乱码原因与解决
- Tomcat服务器的默认解码方式是“ISO-8859-1"标准,因为和计算机最基础的表示单位一致,又因为是单字节编码,造成很多协议默认使用该编码。
- 一般jsp提交的数据是通过UTF-8编码集来编码的,当提交到tomcat服务器时,Tomcat服务器的解码是通过ISO-8859-1默认编码集来解码,由于ISO8859-1的编码集合UTF-8的编码集很多不同,就会出现乱码。也就是说通过request.getParamater()获取的汉字会变成乱码。要想解决这个乱码就要改变获取值的解码格式,先把request获取的值用ISO8859-1编码,再用UTF-8字符集解码。就解决了问题。
- post提交表单解决方法:
request.setCharacterEncoding("UTF-8");
- 用着一句就行了,因为post提交是一种二进制形式提交的。就缺少一个字符集。
- 用get的提交方式:
username=new String(username.getBytes("ISO-8859-1"),"UTF-8");
- 用String类的编解码方式
- 对于响应,需要设置两个参数,一个是服务器输出时用什么编码,浏览器解析用什么编码。
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
1.4. 由JQuery实现Ajax异步校验
- 使用JQuery实现get异步访问服务器端
function fn1(){
//get异步访问
$.get(
"xxxx",//url地址
{"name":"张三","age":25},
function(data){
//执行成功后函数回调
alert(data.name);
},
"json"
);
}
- 使用JQuery实现post异步访问服务器
function fn2(){
//post异步访问
$.post(
"xxxx",//url地址
{"name":"李四","age":25}, //请求参数
function(data){ //执行成功后的回调函数
alert(data.name);
},
"json"
);
}
- 使用JQuery实现Ajax异步访问服务器
function fn3(){
$.ajax({
url:"xxxxx",
async:true,//是否异步
type:"post",//提交类型
data:{"name":"tom","age":18},
success:function(data){
alert(data.name);
},
error.function(){
alert("请求失败");
},
dataType:"json"//数据类型
});
}
2. 案例一:用ajax引擎访问服务器实现搜索框显示
- 前端页面创建搜索显示框
<input id="search" type="text" class="form-control" placeholder="Search" "searchWord(this)">
<div id="showDiv" style="display:none; position:absolute;z-index:1000;background:#fff; width:179px;border:1px solid #ccc;"></div>
<!-- display:none表示不显示出来-->
- 用JQuery实现服务器请求
function searchWord(obj){
//1、获得输入框的输入的内容
var word = $(obj).val();//注意JQuery和js有些不同,
//2、根据输入框的内容去数据库中模糊查询---List<Product>
var content = "";
$.post(//使用post提交方式访问服务器
"${pageContext.request.contextPath}/searchWord",
{"word":word},
function(data){
//3、将返回的商品的名称 现在showDiv中
if(data.length>0){
for(var i=0;i<data.length;i++){
content+="<div style='padding:5px;cursor:pointer' 'clickFn(this)' 'overFn(this)' 'outFn(this)'>"+data[i]+"</div>";
}
$("#showDiv").html(content);
$("#showDiv").css("display","block");
}
},
"json"
);
}
function overFn(obj){
$(obj).css("background","#DBEAF9");
}
function outFn(obj){
$(obj).css("background","#fff");
}
function clickFn(obj){
$("#search").val($(obj).html());
$("#showDiv").css("display","none");
}
- obj代表的是鼠标选中的对象。
- 后端web层Servlet代码实现调用,json的封装。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取关键字
String word=request.getParameter("word");
//2.查询该关键字的所有商品
ProductService service=new ProductService();
List<Object> productList=null;
try {
productList=service.findProductByWord(word);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//使用json的转换工具将对象或集合转成json格式的字符串。
Gson gson=new Gson();
//封装jison
String json=gson.toJson(productList);
System.out.println(json);
response.setContentType("text/html;charset=UTF-8");
//服务器将其传递到ajax引擎里面
response.getWriter().write(json);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
- 注意这里面用了Gson一个google做的工具,用于将获取的值封装成json
- dao层实现数据库查询操作
public List<Object> findProductByWord(String word) throws SQLException {
QueryRunner runner=new QueryRunner(DataSourceUtils.getDataSource());
String sql="select * from product where pname like ? limit 0,8";
List<Object> query=runner.query(sql, new ColumnListHandler("pname"),"%"+word+"%");
return query;
}
- 模糊查询,ColumnListHandler用户返回一个列的值。
3. 案例二:利用Ajax访问服务器,实现注册校验功能
- 利用id绑定用户名,利用span标签可以输入html。
<input type="text" class="form-control" id="username" placeholder="请输入用户名">
<span id="usernameInfo"></span>
- 用jQuery写post访问服务器
//页面加载完成就执行
$(function(){
//为输入框绑定事件
$("#username").blur(function(){
//1. 失去焦点获得输入框内容
var usernameInput=$(this).val();
//2.去服务端校验该用户名是否存在----ajax
$.post(
"${pageContext.request.contextPath}/checkUsername",
{"username":usernameInput},
function(data){
var isExist=data.isExist;
var usernameInfo="";
if(isExist){
usernameInfo="该用户名已经存在"
$("#usernameInfo").css("color","red");
}else{
usernameInfo="该用户可以使用";
$("#usernameInfo").css("color","green")
}
$("#usernameInfo").html(usernameInfo);
},
"json"
);
});
});
- 后端web层主要是获取ajax提交的参数,然后到数据库查找该参数是否存在。
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取要校验的用户名
String username=request.getParameter("username");
//传递username到service层
boolean isExist=false;
UserService service=new UserService();
try {
isExist=service.checkUsername(username);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.getWriter().write("{\"isExist\":"+isExist+"}");
}
- dao层用来查询数据库
public Long checkUsername(String username) throws SQLException {
QueryRunner runner=new QueryRunner(DataSourceUtils.getDataSource());
String sql="select count(*) from user where username=?";
Long query=(Long) runner.query(sql, new ScalarHandler(), username);
return query;
}
- 这个为什么要返回Long型,我也不清楚。都这样写。有些博客上说,ScalarHandler()虽然返回的是Object型,不过他本身就是Long型。