# AJAX组件

平台封装了一套AJAX组件,这套组件可以直接调用Manager层的业务方法,使用较为方便。

# 标准AJAX组件(推荐)

要实现AJAX,需要做如下动作:

1)确定哪个Manager的哪个方法可以被前台AJAX调用,然后在对应方法头加上@AjaxAcces注解

2)前台JSP引入common_footer.jsp,再使用前端包装方法callBackendMethod执行AJAX请求

具体做法如下:

第一步:Java后台使用Ajaxaccess注解注册

找到后台需要注册AJAX的Manager接口,在其方法上增加AjaxAcces注解,代码如下:

package com.seeyon.apps.demo.manager;

import java.util.Map;
import com.seeyon.ctp.common.exceptions.BusinessException;
import com.seeyon.ctp.util.annotation.AjaxAccess;


public interface DemoManager {
 /**
  * 保存
  * @param params
  * @throws BusinessException
  */
 @AjaxAccess
 public void saveDemo(Map<String,Object> params) throws BusinessException;

}

第二步:前端执行AJAX调用

如果是JSP页面,可以在引入common_footer.jsp的前提下,调用callBackendMethod进行AJAX请求:

<%@include file="/WEB-INF/jsp/common/common_footer.jsp"%>
<script type="text/javascript">
var params = {};
params.id=xx;
params.name=yy;
params.title=zz;
/**
 * demoManager:对应Spring bean id
 * saveDemo:对应demoManager interface下的方法
 * params:对应saveDemo方法里面的参数
 */
callBackendMethod("demoManager","saveDemo",params,{
    success : function(ret){
        //这是异步的AJAX请求方法
        $.alert("保存成功!");
    },
    error : function(request, settings, e){
        $.error("异常:"+e);
    }
});//end of callBackendMethod
</script>

默认callBackendMethod采用异步返回,如果开发需要阻塞等待结果返回,则可以采用同步的形式:

注意:一般都不推荐使用同步AJAX,编写代码时尽量使用异步模式

//同步AJAX格式,如下请求会等待AJAX执行结束之后再继续
var projectName=callBackendMethod("projectQueryManager","getProjectName",relateProjectId);

前端AJAX实现原理:参考jsonGateway-debug.js文件:

function callBackendMethod(managerName, methodName) {
  var url = (typeof(window._ctxPath) !== "undefined" ? window._ctxPath : v3x.baseURL)+'/ajax.do?method=ajaxAction&managerName=' + managerName;
  return ajaxCallFuncInner(url, methodName, Array.prototype.slice.call(arguments, 2));
}

# 早期ajaxStub[不推荐]

在老工程可能会看到如下的代码实现方式,这是采用ajaxStub.do存根的方案:

var demoAjax = new demoManager();
demoAjax.saveDemo(params,{
    success : function(ret){
        $.alert("保存成功!");
    },
    error : function(request, settings, e){
        $.error("异常:"+e);
    }
});

其原理就是:启动OA的时候,后端会扫描所有带有Ajax注解信息的类和方法,然后将其封装成一个前端javascript可使用的ajaxStub.js文件,放在seeyon目录下。

只要引用了ajaxStub.js文件的页面,都可以用过new Manager().callMethod()这种对象调用的形式来开发,其实这就是一个AJAX JSSDK。

之所以不推荐使用是因为ajaxStub.js日渐庞大,页面引用要耗费资源时间,影响页面加载速度。

<script type="text/javascript" src="${path}/ajaxStub.js?v=<%=com.seeyon.ctp.common.SystemEnvironment.getLastNodeStartTime()%>"></script>

实现原理参见平台AjaxAuthenticator、AjaxAccessInterceptor、AjaxController、jsonGateway-debug.js。

# 远古getAjaxDataServlet(不推荐)

下面这是更早期的AJAX封装实现,现在已经全面不推荐了,如果看到历史代码可以知晓这个实现原理。

第一步:后台注册:/cfgHome/*-ajax.xml方法

在\src\main\webapp\WEB-INF\cfgHome\路径下,*-ajax.xml文件中,进行对应模块map属性的配置。

示例代码展示了对公文发文、后台格式、项目管理等模块的配置,如下所示:

<map>
        <!-- 公文发文支持手工输入单位 -->
        <entry key="ajaxEdocExchangeAccountManager" value="exchangeAccountManager" ></entry>
        <!-- 后台格式设置 -->
        <entry key="ajaxContentTemplateManager" value="contentTemplateManager" ></entry>
        <!-- 项目管理 -->
        <entry key="ajaxProjectManager" value="projectManager" ></entry>
        <entry key="ajaxHandWriteManager" value="handWriteManager" ></entry>
        <entry key="ajaxWpsAssistManager" value="wpsOfficeApi" ></entry>
        <!-- 会议室管理 -->
        <entry key="ajaxMeetingRoomManager" value="meetingRoomManager" ></entry>
        <!-- 综合办公管理 -->
        <entry key="ajaxOfficeCommonManager" value="officeCommonManager" ></entry>
        <!-- 办公用品管理 -->
        <entry key="ajaxStockManager" value="stockManager"></entry>
</map>

第二步:前端调用:callBackendMethod调用

与平台ajax.do的新方式相似,callBackendMethod也将managerName和methodName两个参数传到前端;与新方式不同的是,由于老版本的ajax通过采用Servlet方法,调用callBackendMethod传值时还需传递相应Servlet的SessionId。

以下代码为该方法调用实例代码,三个参数分别为managerName,methodName和SessinId。

callBackendMethod("loginUserManager","isLeave",getDogSessionId(),{
         success : function(result){
          if(result == "__LOGOUT"){
           alert($.i18n('loginUserState.unknown')+',原因:检测到用户已退出!');//loginUserState.unknown
           exitCurrentSystem();
          }
          else if(result.isLeave==true){
                 showAuthenticationDialog({'avatar':result.avatar});
             }else{
                 unlockAllScreen();
             }
             isDoubleCommit = false;
         },
         error : function(request, settings, e){
          $.alert($.i18n('login.label.lose.connection.desc'));
          isDoubleCommit = false;
         }
     });

实现原理:参考AjaxAuthenticator类。

编撰人:het、admin