js 动态调用 applet 内的方法


js、applet(java) 都是客户端脚本语言,在客户端与用户进行着一些信息交互。然而它们并不是独立的,它们也可以协作工作,互相调用来完成一些复杂的客户端操作。本文从一个项目实战例子,演示了如何使用 js 动态调用 applet 内封装的各种方法。
本文仅贴出了 FileApplet 中被调用的方法,因为 FileUploadApplet extends FileApplet,所以这些方法(public)被直接继承。

/** * added by Defonds * @param filesInfo * File Name1|File Flag Public1|File Document Language1|File Description1|File Operating System1|File Store1|File Title1|File Flag Exp1 */ public void addFileInfomation(String filesInfo,String directoryInfo,String formatInfo){ System.out.println("the file info str gived to applet is:" + filesInfo); String fileName = "",fileFlagPublic = "",fileDocomentLanguage = "",fileDescription = "", fileOperatingSystem = "",fileStore = "",fileTitle = "",fileFlagExp = ""; String[] filesInfoArr = filesInfo.split("|"); if(filesInfoArr.length > 0){ fileName = filesInfoArr[0]; fileFlagPublic = filesInfoArr[1]; fileDocomentLanguage = filesInfoArr[2]; fileDescription = filesInfoArr[3]; fileOperatingSystem = filesInfoArr[4]; fileStore = filesInfoArr[5]; fileTitle = filesInfoArr[6]; fileFlagExp = filesInfoArr[7]; } java.io.File checkinFile = new java.io.File(directoryInfo); FileInfo file = new FileInfo(checkinFile); file.setFileStore(fileStore); file.setFormat(formatInfo); file.setFileFlagPublic(fileFlagPublic); file.setFileFlagEXP(fileFlagExp); file.setFileDocumentLanguage(fileDocomentLanguage); System.out.println("applet-filename=" + file.getFileName()); addFile(file); System.out.println("a file added successfully!"); } /** * @added by Defonds * @param directoryStr * D:/tmp/tmp/AppDevGuide1071.pdf@@@D:/tmp/tmp/AppDevGuide1072.pdf@@@... * @return * D:/tmp/tmp/AppDevGuide1071.pdf@@@D:/tmp/tmp/AppDevGuide1072.pdf... * @note * only return the directories which are valid */ public synchronized String directoryValid(String directoryStr){ System.out.println("the file directory info give to applet is:" + directoryStr); _fileValidStr = directoryStr; FileValidRunner runner = new FileValidRunner(); AccessController.doPrivileged(runner); System.out.println("applet return value is:" + _fileValidStrRe); return _fileValidStrRe; } /** * @author defonds */ class FileValidRunner implements PrivilegedAction { public Object run() { String[] direArrs = _fileValidStr.split("@@@"); if(direArrs.length > 0){ for(int i = 0;i < direArrs.length;i ++){ String tmpName = direArrs[i]; java.io.File tmpFile = new java.io.File(tmpName); if(tmpFile.exists()){//only return the directories which are invalid if(_fileValidStrRe.equals("")){//the first one _fileValidStrRe = tmpName; }else{//not the first one _fileValidStrRe += "@@@" + tmpFile; } } } } return null; } FileValidRunner() { } }
 addFileInfomation 是 js 向 applet 传递一些服务器提供的文件信息,诸如文件名(含完整的路径信息)、文件格式、文件内容语言、操作系统…
 directoryValid 是 js 调用 applet 方法,对一系列的文件路径进行验证,applet 把有效的(即本地确实存在此文件)文件路径进行返回。
 本文仅演示 js 调用 applet 的 directoryValid 方法对文件路径进行验证的例子,addFileInfomation 方法的例子、directoryValid 被调用的完整例子都可以去示例程序下载链接进行下载。
 步骤一:
 编写并编译 applet 程序,然后打包并进行数字签名后把 jar 包放在项目中的自定义目录 common 下。详细过程可以参考作者的博客《一次 applet 客户端打印 jasperreport 报表任务笔记》,这里不再赘述。
 步骤二:
 jsp 中编写 java 脚本,提供 addApplet 方法,以备服务器添加客户端的 applet 应用:<%! void addApplet(JspWriter out, String plugInCodeBase, String appletClass,String name,String codeBase,String jarFiles, int width, int height,HashMap props ) throws Exception { // load java plug-in using dynamic versioning // if installed version of the plug in is 1.4 or above then do not download // else download from the URl specified by codebase property out.println("<OBJECT classid = 'clsid:8AD9C840-044E-11D1-B3E9-00805F499D93'"); out.println(" name = '" + name + "'"); out.println("codebase='" + plugInCodeBase + "#Version=1,4,0,0'" ); out.println("WIDTH ='" + width + "' HEIGHT ='" + height + "'>"); out.println("<PARAM NAME='java_code' VALUE ='" + appletClass + "'>"); out.println("<PARAM NAME='java_codebase' value='" + codeBase + "'>"); out.println("<PARAM NAME='java_archive' value='" + jarFiles + "'>"); out.println("<PARAM NAME='type' VALUE ='application/x-java-applet;version=1.4'>"); out.println("<PARAM NAME='scriptable' VALUE ='true'>"); String key; out.println("<COMMENT>"); out.println("<EMBED type ='application/x-java-applet;version=1.4'"); out.println(" CODE ='" + appletClass + "'"); out.println(" name ='" + name + "'"); out.println(" java_code='" + appletClass + "' java_codebase='" + codeBase + "' java_archive='" + jarFiles + "'"); out.println(" WIDTH ='" + width + "' HEIGHT ='" + height + "' scriptable =true"); out.println("pluginspage = 'http://java.sun.com/products/plugin/index.html#download'>"); out.println("<NOEMBED>"); out.println("alt='Your browser understands the <APPLET> tag but isn/'t running the applet, for some reason.'"); out.println("Your browser is completely ignoring the <APPLET> tag!"); out.println("</noembed></embed></COMMENT></OBJECT>"); } %>
 步骤三:
 jsp 中编写 java 脚本,调用 addApplet 方法添加客户端 applet 服务: String codeBase = Framework.getFullClientSideURL(request,response,"") + "/common"; String plugInCodeBase = null; String jarFiles = ""; jarFiles = "asbAttachmentUploadApplet.jar"; String userAgent = request.getHeader("User-Agent"); userAgent = userAgent.toLowerCase(); if(userAgent.indexOf("x11") != -1 || userAgent.indexOf("hp-ux") != -1 || userAgent.indexOf("sunos") != -1){ plugInCodeBase = (String)FrameworkProperties.getProperty("emxFramework.Unix.JavaPlugInURL"); if(plugInCodeBase == null || "".equals(plugInCodeBase) || "null".equals(plugInCodeBase)){ plugInCodeBase = "http://java.sun.com/j2se/1.4.2/download.html"; } }else{ plugInCodeBase = (String)FrameworkProperties.getProperty("emxFramework.Windows.JavaPlugInURL"); if(plugInCodeBase == null || "".equals(plugInCodeBase) || "null".equals(plugInCodeBase)){ plugInCodeBase = "http://java.sun.com/products/plugin/autodl/jinstall-1_4-windows-i586.cab"; } } int appletWidth = 0; int appletHeight = 0; addApplet(out, plugInCodeBase, "com.matrixone.fcs.applet.FileUploadApplet","upload",codeBase,jarFiles,appletWidth,appletHeight,null);
 步骤四:
 js 中编写 getApplet 方法,获取 applet 对象: function getApplet(){ if (document.applets.length > 0){ return document.applets[0]; }else if(document.embeds.length > 0){ return document.embeds[0]; }else{ alert("<emxUtil:i18nScript localize="i18nId">emxComponents.Common.CanNotStartApplet</emxUtil:i18nScript>"); return ""; } }
 步骤五:
 js 中对 applet 中封装的方法的调用: function next(){ var numOfValid = <%=numOfValidFiles%>; if(numOfValid < 1){ alert('There is no file valid to upload!'); return; } var validDirs = getApplet().directoryValid('<%=directoryStr%>'); parent.document.location = "asbEngrDocumentImportCheckinAppletsFS.jsp?xyz=xyz&validDirs=" + validDirs; }


注:applet 中 directoryValid 返回的是 String 对象,弱类型语言的 js 得到这个对象时会进行自动转换。applet 中要被 js 调用的方法一定是为 public 权限。其它权限的诸如 private、default、protected 方法应该不能够被 js 调用。作者没有去尝试