标签:JavaScript-前端、HttpServlet-后端、XML-JSON-中介
?
1.Ajax简介
Ajax是一种异步的JS和XML联合体,可以理解为一种新方法,整合了前端的JavaScript、HTML、CSS、DOM编程和后端的HttpServlet-Tomcat、Mysql数据库,其中JS用于创建异步对象并代替浏览器发送请求,而Servlet用于操作数据库,返回数据,二者由xml或者json统一。
【注意】现在以JS和JSON居多,因为json轻量级、体积小、易解析。
2.Ajax四步法
第一步:在前端创建异步对象XMLHttpRequest→XHR
var xmlHttp = new XMLHttpRequest();
第二步:注册网页状态变化事件
xmlHttp.onreadystatement = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
//处理返回的结果,反应到DOM对象上;一般需要xmlhttp.responseText;
}
}
第三步:拼接字符串、URL设置、开启连接
var name = document.getElementById("name").value;
var tizhong = document.getElementById("tizhong").value;
var shengao = document.getElementById("shengao").value;
//拼接位URL格式
var param = "name="+name+"&"+"tizhong="+tizhong+"&"+"shengao="+shengao;
xmlhttp.open("get","bimajaxurl?"+param,true);//拼接为URL发送
第四步:发送数据
xmlhttp.send();
【交互过程】用户输入http://localhost:8080/jj/,然后自动到站点下的index.html和index.jsp,后者展现输入框,用户输入,然后通过index.jsp获取输入信息,通过四步法构造Ajax异步对象,拼接为URL字符串进行数据访问;后端Servlet从发过来的URL中得到几个字段,然后经过计算后返回数据,在前端页面展示。
【涉及技术】index.jsp→四步法→URL→getParameter→后台计算→response.getWriter().print()→前台获取→异步对象.responseText→更新DOM.
3.Ajax项目→根据编号返回省份的查询结果
原材料:mysql建表,从该表查询
DROP TABLE IF EXISTS `province`;
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;
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', '江西', '赣', '南昌');
表格数据如下图所示:
思路:略
代码:
//index.jsp文件
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>省份与城市</title>
</head>
<script type="text/javascript">//异步对象代替浏览器发送请求
function serachPro(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("mydata").innerHTML = "省份是:"+xmlhttp.responseText;
}
}
var number = document.getElementById("number").value;
var param = "number="+number;
xmlhttp.open("get","dianji?"+param,true);//拼接为URL发送
xmlhttp.send();
}
</script>
<body>
<p>写数字,打印省份</p>
<div>
请输入数字:<input type="text" id="number"/><br/>
<input type="button" value="点我省份查询" onclick="serachPro()"/>
</div>
<div id="mydata">...正在查询省份数据...</div>
</body>
</html>
//web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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>sf</servlet-name>
<servlet-class>noprovince</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sf</servlet-name>
<url-pattern>/dianji</url-pattern>
</servlet-mapping>
</web-app>
//主程序
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
public class noprovince extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// String name = request.getParameter("number");
response.setContentType("text/html;charset=utf-8");
Connection col = null;
PreparedStatement ps = null; //变为预编译的Statemnet对象
ResultSet rs = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
col = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","123456");
String sql = "select name from province where id =? ";
ps = col.prepareStatement(sql);
ps.setString(1, request.getParameter("number"));
rs = ps.executeQuery();
PrintWriter pw = response.getWriter();
while(rs.next()){
// System.out.println(rs.getString(1));
pw.print(rs.getString(1));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch(SQLException e ){
e.printStackTrace();
}finally {
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (col !=null) {
try {
col.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
总结:本项目前端采用JS和Ajax对象,然后将数据以URL发送到后台的Servlet对象,经过JDBC数据库查询,得到结果后返回给前端,然后异步更新展示。
4.Ajax与Json前后端
上面第三点返回的是单独的一个值,怎么以实际开发中最常用的json格式返回呢?
以上面的例子为例,用户输入编号值,要求以json作为桥梁返回到对应的文本框中,效果如下:
思路:大体过程与3类似,拼接id形式的URL,然后返回json字符串,如下图所示:
?具体代码:
第一步:servlet新建province类,将在mysql查询到的记录格式化为province对象;
public class provinceTable {
//创建实体表对应的实体类
private int id;//把id设置为Integer类型;
private String name;
private String jiancheng;
private String shenghui;
public provinceTable(int id, String name, String jiancheng, String shenghui) {
this.id = id;
this.name = name;
this.jiancheng = jiancheng;
this.shenghui = shenghui;
}
public provinceTable() {
}
public int getId() {
return id;
}
public void setId(int 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;
}
}
第二步:将其转换为JSON对象
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class jsontest {
public static void main(String[] args) throws Exception{
//jackson转换为json对象;
//创建实体表对应的实体类
provinceTable p = new provinceTable(3,"河北","冀","石家庄");
//转换:
ObjectMapper om = new ObjectMapper();
String jsonFromJava = om.writeValueAsString(p);
System.out.println("转换后的结果是" + jsonFromJava);
}
}
【注意】这里使用了几个库文件的自带方法,将java对象转化为json对象!
?第三步:前端封装
<!--index.jsp-->
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>省份与城市</title>
</head>
<script type="text/javascript">//异步对象代替浏览器发送请求
function serachPro(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
// document.getElementById("provin").value = xmlhttp.responseText;
//解析json字符串;
// document.getElementById("provin_city").value = xmlhttp.responseText;
// document.getElementById("provinsimple").value = xmlhttp.responseText;
var data = xmlhttp.responseText;
//转换String到json对象
var jsonObj =eval("("+data+")") ;//获取json格式的字符串,需要转化为json对象
document.getElementById("provin").value = jsonObj["name"];
document.getElementById("provin_city").value = jsonObj["shenghui"];
document.getElementById("provinsimple").value = jsonObj["jiancheng"];
}
}
var number = document.getElementById("number").value;
var param = "number="+number;
xmlhttp.open("get","dianji?"+param,true);//拼接为URL发送
xmlhttp.send();
alert("测试异步与同步");
}
</script>
<body>
<p>写数字,打印省份信息</p>
<div>
请输入数字:<input type="text" id="number"/><br/>
省份名称:<input type="text" id="provin"/><br/>
省份简称:<input type="text" id="provinsimple"/><br/>
该省省会:<input type="text" id="provin_city"/><br/>
<input type="button" value="点我查询" onclick="serachPro()"/>
</div>
<div id="mydata">...正在查询,请稍后...</div>
</body>
</html>
第四步:注册web.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>sf</servlet-name>
<servlet-class>noprovince</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sf</servlet-name>
<url-pattern>/dianji</url-pattern>
</servlet-mapping>
</web-app>
第五步:后台Servlet主程序
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.*;
public class noprovince extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// String name = request.getParameter("number");
// response.setContentType("text/html;charset=utf-8");
//告诉浏览器,我现在返回的是json格式的数据;
response.setContentType("application/json;charset=utf-8");
Connection col = null;
PreparedStatement ps = null; //变为预编译的Statemnet对象
ResultSet rs = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
col = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","123456");
String sql = "select * from province where id =? ";
ps = col.prepareStatement(sql);
ps.setString(1, request.getParameter("number"));
rs = ps.executeQuery();
provinceTable pro;
String jsonFromJava="{}";//定义在这里是为了保证能够传送回去一个json格式的对象;
PrintWriter pw = response.getWriter();
while(rs.next()){
// System.out.println(rs.getString(1));
// pw.print(rs.getString(1));//
int id = Integer.valueOf(rs.getString("id"));
String name = rs.getString("name");
String jiancheng = rs.getString("jiancheng");
String shenghui = rs.getString("shenghui");
pro = new provinceTable(id,name,jiancheng,shenghui);
//转换为json对象;
ObjectMapper om = new ObjectMapper();
jsonFromJava = om.writeValueAsString(pro);
// System.out.println("转换后的结果是" + jsonFromJava);
pw.print(jsonFromJava);//传输回去字符串;
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch(SQLException e ){
e.printStackTrace();
}finally {
if (rs!=null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (col !=null) {
try {
col.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
第六步:配置Tomcat服务器,引入上述几个依赖库即可!
5.总结
5.1 同步与异步
在该案例中,我们发现,Ajax对象的请求是异步的,即他发出请求后不用干等servlet发回响应信息,可以进行其他操作,如创建新的Ajax对象,弹窗等等,而控制是否异步的关键就在于Ajax对象的open方法中的参数,如果是true则是异步,否则同步。
5.2 调试
在写程序过程中,一定要写测试语句,循序渐进的测试,以减少后期调错的成本,如加入打印语句,加入alert弹窗语句等。
|