通用Servlet Ajax请求 /do 处理所有请求,反射机制

时间:2023-01-13 11:36:47
//我们来看下通用ajax 对应的js//其中action为系统内对应的Action类,method 对应的是类中的方法,page和id 可以为"",param为传入参数,//func为回调函数,p1-p8均为回调函数传递的参数
function callObjectAction(action, method, page, id, param, func, p1, p2, p3, p4, p5, p6, p7, p8) {
if (!Me._id) {
    window.open('index.html','_self');
  } else {
    var sPost = '{"a":"'+action+'","c":"'+method+'","k":"' + page + '","i":"' + id + '","_userid":"'+ Me._id +'"';
    if (param) {
      sPost += ','+param;
    }
    sPost += '}';
//alert("post = " + sPost + "\r\n >>>   " + encrypt(sPost, Me._s).length);
    $.ajax({
      url : PostAction,
      method : 'POST',
      async : false,
      cache : false,
      //timeout : 30000,
      data : {
        a : encrypt(sPost, Me._s),
        b : "",
        c : Me._s
      },
//      beforeSend:function() {
//alert("before send");
//      },
//      complete:function() {
//alert("after success or error");
//      },
      success : function(callBackData) {
        var jsonData = eval("(" + decrypt(callBackData, Me._s) + ");");
        if (jsonData.m) {
          if (jsonData.s == '1') {
            successMessage(jsonData.m);
          } else {
            if (document.getElementById("er-" + page + "." + id)) {
              document.getElementById("er-" + page + "." + id).innerHTML = jsonData.m;
              document.getElementById("er-" + page + "." + id).style.display = "";
            } else {
              errorMessage(jsonData.m);
            }
          }
        }
        if (jsonData.c) {
          eval(jsonData.c);
        }
        if (jsonData.s=='1') {
          if (func) {
            func(jsonData,p1,p2,p3,p4,p5,p6,p7,p8);
          }
        }
      },
      error:function(callBackData) {
alert("error");
      }
    });
  }
};
//对于以上代码,PostAction对应你要请求的地址,我们暂时定义为var PostAction = "http://localhost:8080/tom/app/do";//拼接sPost参数,作为json格式传入后台,a是加密过的数据,c是当前用户id//在后台,我们配置对应的Servlet,我们拦截后缀为/app/do的请求,可以拦截所有app/do请求
	<servlet>
		<servlet-name>AppReceiver</servlet-name>
		<servlet-class>app.servlet.AppServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>AppReceiver</servlet-name>
		<url-pattern>/app/do</url-pattern>
	</servlet-mapping>


//我们这里AppServlet继承我们写好的BaseServlet基类,我们的BaseServlet继承HttpServlet
      JsonNode node = JsonUtil.getJson(sJson);
      sUser = JsonUtil.getJsonStringValue(node, "_u");
      String sClass = JsonUtil.getJsonStringValue(node, "a");
      String sFunction = JsonUtil.getJsonStringValue(node, "c");
//取出对应的类以及函数
 
String sIP = getRemoteHost(request);

//获取远程ip访问地址,具体方法函数如下://获取客户端地址 

public String getRemoteHost(javax.servlet.http.HttpServletRequest request) { String ip = request.getHeader("x-forwarded-for"); if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getHeader("WL-Proxy-Client-IP"); } if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { ip = request.getRemoteAddr(); } return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip; }


sReturn = callAction(request, response, sClass, sFunction, sToken, node, sUser);
//上面一句是关键地方,传递函数以及类,node是封装后的ip地址//下面是具体执行反射调用的过程,非常重要
 //调用执行方法
  public String callAction(HttpServletRequest request, HttpServletResponse response, String sClass, String sFunction,
      String sToken, JsonNode node, String sUser) throws Exception {
    String sResult = "";
    Class[] aParams = new Class[4];
    Object[] aValues = new Object[4];
    aParams[0] = HttpServletRequest.class;
    aParams[1] = HttpServletResponse.class;
    aParams[2] = JsonNode.class;
    aParams[3] = String.class;
    aValues[0] = request;
    aValues[1] = response;
    aValues[2] = node;
    aValues[3] = sUser;

    Class aClass = null;
    try {
      aClass = Class.forName(ConfigUtil.App + ".app.action.Action" + sClass);
    } catch (ClassNotFoundException e) {
      aClass = Class.forName("app.action.Action" + sClass);
    }
    sResult = "" + aClass.getMethod(CommonUtil.isNull(sFunction) ? "action" : sFunction, aParams).invoke(null, aValues);
    return sResult;
  }


//我们来分析一下,request和response对象,类名,方法名,token,node传入参数,sUser当前用户
//创建一个aParams 的类数组来保存类数据,Class.forName("app.action.Action"+sClass),
//class.forName()是运用反射的原理创建对象,平常我们创建对象都是用new方式,class.forName也是一种方式。

//在这里可以简单说下5种创建对象的方式,1:使用new关键字,调用了构造函数,2:使用Class类的newInstance方法,调用了构造函数,
//3:使用Constructor类的newInstance方法,4:使用clone方法,没有调用构造函数,5:使用反序列化,没有调用构造函数。
//如,我前台写callObjectAction("Config","goodsPutAwayCheck",'',i,sParam,loadTableOption,i,d,c,s,p,t,f);
//即调用了app.action.ActionConfig类的goodsPutAwayCheck方法,返回数据在js中已经有处理,就不再细说,完整的公用callObjectAction适用所有请求