今天的内容
1.ajax的删除:在不重新加载整个页面的情况下,只删除当前这一条数据.
实现思路1:先在前端用ajax将要删除的学生传到后台Servlet中将数据库表中当前这个学生数据给删除掉;将删除的结果响应给前端ajax,前端ajax得到结果后用 JavaScript动态删除这个学生这行记录就可以.
优点:节省带宽.
缺点:当前页面不刷新的时候每删除一条记录就少显示一条记录.
eg://删除学生,第一个参数要删除的学生姓名,第二个参数是删除的按纽节点对象
function delStu(uname1,inputObject){
var result=confirm("确定要删除当前这个学生吗?");
if (result) {
/*发送异步ajax请求到后台删除当前这个学生的数据*/
//1.创建ajax引擎对象
var ajaxObject;
if(window.XMLHttpRequest){
//新浏览器
ajaxObject=new XMLHttpRequest();
}else{
//IE5,6
ajaxObject=new ActiveXObject("Microsoft.XMLHTTP");
}
//2.创建请求
ajaxObject.open("get","TeacherServlet?method=delStudentByName&uname="+uname1,true);
//3.发送请求
ajaxObject.send();
//4.调用回调函数
ajaxObject.onreadystatechange=function () {
if (ajaxObject.readyState==4&&ajaxObject.status==200){
//接收响应结果
var result=ajaxObject.responseText;
alert(result);
//如果后台数据库表中已经将当前学生数据删除成功了,再删除前端学个学生对象就这一行
if(result=="1"){
//获得表格中要删除的这一行
var delTr=inputObject.parentNode.parentNode;
//获得要删除的这一行的父节点
var parent=delTr.parentNode;
//删除当前这一行
parent.removeChild(delTr);
alert(uname1+"删除成功");
}
}
}
}
}
实现思路2:先在前端用ajax将要删除的学生及当前页码传到后台Servlet中将数据库表中当前这个学生数据给删除掉;再根据当前页码将当页数据查询出来用模板页面展示再将模板页面返回给ajax,ajax再根据模板页面将当前数据展示部分用模 板页面替换.
优点:用户体验度高.
缺点:相对第一种删除耗带宽.
function delStu(uname1,curr){
var result=confirm("确定要删除当前这个学生吗?");
if (result) {
/*发送异步ajax请求到后台删除当前这个学生的数据*/
//1.创建ajax引擎对象
var ajaxObject;
if(window.XMLHttpRequest){
//新浏览器
ajaxObject=new XMLHttpRequest();
}else{
//IE5,6
ajaxObject=new ActiveXObject("Microsoft.XMLHTTP");
}
//2.创建请求
ajaxObject.open("get","TeacherServlet?method=delStudentByName&uname="+uname1+"&currpage="+curr,true);
//3.发送请求
ajaxObject.send();
//4.调用回调函数
ajaxObject.onreadystatechange=function () {
if (ajaxObject.readyState==4&&ajaxObject.status==200){
//接收响应结果
var result=ajaxObject.responseText;
//第二种ajax删除学生,第一个参数要删除的学生姓名,第二个参数是当前页面
document.getElementById("tb1").innerHTML=result;
}
}
}
}
2.用反射升级Servlet:
2.1:升级Servlet请求的处理方法
原来效果:一个servlet可以处理多个请求,但是在servlet中要写多个判断请求,再调用对应方法处理.
实现效果:http://localhost:8888/项目名/Servlet?method=方法名,直接根据请求调用对应servlet中方法.不用判断.
实现原理:抽取一个公共servlet,让所有servlet继承自公共的servlet.在这个公共servlet的service()中接收所有请求的方法名,根据方法名得到方法的反射对象调用servlet中方法.
eg:/**
* 公共servlet,重写HttpServlet的service()
* @author sx
* @version 1.0 2020-04-03
*/
@WebServlet("/FatherServlet")
public class FatherServlet extends HttpServlet {
/**
*重写父类HttpServlet的service方法
*/
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求编码和响应的编码
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
try {
//接收请求中方法名
String methodName=request.getParameter("method");
//得到当前请求Servlet的反射对象,this指代是请求的Servlet
Class servletClass=this.getClass();
//通过方法名得到方法的反射对象
Method methodObject=servletClass.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
//设置方法的权限
methodObject.setAccessible(true);
//用方法的反射对象调用对应Servlet中方法,this指代是请求的Servlet
methodObject.invoke(this,request,response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.2:升级Servlet响应
原来效果:servlet中处理请求方法都返回void,在方法中自己来决定转发,还是重定向,还是响应给ajax.
实现效果:让所有servlet处理请求的方法都返回String,在公共Servlet的service方法中统一根据返回String来判断是转发,还是重定向,还是响应给ajax
"url" 转发
"redirect:url" 实现重定向
"ajax:String" 响应字符串给ajax引擎
实现原理:因为Servlet中每个请求的方法调用都要经过Service(),
所以在Service()中调用方法时接收结果,再根据结果判断跳转就可以.
eg:protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置请求编码和响应的编码
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
try {
//接收请求中方法名
String methodName=request.getParameter("method");
//得到当前请求Servlet的反射对象,this指代是请求的Servlet
Class servletClass=this.getClass();
//通过方法名得到方法的反射对象
Method methodObject=servletClass.getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
//设置方法的权限
methodObject.setAccessible(true);
//用方法的反射对象调用对应Servlet中方法,将方法返回结果转换为String接收,因为我们设定servlet中所有方法返回String. this指代是请求的Servlet
String result= methodObject.invoke(this,request,response).toString();
//根据方法返回结果来判断是转发还是重定向还是ajax
//result="url" 转发
//result="redirect:url" 实现重定向
//result="ajax:String" 响应字符串给ajax引擎
if (result.startsWith("redirect:")){
//重定向
//将重定向的url从result拆分出来
String url=result.substring(result.indexOf(":")+1);
System.out.println("*****"+url);
//重定向
response.sendRedirect(url);
}else if(result.startsWith("ajax:")){
//响应给ajax引擎
//将响应的内容拆分出来
String content=result.substring(result.indexOf(":")+1);
//将内容响应给ajax引擎对象
response.getWriter().write(content);
}else{
//转发
request.getRequestDispatcher(result).forward(request,response);
}
} catch (Exception e) {
e.printStackTrace();
}
}
2.3:升级Servlet的接收请求数据:
原来效果:要接收请求中数据用request.getParameter()或request.getParameterValues()方法来接收,一但请求中数据参数比较多时,接收数据麻烦.
实现效果:传一个对象给我,就可以用这个对象直接一次接收请求中值.
实现原理:在公共Servlet中声明一个方法,先用getParameterMap()将请求中所有参 数以key-value对方式接收,再用反射对象将请求中数据封装到对象的属性中.前提:表单的name属性名或者说是参数Key名要与实体对象的属性一一对应.
eg: /**
*用一个对象接收请求中参数的数据
*@param clazz, request, response
*@return
*/
public <T> T requestMap(Class<T> clazz,HttpServletRequest request,HttpServletResponse response) throws IllegalAccessException, InstantiationException, NoSuchFieldException{
//1.用请求对象接收请求中所有参数
Map<String,String[]> values= request.getParameterMap();
/*2.处理请求中数据,将请求中接收value值转换String*/
//声明一个新集合存请求中处理数据
Map<String,String> hmap=new HashMap<String, String>();
//遍历原来的集合,将原来的数据处理完后复制新集合中
for (String key:values.keySet()){
if (key!=""){
//将参数的value值String[]转换为string,[eat,sleep]
String newValue=Arrays.toString(values.get(key));
System.out.println("###"+newValue.substring(1,newValue.length()-1));
//将接收值存新集合中
hmap.put(key, newValue.substring(1,newValue.length()-1));
}
}
/*3.将接收值用反射封装到实例对象中,前提条件是实例对象的属性名与接收参数的key值一一对应*/
//用反射对象获得实例对象
T t1=clazz.newInstance();
//用commons-beanutils工具包中类,将对象的属性用反射赋值,前提条件是对象的属性名与Map集合中Key名一一对应
//commons-beanutils工具包要与commons-logging包一起使用
try {
BeanUtils.populate(t1,hmap);
}catch (Exception e){
e.printStackTrace();
}
return t1;
}