目录
1. 简介
这篇文章讨论的是ajax与Java后台互相传数据的功能,将会用到两种方法【或许叫做ajax使用的两种格式更为恰当】——一种是菜鸟教程上的方法,另一种是在网上查资料的时候大部分人用的方法。文章将重点对比两种方法在数据传输方面的差异性。
2.方法一:
前端js代码:
var xmlhttp; //声明一个XMLHttpRequest对象
if(window.XMLHttpRequest){ //根据浏览器情况实例化xmlhttp对象
xmlhttp=new XMLHttpRequest();
}
else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function () { //发送请求后,根据发送状态进行一系列操作
dosomething();
}
xmlhttp.open("GET", "saveImg?name=plane", true); //xmlhttp为向后台发送请求做必要的设置
xmlhttp.send(); //发送请求
后端Java代码
@WebServlet("/saveImg") //与前端xmlhttp.open函数中url参数一样
public class Save extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name"); //取出前端传入的值
System.out.println(name);
String s = "{\"name\" : \"宏彬\", \"age\" : 23, \"sex\": \"男\"}"; //准备向前端发送的一些数据,以键值对形式
resp.setCharacterEncoding("utf-8");
resp.setContentType("application/json; charset=utf-8");
resp.getWriter().write(s); //将准备的数据发送出去
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
这种方法是按照菜鸟教程里关于ajax方法进行数据传输的, 在看到这里的时候发现它没有告诉我前端该怎么取出后台传给我的数据【应该有个data内置对象,但是我没找到菜鸟教程把它放在哪里讲了】。
3.方法二:
前端js代码
var jsondata={ //定义一个json对象,用于存储数据
"name" : "plane",
"age" : 17
}
$.ajax({ //调用ajax发送数据
type:"get", //发送方式,post或者get
url:"saveImg", //发送给后台的url声明
data:jsondata, //指定要发送给后台的数据
success:function (data) { //发送成功并且成功获得后台响应的时候,
alert(data.name+data.age+data.sex); //执行的操作
},
error:function (e) { //发送失败了该执行的操作
alert("发生未知错误");
}
})
后端Java代码:与方法一中的一样
@WebServlet("/saveImg") //与前端xmlhttp.open函数中url参数一样
public class Save extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name"); //取出前端传入的值
System.out.println(name);
String s = "{\"name\" : \"宏彬\", \"age\" : 23, \"sex\": \"男\"}"; //准备向前端发送的一些数据,以键值对形式
resp.setCharacterEncoding("utf-8");
resp.setContentType("application/json; charset=utf-8");
resp.getWriter().write(s); //将准备的数据发送出去
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.两种方法的对比
对于熟悉Java的同学来说可能第一种方法看起来更习惯些,它的代码风格也更和Java接近。第二种方法里主要使用了jQuery的一些标签,看起来不太习惯。这里主要说的是,既然它们都是Ajax,第二种有success和error方法来进行请求响应成功或者失败的相应操作,那么第一种方法又该如何实现这样的操作呢?
看ajax onreadystatechange事件【摘自菜鸟教程】
onreadystatechange 事件
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。
下面是 XMLHttpRequest 对象的三个重要的属性:
属性 描述 onreadystatechange 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 readyState 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
- 0: 请求未初始化
- 1: 服务器连接已建立
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪
status 200: "OK"
404: 未找到页面在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
方法一里面就对onreadystatechange属性赋值了一个函数,可以根据readyState和status的值实现success和error的操作.
如下面这段代码在方法一的代码中也实现了代码二中的功能
var xmlhttp; //声明一个XMLHttpRequest对象
if(window.XMLHttpRequest){ //根据浏览器情况实例化xmlhttp对象
xmlhttp=new XMLHttpRequest();
}
else {
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function () { //发送请求后,根据发送状态进行一系列操作
if(xmlhttp.readyState==4&&xmlhttp.status==200){
var jsondata = xmlhttp.responseText
//alert(jsondata.name+jsondata.age+jsondata.sex);
alert(jsondata);
}
else{
alert("发生错误");
}
}
xmlhttp.open("GET", "saveImg?name=plane", true); //xmlhttp为向后台发送请求做必要的设置
xmlhttp.send();
嗯....运行之后,发现代码逻辑走的并不是if里面的代码,而是走了else里面的代码。在查看xmlhttp.readyState和xmlhttp.status后发现它们的值变化了四次,分别是(0, 0), (1, 200), (2, 200), (3, 200),这也正好对应着请求响应的几个步骤。
这是第四次状态的时候走if语句时页面的显示。虽然jsondata显示的格式和json格式很像,但是它应该只是一个字符串,不要把它当json用【就像被注释掉的那行一样】,取不到值【undefined】
如果想要想第一种方法那样使用键值对的形式取数据,那么后台传过来的数据就需要是xml类型的了。具体参考下面给的菜鸟教程示例
请求 cd_catalog.xml 文件,并解析响应:
xmlDoc=xmlhttp.responseXML; txt=""; x=xmlDoc.getElementsByTagName("ARTIST"); for (i=0;i<x.length;i++) { txt=txt + x[i].childNodes[0].nodeValue + "<br>"; } document.getElementById("myDiv").innerHTML=txt;
5.总结
在Ajax传输数据的时候,第一种方法直接在url中,通过在后面添加“?key1:val1&key2:val2...”的方式向后台传数据,取数据就只能取到一个字符串。想要取键值对则后台需要响应回来一个xml文件
第二种方法虽然格式上和Java代码差异有些大,但是它可以指定传输数据的对象,并且通过这个对象用取键值对的方法取值,在存取数据的方面感觉比第一种方法更方便些。