问题的提出:
假定我们的html 页中有一些表单需要处理,并且我们需要初始化数据库中的字段,我们该怎么办?标准的解决办法就是使用cgi脚本或是使用java servlet等服务器端程序,但是你有没有想过,还可以编写一个脚本程序使你可以用javascript直接调用服务器端java程序进行任何计算的结果,就像下面代码中列的那样:
| <html> 我们的表单<br> <form> <input type="text" name="textfield"><br> <input type="button" value="click" onclick="updatefield();"> </form> <script> function updatefield() { document.forms[0].textfield.value=java.dbconnection.getdata('sql_expr'); } </script> </html> |
所以,当用户点击按钮,该程序就会调用java的dbconnection类,然后就可以在javascript应用程序中使用java返回的结果了。上面的程序只是更新了textfield的值,我们不必刷新整个页面。由于这个程序也不是jsp文件,所以不必把你的页面编译成java servlet。
你还可以使用调用某些java函数返回的结果替代段落中的文字;在一个非常大的html表中,你可以使用同样的方法,只要更新一行信息:
| <script language="javascript"> function changecol() { document.all.quote.rows[0].cells[1].innertext=java.stock.getquote('wayne'); } </script> <table id="quote" border=1> <tr><td>wayne</td><td>123</td></tr> <tr><td>another one</td><td>34</td></tr> </table> |
怎么样,能够直接在javascript中嵌入java对象的调用,而且可以保证你的页面的其它部分不会被改变,你一定对这个问题比较感兴趣吧。好吧,现在就让我们用java servlet来实现它吧。
工作原理
我的构思是使用java servlet编写一个jinj(java in javascript)程序,能够让 html 页面内整合 java 类和 javascript脚本,将所有使用javascript调用java函数的html页面都传送到这个servlet中处理,jinj将即时产生带有java applet的隐藏帧,这个applet起着桥梁的作用,用来和java通讯,它的大小还不到2kb,为了调用对象,applet使用http连接同一个jinj servlet。jinj用相应的javascript结构来替换所有的java调用(其实每一个调用前都有前缀java),并且保持页面的其它部分不变。所以,为了能够让jinj正确识别,你的javascript代码中的任何java调用,都要使用如下的结构: java.object_name.function_name(list_of_parameters) 其中:
java:是一个标准的前缀:
object_name:是一个变量名,保存某些java类的实例(在后面,我们会详细的探讨如何创建/定义这样的变量),比如说它可以是一个类名。
function_name:是一个java类的函数名。
list_of_parameters:是调用的函数的参数列表(可以为空)。
下面也将会探讨如何把参数传给java,每个参数显然是某个javascript表达式。你也可以使用预编译页,换句话说就是在使用html页面之前编译它。
服务器实现
在谈编程之前我还想说一说jinj的服务器实现。在你的服务器中需要两个组成部分:jinj servlet和bridge applet.。你所有需要被整合的html页面都是被jinj servlet预处理,你可以通过以下方法实现:
a)把你的页面当作一个参数传递给jinj servlet
所以你可以把你html页中如下的超链接<a href="mypage.html">我的页面</a>改为:<a href="http://myhost/servlet/jinj?mypage.html" target="_top">我的页面</a>
jinj servlet 随即把所有的java调用转化成javascript,然后产生页面并输出出来。
b)定义某种映射。举例来说,这里我们设置servlet调用扩展名为.jinj的文件 (这里介绍的方法针对运行于nt上的jswdk,你所使用的servelt系统的具体定义映射的方法请参看你的用户指南)
jinj.code=jinj
jinj.initparams=servlet=http://myhost/servlet/jinj,
root=c://jswdk//webpages,
objects=c://jswdk//obj.txt,
codebase=http://myhost/
设置了以后,你就可以使用http://myhost/some_file.jinj然后jinj servlet将会自动被调用了
servlet参数
为了让jinj正常运行,还应当能够为jinj servlet设置一些全局参数,这也是我们在编程是应当注意到的问题。对于jswdk, servlet属性是参数'initparams'的一部分;对于tomcat,则应当编辑系统中的web.xml
1)需要设置jinj servlet的路径,参数名是servlet,就像这样:
http://your_host:port/servlet/jinj
2) 需要设置存放html页的根目录,参数名是root,其值就像这样: /home/webpages (或c:/webpages) (默认值是一个空的字符串)。 例如,如果你的根目录是:/home/webpages,并且你使用http://host/servlet/jinj?myfile.htm 的话,那你的真实的文件名是/home/webpages/myfile.htm
3) 需要设置你定义的java对象的文件的完全目录,参数名是objects,其值只是一个存放在你的服务器中的一个文件的文件名。
4) 需要设置用于java applet的codebase,参数名是codebase,定义了存放applet的类的路径,比如http://your_host/ 。
以下为tomcat中web.xml 中的相应设置:
| <servlet> <servlet-name>jinj</servlet-name> <servlet-class>jinj</servlet-class> <init-param> <param-name>servlet</param-name> <param-value>http://your_host/servlet/jinj</param-value> </init-param> <init-param> <param-name>root</param-name> <param-value>path_to_the_root_directory</param-value> </init-param> <init-param> <param-name>objects</param-name> <param-value>path_to_your_objects_file</param-value> </init-param> <init-param> <param-name>codebaset</param-name> <param-value>http://your_host/</param-value> </init-param> </servlet> |
在编程时还应当注意实现读取对象文件中所包含的对象,或创建新的java对象
1. 在初始化jinj servlet时将创建一些java对象,因此你必须在某个文本文件中定义这些对象,并且在参数objects中设置这个文件的路径,这是一个文本文件,每一行描述了一个元素(空行和以#或//开头的行将被忽略),使用下面的格式来描述参数:
object_name=new class_name(list_of_parameters);
换句话说,它很象每次调用类构造器的new操作符,object_name 是就是某个你将在javascript中使用到的标识符,例如:
file://数据池
a=new dbpool(5);
file://哈希表
b=new java.util.hashtable();
或者使用你自己定义的包和类:c=new mypackage.myclass(true);
然后在javascript中,你就可以使用它们了,如a.connect(),其中connect() 是类dbpool的一个函数,或者使用b.put('key',value)
注意:
1)你的类应当放在你的classpath指定的目录下面。
2)你可以使用类名作为对象名 (不过这必须在没有重名的情况下,因为对象名必须是唯一的),如:dbpool=new dbpool();
2. 为了更优化程序,应当在编程的时候就预建一些对象组成标准化库,通过标准化库,你可以在运行中创建/删除对象的实例,查看存在的对象等。
下面就是我们需要实现的标准化库(预定义的对象) ,对象名是jinj,所以服务器端名为jinj的实例将会被自动创建,这给类中有下面几个函数:
public boolean create(string object_name,string class_name,list_of_constructors_parameters); public void delete(string object_name); public boolean exists(string object_name); public string id(); public int random(int n1, int n2); public string rewriteurl(document,string id_name); public string rewriteurl(document,string id_name,string id_value); |
create(创建):能够让你在运行时创建某个对象的实例:
参数为:
- 新的对象名
- 类名
- 参数列表 (如果你使用默认构造函数的时候,可以为空)。
返回值:
- 根据创建的接过返回true 或 false
例如:
| <script language="javascript"> <!--创建myhash 作为一个新的哈希表hashtable --> java.jinj.create("myhash","java.util.hashtable"); <!-- 使用myhash --> java.myhash.put('key1','shop1'); </script> delete:让你删除任何对象的实例。 参数为: - 对象名 例如: <script language="javascript"> <!-- 删除myhash --> java.jinj.delete("myhash"); </script> exists:查看对象的实例是否存在。 参数为: - 对象名 返回值: true 或 false 例如: <script language="javascript"> if (java.jinj.exists("myhash")=='false') { <!--创建myhash 作为一个新的哈希表hashtable --> java.jinj.create(myhash,"java.util.hashtable"); <!--使用myhash --> java.myhash.put('key1','shop1'); } </script> id: 返回唯一的标示符,比如你可以在支持session的程序中使用这个函数。 random: 从给定的数域中返回随机值: 例如: <script language="javascript"> var sessionid=java.jinj.id(); <!-- 从1到10中的随机数 --> var randvalue=java.jinj.random(1,10); </script> rewriteurl:能够让你使用session。你可以用<a href="some_url? id_name=id_value">你的链接</a>来替代<a href="some_url">你的链接</a>这同样适用于任何形式的动作。你可以只设置一个参数名,参数值将自动生成,也可以同时设置参数名和参数值: 例如: <script language="javascript"> <!--添加sessionid=某个值到这个链接 --> java.jinj.rewriteurl(document,'sessionid'); <!-- 添加 id=12345 到这个链接--> java.jinj.rewriteurl(document,'id',12345); </script> |
我们还要能够分析读入java函数的参数,对于一个参数我们必须知道它的数据类型,为了简单起见,我们就认为有四种数据类型整型,浮点型,布尔型其余的全归于字符串型,你可以看到,这在程序中都有相应的解释。
例如:
<!-- 我们假定a(int,float,string,boolean) --> java.myclass.myfunc(2, 5.6, a123, true); |
为了保证你传递的参数是一个字符串型的值的话,请你使用"或者',如:
<!--总是作为字符串型数据传递--> java.myclass.myfunc("256"); |
函数返回的结果问题
如果java函数的类型为void的话,那么将返回给javascript一个空字符串,在别的情况下(如果不是数组),将返回java对象的字符型返回值。如果你的java函数返回数组或者向量(vector)或枚举(enumeration),结果将被表示为javascript中的数组。例如:在类dbpool中,你如果有某个函数performquery(some_sql_string)来通过jdbc来调用sql查询,将转换resultset成为数组(或向量)然后把这个数组返回给javascript。
res=java.dbpool.performquery("select * from emp"); first=res[0]; second=res[1]; |
程序还应该实现控制台(jinj控制台),这样你就可以直接从浏览器中运行这个servlet,并且可以创建/删除对象,相应的命令是: http://your_host/servlet/jinj?your_password
或者,如果你使用扩展名映射jinj的话,则::
http://your_host/your_file.jinj?your_password ,这些都应当在程序中体现,你可以在servlet的初始化参数中设置口令,参数名是admin. 如:
| jinj.code=jinj jinj.initparams=admin=secret, servlet=http://myhost/servlet/jinj, root=/home/www/pub, objects=/home/load/obj.txt, codebase=http://myhost/ 默认的密码值是abcd,所以使用jinj?abcd 将运行管理员界面,通过这一页,你可以删除或者创建新的对象的实例。 |
下面,然我们来看看具体在java代码上如何实现我们的构思:
jinj.java
| import java.io.*; import java.lang.reflect.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class jinj extends httpservlet { public jinj() { } public void init(servletconfig servletconfig)//初始化 throws servletexception { super.init(servletconfig); inst = new hashtable(); cls = new hashtable(); newline = system.getproperty("line.separator"); file://获取行分割符在本系统中的属性值,例如在unix下为/n separator = system.getproperty("file.separator");//获取文件分割符在本系统中的属性值,例如在unix下为/ if((this_servlet = getinitparameter("servlet")) == null) file://getinitparameter方法,返回一个字符串,包含命名的初始化参数的值,如果参数不存在则为空。 this_servlet = ""; if((admin = getinitparameter("admin")) == null) admin = "abcd"; if((document_root = getinitparameter("root")) == null) document_root = ""; if(document_root.length() > 0 && !document_root.endswith(separator)) file://如果document_root的长度为正值,并且不以文件分割符结尾则 document_root = document_root + separator; if((codebase = getinitparameter("codebase")) == null) codebase = ""; java_file = getinitparameter("objects"); if(java_file != null && inst != null) loadjava(java_file); } private void loadjava(string s) { system.out.println("从" + s +"调用java对象 "); try { bufferedreader bufferedreader = new bufferedreader(new inputstreamreader(new fileinputstream(s))); file://创建一个文件输入流缓冲区 string s1; file://开始分析文件 while((s1 = bufferedreader.readline()) != null)//每次读入一行 { s1 = s1.trim(); file://把字符串两端的空格去掉 /********************************************************* * 如果以";"结尾则去掉";" **********************************************************/ if(s1.endswith(";")) s1 = s1.substring(0, s1.length() - 1).trim(); /***************************************************************************** * 如果s1的长度大于零,并且第一个字符不为#和//,则调用processline处理这一行参数 ******************************************************************************/ if(s1.length() > 0 && s1.charat(0) != '#' && !s1.startswith("//")) processline(s1); } bufferedreader.close(); return; } catch(exception _ex) { return; } } private void processline(string s) { /************************************************************************** *取得这一行中第一次出现等号的下标值,如果没出现等号则返回-1 *如果没有等号,则输出错误信息 **************************************************************************/ int i = s.indexof("="); if(i <= 0 || i == s.length() - 1) { system.out.println("不能处理此行信息: " + s); return; } string s1 = s.substring(0, i).trim();//s1为s中等号前的字符串 string s2 = s.substring(i + 1).trim();//s2为s中等号后的字符串 if(s2.startswith("new "))//判断s2是否以new开头,如new class_name(list_of_parameters); s2 = s2.substring("new".length()).trim(); if(s1.length() == 0 || s2.length() == 0) { system.out.println("不能处理此行信息: " + s); return; } if(inst.get(s1) != null) file://为了防止重复定义类名 { system.out.println("重复命名 " + s1); return; } i = s2.indexof("("); if(i <= 0 && !s2.endswith(")")) { system.out.println("不能处理此行信息:" + s); return; } string s3 = s2.substring(0, i).trim();//s3为新定义的类名 s2 = s2.substring(i + 1, s2.length() - 1).trim();//s2为参数列表 if(inst.size() < 5) processline1(s1, s3, s2, s); } |
| private string preparestring(string s) { if(s == null) return null; if(s.length() < 2) return s; if(s.charat(0) == '"' && s.charat(s.length() - 1) == '"') file://如果字符串s以"开头,又以"结尾,则把两头的"去掉 return s.substring(1, s.length() - 1); if(s.startswith("'") && s.endswith("'"))//如果字符串s以'开头,又以'结尾,则把两头的"去掉 return s.substring(1, s.length() - 1); else return s; } private boolean processline1(string s, string s1, string s2, string s3) { file://创建一个object类的实例 object obj[] = { null, null }; class class1; if((class1 = (class)cls.get(s1)) == null) try { class1 = class.forname(s1);//返回具有s1指定的类名的类的class描述符 cls.put(s1, class1); file://放回哈西表 } catch(exception _ex) { system.out.println("不能装载类 " + s1); return false; } obj[0] = class1; if(s2.length() == 0) { try { obj[1] = class1.newinstance();// 创建类的新实例 } catch(nosuchmethoderror _ex) { system.out.println("不能创建对象的实例 " + s3); return false; } catch(exception _ex) { system.out.println("不能创建对象的实例 " + s3); return false; } inst.put(s, ((object) (obj))); } else { object obj1[] = getparamarray(s2, 0); file://取得参数列表 if(obj1 == null) { system.out.println("不能处理这行参数: " + s3); return false; } try { constructor cons = class1.getconstructor((class[])obj1[0]);//使用参数列表构建类构建器 if(class1 == null) { system.out.println("不能创建对象的实例 " + s3); return false; } obj[1] = cons.newinstance((object[])obj1[1]); inst.put(s, ((object) (obj))); } catch(exception _ex) { system.out.println("不能创建对象的实例 " + s3); return false; } } return true; } |
| private object[] getparamarray(string s, int i) file://取得s中所包含的参数列表,存入一个object数组中 { string s1 = s.trim(); file://去除末尾的空格 string s6 = ","; vector vector = new vector(); if(s1.length() > 0) { if(s1.charat(0) == '(')//去掉( s1 = s1.substring(1); if(s1.endswith(")"))//去掉) s1 = s1.substring(0, s1.length() - 1); string s2 = s1.trim(); file://去掉字符串后的空格 if(s2.length() == 0 && i == 0) file://如果s2长度为零,说明没有参数 return null; string s4; if(s2.length() > 0) { if(s2.charat(0) == '"')//如果s2以"开头,则用/"代替 s6 = "/""; else if(s2.charat(0) == '/'')//如果s2以/'开头,则用'代替 s6 = "'"; else s6 = ","; s4 = s2.substring(0, 1); file://取得s2的第一个字符 s2 = s2.substring(1);//取得s2的第二个字符往后的字符 } else { s4 = ""; } for(; s2.length() > 0; s2 = s2.substring(1))//这些语句是为了把参数表中的参数分离出来 { string s5 = s2.substring(0, 1);//取得s2的第一个字符 if(s5.equals(s6)) file://如果s5和s6相等,即判断s5是否为两个参数的分隔符 { if(s6.equals("/"") || s6.equals("'"))//如果s6为/"或',则 s4 = s4 + s6; vector.addelement(s4); file://把s4(即一个参数值)加入vector中 s2 = s2.substring(1).trim(); s4 = ""; if(s2.length() == 0) break; s4 = s2.substring(0, 1); if(s4.charat(0) == ',') file://如果s4以","开头,则判断s4是否以分隔符开头 { s2 = s2.substring(1).trim(); s4 = ""; if(s2.length() == 0) break; s4 = s2.substring(0, 1); } if(s4.charat(0) == '"') s6 = "/""; else if(s4.charat(0) == '/'') s6 = "'"; else s6 = ","; } else { s4 = s4 + s5; } } if(s4.length() > 0) vector.addelement(s4); } int j = vector.size(); file://取得向量变量vector的大小,vector中保存的都是参数值 if(j == 0 && i == 0) return null; file://没有参数 object aobj[] = new object[3]; class class1[] = new class[j + i]; object aobj1[] = new object[j + i]; aobj[0] = class1; aobj[1] = ((object) (aobj1)); aobj[2] = new integer(j + i); for(int k = i; k < j + i; k++) { string s3 = (string)vector.elementat(k - i); try file://以下的代码是为了判断,每个参数到底是什么数据类型 { file://判断是否为整型 integer integer = integer.valueof(s3); class1[k] = integer.type; aobj1[k] = integer; } catch(exception _ex) { try { file://判断是否为浮点型 float float1 = float.valueof(s3); class1[k] = float.type; aobj1[k] = float1; } catch(exception _ex2) { file://判断是否为布尔类型 s3 = preparestring(s3); if(s3.equals("true")) file://判断是否为真 { class1[k] = boolean.type; aobj1[k] = new boolean(true); } else if(s3.equals("false")) file://判断是否为假 { class1[k] = boolean.type; aobj1[k] = new boolean(false); } else { class1[k] = class$java$lang$string == null ? (class$java$lang$string = class$("java.lang.string")) : class$java$lang$string; aobj1[k] = s3; } } } } vector = null; return aobj; } |
| public void dopost(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse) throws servletexception, ioexception { doget(httpservletrequest, httpservletresponse); } public void doget(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse) throws servletexception, ioexception { string s = ""; string s1 = ""; s = httputils.getrequesturl(httpservletrequest).tostring(); file://返回一个字符串,包含请求字符串中包含的协议名,主机名,端口号以及路径,但是不包含请求的内容 int i; if((i = s.indexof("?")) > 0)//去掉s结尾的问号 s = s.substring(0, i); s1 = httpservletrequest.getquerystring();//取的请求字符串的请求内容 if(s1 == null) { parsefile(s1, httpservletrequest, httpservletresponse); return; } if(s1.equals(admin)) file://如果请求串等于admin { adminpage(httpservletrequest, httpservletresponse, s); file://进入管理员界面 return; } if(s1.equals("namiotde")) file://如果请求串为namiotde,则执行相应的执行命令 { executerequest(httpservletrequest, httpservletresponse); return; } string s2 = getfromquery(s1, "what="); file://取的动作的属性值 if(s2.equals("hframe")) { gethiddenframe(httpservletrequest, httpservletresponse);//转到隐藏帧 return; } if(s2.equals("mframe")) { getmainframe(s1, httpservletrequest, httpservletresponse); file://转到主帧 return; } else { parsefile(s1, httpservletrequest, httpservletresponse); return; } } file://管理员界面,执行添加删除对象的操作 private void adminpage(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, string s) throws ioexception { printwriter printwriter = httpservletresponse.getwriter(); string s1 = ""; string s4 = httpservletrequest.getparameter("what"); file://返回请求串中what,即动作的属性值 if(s4 != null) if(s4.equals("delete")) file://如果what的值为delete,则执行相应的操作 { for(enumeration enumeration = httpservletrequest.getparameternames(); enumeration.hasmoreelements();) { string s2 = (string)enumeration.nextelement(); if(s2.startswith("_")) { inst.remove(s2.substring(1)); s1 = s1 + " " + s2.substring(1); } } if(s1.length() > 0) s1 = "删除: " + s1; } else if(s4.equals("add")) file://如果what的值为add,则执行相应的操作 { string s5 = httpservletrequest.getparameter("oname");//取的对象名 string s6 = httpservletrequest.getparameter("jinj"); file://取得类名 string s7 = httpservletrequest.getparameter("params"); file://取得参数 if(s5 == null) s5 = ""; else s5 = s5.trim(); if(s6 == null) s6 = ""; else s6 = s6.trim(); if(s7 == null) s7 = ""; else s7 = s7.trim(); if(s7.length() > 0 && !s7.startswith("(")) s7 = "(" + s7 + ")"; if(s5.length() > 0 && s6.length() > 0 && inst.size() < 5) { string s3 = s5 + "=new " + s6 + s7;//写成标准的对象实例化形式 if(processline1(s5, s6, s7, s3)) s1 = s5 + " 被载入..."; else s1 = "不能载入" + s3; } } httpservletresponse.setcontenttype("text/html"); printwriter.println("<html>"); printwriter.println("<head>"); printwriter.println("<title>jinj 控制台</title>"); printwriter.println("</head>"); printwriter.println("<body bgcolor=/"#ffffff/">"); printwriter.println(setscript()); if(s1.length() > 0) printwriter.println("<br><i>" + s1 + "</i><br>"); printwriter.println("<h2><center>对象</center></h2>"); printwriter.println("<br>"); printwriter.println(objectstable(s)); printwriter.println("</body>"); printwriter.println("</html>"); } |
| private string setscript() { stringbuffer stringbuffer = new stringbuffer(); stringbuffer.append("<script language=/"javascript/">" + newline); stringbuffer.append("function fun(what)" + newline); stringbuffer.append("{ document.mf.what.value=what; document.mf.submit(); }" + newline); stringbuffer.append("</script>" + newline); return stringbuffer.tostring(); } private string objectstable(string s) { stringbuffer stringbuffer = new stringbuffer(); string s2 = "#d5e6e1"; stringbuffer.append("<form name=/"mf/" method=post action=/"" + s + "?" + admin + "/">" + newline); stringbuffer.append("<input type=hidden name=/"what/">" + newline); stringbuffer.append("<table width=98% border=0>"); stringbuffer.append("<tr bgcolor=#ccccff><td nowrap> </td><td nowrap>对象名</td><td nowrap>类名</td></tr>" + newline); for(enumeration enumeration = inst.keys(); enumeration.hasmoreelements();) { string s1 = (string)enumeration.nextelement(); object aobj[] = (object[])inst.get(s1); stringbuffer.append("<tr bgcolor=/"" + s2 + "/">"); stringbuffer.append("<td width=5 nowrap>"); stringbuffer.append("<input type=checkbox name=/"_" + s1 + "/">"); stringbuffer.append("</td>"); stringbuffer.append("<td nowrap>" + s1 + "</td><td nowrap>" + aobj[0] + "</td></tr>" + newline); if(s2.equals("#d5e6e1")) s2 = "#f7f7f7"; else s2 = "#d5e6e1"; } stringbuffer.append("</table>" + newline); stringbuffer.append("<br><br>"); stringbuffer.append("<table>" + newline); stringbuffer.append("<tr>"); if(inst.size() > 0) stringbuffer.append("<td align=left nowrap><input type=button value=delete onclick=/"fun('delete');/"></td>"); else stringbuffer.append("<td nowrap> </td>"); stringbuffer.append("<td nowrap> </td>"); stringbuffer.append("<td align=right nowrap>对象名 <input type=text size=10 name=/"oname/"> 类名 <input type=text size=18 name=/"jinj/"> 参数 <input type=text name=/"params/"> "); stringbuffer.append("<input type=button value=add onclick=/"fun('add');/"></td></tr>"); stringbuffer.append("</table>" + newline); stringbuffer.append("</form>"); return stringbuffer.tostring(); } file://分析文件 private void parsefile(string s, httpservletrequest httpservletrequest, httpservletresponse httpservletresponse) throws ioexception { string s1 = geturl(httpservletrequest); string s2 = getfile(s, httpservletrequest); httpservletresponse.setcontenttype("text/html"); printwriter printwriter = httpservletresponse.getwriter(); printwriter.println("<html>"); if(s1 == null) { printwriter.println("<br>找不到servlet名.请检查初始参数"); } else { printwriter.println("<frameset rows=/"*,100%/" border=0>"); printwriter.println("<frame name=/"hframe/" src=/"" + s1 + "?" + "what" + "=" + "hframe" + "/">"); printwriter.println("<frame name=/"mframe/" src=/"" + s1 + "?" + "what" + "=" + "mframe" + "&" + "df" + "=" + s2 + "/">"); printwriter.println("</frameset>"); } printwriter.println("</html>"); printwriter.flush(); printwriter.close(); } |
| private string getid()//取id命令,使用当前的时间配合随机数产生的是唯一值 { string s = ""; synchronized(sessionidlock) { long l = system.currenttimemillis(); random random = new random(); s = string.valueof(l); for(int i = 1; i <= 6; i++) s = s + (int)(1.0d + 6d * random.nextdouble()); } return s; } private string randomvalue(string s, string s1)//取随机数 { random random = new random(); int i; int j; try { i = integer.parseint(s); j = integer.parseint(s1); } catch(exception _ex) { return "对于random()无效的参数值"; } return string.valueof((int)((double)i + (double)j * random.nextdouble())); } private void executerequest(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse) file://执行请求 throws ioexception { string s = httpservletrequest.getparameter("params"); file://返回参数params的值 string s2 = ""; string s3 = ""; string s4 = ""; object aobj[] = { null, null }; int i = s.indexof("@#$"); string s1 = s.substring(0, i); file://取出"@#$"前的字符串 if(s.length() <= i + "@#$".length()) file://如果大于的话,说明@#$后还有其他的字符 s2 = ""; else for(s = s.substring(i + "@#$".length()).trim(); s.length() > 0;) { i = s.indexof("@#$"); if(i < 0) { if(s2.length() > 0) s2 = s2 + ","; s2 = s2 + s; s = ""; } else { if(s2.length() > 0) s2 = s2 + ","; s2 = s2 + s.substring(0, i); if(s.length() <= i + "@#$".length()) s = ""; else s = s.substring(i + "@#$".length()).trim(); } } i = s1.indexof("."); if(i > 0 && i < s1.length() - 1) { s3 = s1.substring(0, i); s1 = s1.substring(i + 1); } if(s3.equals("j2j")) { if(s1.equals("exists")) file://exists命令 { if(s2.length() == 0) file://参数为零显然是错误的 { s4 = "错误的标准函数调用"; } else { if((i = s2.indexof(",")) > 0) s2 = s2.substring(0, i); s4 = string.valueof(inst.get(s2) != null);//判断是否存在s2对象 } } else if(s1.equals("delete")) file://delete函数 { if(s2.length() == 0) { s4 = "错误的标准函数调用"; } else { if((i = s2.indexof(",")) > 0) s2 = s2.substring(0, i); inst.remove(s2); file://删除s2对象 s4 = ""; } } else if(s1.equals("create")) file://create函数,创建新的对象的实例 { if(s2.length() == 0 || (i = s2.indexof(",")) < 0) { s4 = "错误的标准函数调用"; } else { string s8 = s2.substring(0, i); file://s8为对象名 s2 = s2.substring(i + 1); string s9; if((i = s2.indexof(",")) < 0) { s9 = s2; file://如果没有构造参数列表则s9(类名)就等于s2 s2 = ""; } else { s9 = s2.substring(0, i); file://否则,s9(类名)为两个逗号之间的字符串 s2 = s2.substring(i + 1); file://s2是构造参数列表 } if((aobj = (object[])inst.get(s8)) != null) { s4 = "false"; } else { string s5 = s8 + "=new " + s9 + "(" + s2 + ")"; file://s5为一标准java对象实例化形式,送入processline1处理 s4 = string.valueof(processline1(s8, s9, s2, s5)); } } } else if(s1.equals("id"))//id命令 s4 = getid(); else if(s1.equals("random")) file://random命令 { if((i = s2.indexof(",")) < 0) file://如果没有两个参数的话,出错 s4 = "错误的标准函数调用"; else s4 = randomvalue(s2.substring(0, i), s2.substring(i + 1)); file://取随机值 } else { s4 = "错误的标准函数调用"; } } else if((aobj = (object[])inst.get(s3)) == null) { s4 = "不能发现" + s3+ "的实例"; } else { class class1 = (class)aobj[0]; object obj = aobj[1]; try { if(s2.length() > 0) { object aobj1[] = getparamarray(s2, 0); file://从s2中取出参数列表 method method = class1.getmethod(s1, (class[])aobj1[0]); object obj2 = method.invoke(obj, (object[])aobj1[1]); if(method.getreturntype().getcomponenttype() == null) { string s6 = method.getreturntype().tostring(); if(s6.indexof("java.util.vector") > 0)//判断s6中是否有java.util.vector { if(obj2 == null) { s4 = ""; } else { vector vector = (vector)obj2; if(vector.size() == 0) { s4 = ""; } else { for(int j = 0; j < vector.size(); j++) { s4 = s4 + "@#$"; s4 = s4 + (string)vector.elementat(j); } } } } else if(s6.indexof("java.util.enumeration") > 0) { if(obj2 == null) { s4 = ""; } else { enumeration enumeration = (enumeration)obj2; if(!enumeration.hasmoreelements()) s4 = ""; else while(enumeration.hasmoreelements()) { s4 = s4 + "@#$"; s4 = s4 + (string)enumeration.nextelement(); } } } else if(obj2 == null) s4 = ""; else s4 = string.valueof(obj2); } else { for(int k = 0; k < array.getlength(obj2); k++) { s4 = s4 + "@#$"; if((obj = array.get(obj2, k)) != null) s4 = s4 + obj; } } } else { method method1 = class1.getmethod(s1, null); object obj3 = method1.invoke(obj, null); if(method1.getreturntype().getcomponenttype() == null) { string s7 = method1.getreturntype().tostring(); if(s7.indexof("java.util.vector") > 0) { if(obj3 == null) { s4 = ""; } else { vector vector1 = (vector)obj3; if(vector1.size() == 0) { s4 = ""; } else { for(int l = 0; l < vector1.size(); l++) { s4 = s4 + "@#$"; s4 = s4 + (string)vector1.elementat(l); } } } } else if(s7.indexof("java.util.enumeration") > 0) { if(obj3 == null) { s4 = ""; } else { enumeration enumeration1 = (enumeration)obj3; if(!enumeration1.hasmoreelements()) s4 = ""; else while(enumeration1.hasmoreelements()) { s4 = s4 + "@#$"; s4 = s4 + (string)enumeration1.nextelement(); } } } else if(obj3 == null) s4 = ""; else s4 = string.valueof(obj3); } else { for(int i1 = 0; i1 < array.getlength(obj3); i1++) { s4 = s4 + "@#$"; object obj1; if((obj1 = array.get(obj3, i1)) != null) s4 = s4 + obj1; } } } } catch(exception _ex) { s4 = "不能从类 "+ class1.getname()+ "中调用"+ s1; } if(s4 == null) s4 = ""; } printwriter printwriter = httpservletresponse.getwriter(); httpservletresponse.setcontenttype("text/html"); printwriter.println(s4); printwriter.flush(); printwriter.close(); } private void getmainframe(string s, httpservletrequest httpservletrequest, httpservletresponse httpservletresponse) throws ioexception { printwriter printwriter = httpservletresponse.getwriter(); string s1 = getfromquery(s, "df="); file://取得数据文件所在的路径和文件名 httpservletresponse.setcontenttype("text/html"); if(s1.length() == 0) printwriter.println("<html><br>不能打开数据文件</html>"); else try { file://打开数据文件 bufferedreader bufferedreader = new bufferedreader(new inputstreamreader(new fileinputstream(s1))); string s2; while((s2 = bufferedreader.readline()) != null) { int i; while((i = s2.indexof("java.")) > 0) { string s3 = s2.substring(0, i) + "parent." + "hframe" + ".javabridge('"; string s4; for(s4 = s2.substring(i + "java.".length()); s4.length() > 0; s4 = s4.substring(1)) { if(s4.charat(0) == '(') { s3 = s3 + "'"; s4 = s4.substring(1); break; } s3 = s3 + s4.substring(0, 1); } if(needcomma(s4)) s3 = s3 + ","; s2 = s3 + s4; } printwriter.println(s2); } bufferedreader.close(); } catch(exception _ex) { printwriter.println("不能读取数据文件" + s1); } printwriter.flush(); printwriter.close(); } file://取得隐藏帧 private void gethiddenframe(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse) throws ioexception { string s = getid(); file://取得id printwriter printwriter = httpservletresponse.getwriter(); httpservletresponse.setcontenttype("text/html"); file://调用applet bridge printwriter.println("<html>"); printwriter.println("<applet code=/"bridge.class/" codebase=/"" + codebase + "/" width=10 height=10>"); printwriter.println("<param name=/"servlet/" value=/"" + geturl(httpservletrequest) + "/">"); printwriter.println("</applet>"); printwriter.println("<script language=/"javascript/">"); printwriter.println("function javabridge(fname)"); printwriter.println("{"); printwriter.println(" var s='';"); printwriter.println(" if (fname=='jinj.rewriteurl' && javabridge.arguments.length>2)"); printwriter.println(" {"); printwriter.println(" if (javabridge.arguments.length==3)"); printwriter.println(" return rewriteurl(javabridge.arguments[1],javabridge.arguments[2]);"); printwriter.println(" else"); printwriter.println(" return rewriteurl(javabridge.arguments[1],javabridge.arguments[2],javabridge.arguments[3]);"); printwriter.println(" }"); printwriter.println(" for (i=1;i<javabridge.arguments.length;i++)"); printwriter.println(" { if (s!='') { s+='@#$';}"); printwriter.println(" s+=javabridge.arguments[i]; }"); printwriter.println(" s=document.applets[0].fromjava(fname,s);"); printwriter.println(" i=s.indexof('@#$');"); printwriter.println(" if (i<0) return s;"); printwriter.println(" ans=new array(); s=s.substring(3); i=s.indexof('@#$'); j=0;"); printwriter.println(" while (i>=0)"); printwriter.println(" { ans[j]=s.substring(0,i); j=j+1; s=s.substring(i+3); i=s.indexof('@#$'); }"); printwriter.println(" ans[j]=s; return ans; "); printwriter.println("}"); printwriter.println("function rewriteurl1(s,id)"); printwriter.println("{"); printwriter.println("if (s.indexof('?')>0) return s+'&'+id+'='+'" + s + "';"); printwriter.println("return s+'?'+id+'='+'" + s + "';"); printwriter.println("}"); printwriter.println("function rewriteurl2(s,id,vl)"); printwriter.println("{"); printwriter.println("if (s.indexof('?')>0) return s+'&'+id+'='+vl;"); printwriter.println("return s+'?'+id+'='+vl;"); printwriter.println("}"); printwriter.println("function rewriteurl(doc)"); printwriter.println("{"); printwriter.println(" i=rewriteurl.arguments.length;"); printwriter.println(" if (i>1)"); printwriter.println(" {"); printwriter.println(" tmp=rewriteurl.arguments[1];"); printwriter.println(" for (j=0; j<doc.links.length; j++)"); printwriter.println(" {"); printwriter.println(" s=doc.links[j].href;"); printwriter.println(" if (s.indexof(tmp+'=')<0)"); printwriter.println(" {"); printwriter.println(" if (i==2) doc.links[j].href=rewriteurl1(s,tmp);"); printwriter.println(" else doc.links[j].href=rewriteurl2(s,tmp,rewriteurl.arguments[2]);"); printwriter.println(" }"); printwriter.println(" }"); printwriter.println(" for (j=0; j<doc.forms.length; j++)"); printwriter.println(" {"); printwriter.println(" s=doc.forms[j].action;"); printwriter.println(" if (s.indexof(tmp+'=')<0)"); printwriter.println(" {"); printwriter.println(" if (i==2) doc.forms[j].action=rewriteurl1(s,tmp);"); printwriter.println(" else doc.forms[j].action=rewriteurl2(s,tmp,rewriteurl.arguments[2]);"); printwriter.println(" }"); printwriter.println(" }"); printwriter.println(" }"); printwriter.println(" return " + s + ";"); printwriter.println("}"); printwriter.println("</script>"); printwriter.println("</html>"); printwriter.flush(); printwriter.close(); } private string getfile(string s, httpservletrequest httpservletrequest) { string s1 = httpservletrequest.getrequesturi(); string s2 = ""; if(s1.endswith("jinj") || s1.endswith("jinj.class")) { if(s == null) return null; s1 = getfromquery(s, "df="); if(s1.length() == 0) s2 = s; else s2 = s1; } else { s2 = s1; } if(s2 == null) return s2; if(s2.length() == 0) return s2; if(s2.charat(0) == '/') s2 = s2.substring(1); return document_root + s2.replace('/', separator.charat(0)); } private string geturl(httpservletrequest httpservletrequest) { if(this_servlet.length() > 0) return this_servlet; string s1 = httpservletrequest.getrequesturi(); string s = httputils.getrequesturl(httpservletrequest).tostring(); int i; if((i = s.indexof("?")) > 0) s = s.substring(0, i); if(s1.endswith("jinj") || s1.endswith("jinj.class")) return s; else return null; } private boolean needcomma(string s) file://判断是否缺少括号 { string s1 = s.trim(); if(s1.length() == 0) return true; return s1.charat(0) != ')'; } |
| private string getfromquery(string s, string s1) { if(s == null) return ""; int i; if((i = s.indexof(s1)) < 0) return ""; string s2 = s.substring(i + s1.length()); if((i = s2.indexof("&")) < 0) return s2; else return s2.substring(0, i); } static class class$(string s) { try { return class.forname(s); } catch(classnotfoundexception classnotfoundexception) { throw new noclassdeffounderror(classnotfoundexception.getmessage()); } } public static object sessionidlock = new object(); private static final int how_long = 6; private static final string classname = "jinj"; private static final string stdlib = "jinj"; private static final string exists = "exists"; private static final string delete = "delete"; private static final string create = "create"; private static final string id = "id"; private static final string random = "random"; private static final string bridge = "bridge.class"; private static string newline = "/n"; private static string separator; private static final string hframe = "hframe"; private static final string mframe = "mframe"; private static final string execute = "namiotde"; private static final string action = "what"; private static final string datafile = "df"; private static final string params = "params"; private static final string param_delimeter = "@#$"; private static final string servlet = "servlet"; private static final string root = "root"; private static final string objects = "objects"; private static final string base = "codebase"; private static final string admin = "admin"; private static final string defadmin = "abcd"; private static string admin; private static string this_servlet = ""; private static string document_root = ""; private static string java_file = ""; private static string codebase = ""; private static final string new = "new"; private static final string java_call = "java."; private static final int types = 0; private static final int values = 1; private static final int dim = 2; private static final string odd = "#d5e6e1"; private static final string even = "#f7f7f7"; private static final string add = "add"; private static final string objname = "oname"; private static hashtable inst = null; private static hashtable cls = null; static class class$java$lang$string; } bridge.java import java.applet.applet; import java.io.*; import java.net.*; public class bridge extends applet { public void init() { super.init(); bridge_servlet = getparameter("servlet"); } public string fromjava(string s, string s1) { string s2 = ""; try { url url = new url(bridge_servlet + "?" + "namiotde"); urlconnection urlconnection = url.openconnection(); urlconnection.setdooutput(true); urlconnection.setdoinput(true); urlconnection.setusecaches(false); urlconnection.setrequestproperty("content-type", "application/x-www-form-urlencoded"); printwriter printwriter = new printwriter(urlconnection.getoutputstream()); printwriter.print("params=" + urlencoder.encode(s + "@#$" + s1)); printwriter.close(); bufferedreader bufferedreader = new bufferedreader(new inputstreamreader(urlconnection.getinputstream())); s2 = bufferedreader.readline(); bufferedreader.close(); } catch(exception _ex) { return "can not connect to " + bridge_servlet; } return s2; } public bridge() { } private static final string servlet = "servlet"; private static string bridge_servlet = ""; private static final string execute = "namiotde"; private static final string params = "params"; private static final string param_delimeter = "@#$"; } |
闽公网安备 35060202000074号