AJax
1. 前端视图
ajax\src\main\webapp\ajax-register.html
<html><head><meta charset="UTF-8">
</head><body><form class="form-horizontal" role="form"><div><tr><td>账号</td><td class="inputs"><input name="username" type="text" id="username"></td><br><span id="username_err" class="err_msg" style="display:none">用户名已存在</span></tr></div><div><tr><td>密码</td><td class="inputs"><input name="password" type="text" id="password"></td></tr></div></form><script>// 1.给用户输入框绑定失去焦点事件document.getElementById("username").onblur = function () {// alert("TTT");// 2.发送ajax请求// 获取参数var username = this.value;// 2.1.创建核心对象const xhttp = new XMLHttpRequest();// 2.2.发送请求// 通过selectUserservlet向servlet.java发送usernema数据xhttp.open("GET", "http://localhost:8080/ajax/selectUserservlet?username=" + username);// 传两个参数:// xhttp.open("GET", "http://localhost:8080/ajax/selectUserservlet?username=test2&username2=test2");xhttp.send();// 2.3.获取响应xhttp.onreadystatechange = function () {if (this.readyState == 4 && this.status == 200) {//判断if (this.responseText == "true") {// 用户名已存在// 将展示(display)启用,显示提示信息document.getElementById("username_err").style.display = '';}else {// 用户名不存在// 将展示(display)关闭,清除提示信息document.getElementById("username_err").style.display = 'none';}}};}</script>
</body>
</html>
2. 后端
ajax\src\main\java\com\mercurows\web\servlet\servlet.java
package com.mercurows.web.servlet;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/selectUserservlet")
public class servlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1.接受用户名String username = req.getParameter("username");System.out.println(username);// 2.调用service查询user对象boolean flag = true;// 3.标记响应resp.getWriter().write("" + flag);}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doGet(req, resp);}
}
3. 请求链接如何确定?
xhttp.open("GET", "http://localhost:8080/ajax/selectUserservlet");
上述不带参数传递的请求连接为:http://localhost:8080/ajax/selectUserservlet
具体步骤:
用tomcat打开项目
一开始默认进来是这样的:
又因为要跳转到后端的servlet的servlet.java
页面,通过上面的注解 **@WebServlet(“/selectUserservlet”)**知道请求链接后面应该跟随selectUserservlet
若想传递参数则需要修改链接为:
http://localhost:8080/ajax/selectUserservlet?username=" + username
此时后端接受参数方法为:
String username = req.getParameter("username");
4. 项目结构
Axios
0. 导入js文件
去网上找到axios.js
并导入项目中
然后在前端中导入
<script src="js/axios.js"></script>
1. 前端视图
ajax\src\main\webapp\axios-demo.html
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>Title</title></head><body><script src="js/axios.js"></script><!-- 1.get方式 --><!-- <script>axios({method:"get",url:"http://localhost:8080/ajax/axiosServlet?username=zhangsan"}).then(function (resp){alert(JSON.stringify(resp.data));})</script> --><!-- 2.post方式 --><script>axios({method:"post",url:"http://localhost:8080/ajax/axiosServlet",data:"username=zhangsan"}).then(function (resp){alert(JSON.stringify(resp.data));})</script></body>
</html>
2. 后端
ajax\src\main\java\com\mercurows\web\servlet\AxiosServlet.java
package com.mercurows.web.servlet;import java.io.IOException;
import java.util.HashMap;
import java.util.Map;import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import net.sf.json.JSONObject;@WebServlet("/axiosServlet")
public class AxiosServlet extends HttpServlet{@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {System.out.println("get..");// 1.接受用户名String username = req.getParameter("username");// 2.响应数据// res.getWriter().write("hello axios");System.out.println(username);Map<Object,Object> data1 = new HashMap<>();data1.put("name", "Alice");data1.put("age", 12);data1.put("measurements", new int[] { 60, 70, 70 });JSONObject object = JSONObject.fromObject(data1); //创建Json对象//将json对象转化为字符串在终端输出System.out.print(object.toString());//把json数据返回给浏览器:res.getWriter().write(object.toString());}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse res) throws IOException {System.out.println("pos..");this.doGet(req,res);}
}
3. 确定请求链接
参考AJax中的方法
**注意:**上面后端中使用JSONObject
了传递JSON数据,可参考博客:简单的后端传送json格式至前端正确处理方法
4. 项目结构
Servlet优化
情景想象:对于Student实体对象有添加(add)、查找(select)等方法,按照我旧的设计方法,会设计两个servlet类:AddStudentServlet、SelectALLStudentServlet。如果后面后续又出现了更多操作,这使得servlet类的管理出现不便。这时我可以采取与MyBatis类似的处理方法进行映射,见:MyBatis简单入门。Student专门写个成一个StudentServlet类,然后原本的AddStudentServlet、SelectALLStudentServlet写成里面的成员方法。
1.自定义servlet类重写service方法
自定义继承了HttpServlet
类的子类,并且重写protected void service(HttpServletRequest req, HttpServletResponse resp)
方法–根据请求链接来决定是调用doGet
还是doPost
之类的,源码可以见:源码,重写了该方法之后也就可以做到无需写doGet
、doPost
等方法。
ajax\src\main\java\com\mercurows\web\servlet\BaseServlet.java
package com.mercurows.web.servlet;import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;// @WebServlet("/selectUserservlet")
// 替换HttpServlet,根据请求的最后一段路径来进行分发
public class BaseServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1.1获取请求路径,即浏览器输入栏的链接String uri = req.getRequestURI();// System.out.println(uri);// 1.2获取最后一段路径,即StudentServlet中的成员方法名//这里的方法名即指int index = uri.lastIndexOf('/');String methodName = uri.substring(index + 1);// System.out.println(methodName);// 2.执行方法// 2.1 获取TeacherServlet、StudentServlet字节码对象Class// 谁调用该方法,该方法中的this就是谁Class<? extends Object> cls = this.getClass();cls.getMethods();// 2.2获取方法Method对象try {// 方法名称、方法参数对应的classMethod method = cls.getMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);// 2.3参数:调用方法的类,该方法对应的参数method.invoke(this, req, resp);} catch (NoSuchMethodException e) {e.printStackTrace();} catch (SecurityException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}
}
2. 映射servlet的类
与以往编写servlet
类要继承HttpServlet
类一样,这里因为BaseServlet
继承了HttpServlet
,所以直接继承BaseServlet
即可,如:
ajax\src\main\java\com\mercurows\web\servlet\StudentServlet.java
package com.mercurows.web.servlet;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/student/*")
public class StudentServlet extends BaseServlet {public void selectAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("Student selectAll..");}public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("Student add..");}public void del(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("Student del..");}
}
这里的@WebServlet("/student/*")
表示通配符,表示当要执行StudentServlet
中任一方法时(如selectAll方法,则路径应该是:/student/selectAll
)便会见控制权转交给对应方法。
3. 具体执行流程
运行tomcat打开项目浏览器:
假如要执行StudentServlet
中的成员方法,则具体路径为:http://localhost:8080/ajax/student/selectAll
**具体的:**当我在浏览器中输入http://localhost:8080/ajax/student/del时,执行流程如下
- 请求由服务器接收,并传递给与路径匹配的Servlet,即
BaseServlet
。BaseServlet
的service
方法被调用,传入HttpServletRequest
和HttpServletResponse
对象。- 在
service
方法内部,通过req.getRequestURI()
获取请求的URI,即/ajax/student/del
。- 然后,通过
uri.lastIndexOf('/')
获取最后一个斜杠的索引,这里是14
。- 使用
uri.substring(index)
截取最后一段路径,即/del
,并将其存储在methodName
变量中。methodName
现在包含要执行的方法名。BaseServlet
的service
方法执行完毕,控制权传递回StudentServlet
。StudentServlet
继承自BaseServlet
,因此它会继承service
方法。service
方法在StudentServlet
中未被重写,因此将调用BaseServlet
中的service
方法。BaseServlet
的service
方法将执行上述步骤来解析URI,并确定要执行的方法名为/del
。service
方法输出/ajax/student/del
和/del
的日志信息。service
方法执行完毕,请求处理完成。总结:请求首先由
BaseServlet
接收并解析URI,然后确定要执行的方法名为/del
。然后控制权传递给StudentServlet
,但由于StudentServlet
没有重写service
方法,因此将继续执行BaseServlet
中的service
方法。
4. 多个映射servlet的类
假如,现在又多了TeacherServlet.java
,同理也只需要继承BaseServlet.java
即可,而且BaseServlet.java
不需要做出任何修改。
ajax\src\main\java\com\mercurows\web\servlet\TeacherServlet.java
package com.mercurows.web.servlet;import java.io.IOException;import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@WebServlet("/teacher/*")
public class TeacherServlet extends BaseServlet {public void selectAll(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("teacher selectAll..");}public void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {System.out.println("teacher add..");}
}