在servlet JSP applet与JS之间穿梭

在servlet JSP applet与JS之间穿梭
  一直想来涂些东西,越来越感觉自己好多好多东西都不懂,懂的东西又好肤浅!惭愧!惭愧!

   这儿涂些关于applet的东西。时间不多,希望涂完后还可以休息下,开始吧:

  首先自己做一个applet,然后打成JAR包(在Eclipse中可以用 fatjar这个插件来完成)这里涉及到给applet签名:

  如何给applet签名(参考):

  没有经过数字签名的Applet在默认情况下没有写本地文件的权限。那么让我们准备签名代码吧。
首先用keytool命令产生用来签名的key。下面这个命令产生一个叫"mykey"的key,它存储在我们新建的叫"mystore"的keystore中。

  keytool -genkey -alias mykey -keystore mystore

  接下来它会问一些问题包括keystore的密码,key的密码等,如下所示:

  输入keystore密码:  storepass
  您的名字与姓氏是什么?
    [Unknown]:  AYellow
  您的组织单位名称是什么?
    [Unknown]:  我的组织单位
  您的组织名称是什么?
    [Unknown]:  我的组织
  您所在的城市或区域名称是什么?
    [Unknown]:  北京
  您所在的州或省份名称是什么?
    [Unknown]:  北京
  该单位的两字母国家代码是什么
    [Unknown]:  CN
  CN=AYellow, OU=我的组织单位, O=我的组织, L=北京, ST=北京, C=CN 正确吗?
    [否]:  Y

  输入<mykey>的主密码
        (如果和 keystore 密码相同,按回车):  keypass

  完成后会在当前目录下生成一个叫mystore的文件,这个文件包含了我们的key。用jarsigner命令签名我们的代码test.jar(需要输入keystore和key的密码):

  
jarsigner  - keystore mystore myJarName.jar mykey

  Enter Passphrase 
for  keystore: storepass
  Enter key password 
for  mykey: keypass


  再次运行Applet,在Applet加载的时候会出现一个对话框,说该Applet由不可信任的发行者签名并宣称代码是安全的,是不是要对Applet授权。选择"授权于会话",然后点击我们的按钮,看看是不是成功的创建了文件?

  辅助:写一个CLASS,通过其可在applet中调用JSP中的JS代码
public   class  CallJavascript {
    
public  CallJavascript() {
    }

    
/**
     *
     * 
@param  ob Object 这是一个applet对象
     * 
@param  str String
     
*/
    
public  String callJs(Object ob, String str) {
        String jscmd 
=  str;
        System.out.println(
" javasriptL "   +  str);
        String jsresult 
=   null ;
        
boolean  success  =   false ;
        
try  {
            Method getw 
=   null , eval  =   null ;
            Object jswin 
=   null ;
            Class c 
=  Class.forName( " netscape.javascript.JSObject " );
            
/*  does it in IE too  */
            Method ms[] 
=  c.getMethods();
            
for  ( int  i  =   0 ; i  <  ms.length; i ++ ) {
                
if  (ms[i].getName().compareTo( " getWindow " ==   0 )
                    getw 
=  ms[i];
                
else   if  (ms[i].getName().compareTo( " eval " ==   0 )
                    eval 
=  ms[i];
            }

            Object a[] 
=   new  Object[ 1 ];
            a[
0 =  ob;  /*  this is the applet  */
            jswin 
=  getw.invoke(c, a);  /*  this yields the JSObject  */
            a[
0 =  jscmd;
            Object result 
=  eval.invoke(jswin, a);
            
if (result != null ){
                
if  (result  instanceof  String){
                    jsresult 
=  (String) result;
                }
else {
                    jsresult 
=  result.toString();
                }
            }
            
            success 
=   true ;
        }
catch  (InvocationTargetException ite) {
            ite.printStackTrace();
            jsresult 
=   ""   +  ite.getTargetException();
        } 
catch  (Exception ex) {
            ex.printStackTrace();
            jsresult 
=   ""   +  ex;
        }

        
if  (success){
            System.out.println(
" eval succeeded, result is  "   +  jsresult);
        }
else {
            System.out.println(
" eval failed with error  "   +  jsresult);
        }
        
return  jsresult;
    }
}


  可以看到其中主要用到了netscape.javascript.JSObject这个object(<%=jdk_home%>\jre\lib\plugin.jar(jdk1.5)),它允许 Java 代码访问 JavaScript 方法和属性
主要通过反射用到了JsObject的getWindow与evel二个方法来完成此类
JSObject主要方法如下:
Method         描述
call               Calls a JavaScript 方法
eval              Evaluates a JavaScript expression
getMember         Retrieves a named member of a JavaScript object
getSlot          Retrieves an indexed member of a JavaScript object
removeMember    Removes a named member of a JavaScript object
setMember          Sets a named member of a JavaScript object
setSlot          Sets an indexed member of a JavaScript object
toString          Converts a JSObject to a string


  可想而知,用CallJS就如下所示了:
CallJavascript calljs  =   new  CallJavascript();
String type 
=  calljs.callJs( this " document.pmMstForm.type.value; " );
or
calljs.callJs(
this " waiting() " );



  如何通过APPLET与Servlet通信,这个很简单了。因为applet本来就是一个jar包了。不过,将欲传输的对象序列化到流里面(较大些的,
如持久化对象),也可以放到一个请求(request)中(相对较小的字符串等)。如下所示:

import  java.net.URL;
import  java.net.URLConnection;
import  java.io.ObjectInputStream;
import  java.io.IOException;
import  java.util.Map;
import  java.io.ObjectOutputStream;
import  java.util.List;
import  java.util.Iterator;

/**
 *
 * <p>Title:</p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: </p>
 *
 * 
@author  not attributable
 * 
@version  1.0
 
*/
public   class  DataTransferUtil {
    
public  DataTransferUtil() {
    }

    
public   static  Map getData(Map paraMap, List list, URL strURL) {

        URL url 
=   null ;
        URLConnection urlcon 
=   null ;
        ObjectInputStream ois 
=   null ;
        ObjectOutputStream oos 
=   null ;
        
try  {
            url 
=  strURL;
            urlcon 
=  url.openConnection();
            Iterator iter 
=  paraMap.keySet().iterator();
            
while  (iter.hasNext()) {
                String key 
=  (String) iter.next();
                urlcon.addRequestProperty(key, (String) paraMap.get(key));
            }
            urlcon.setUseCaches(
false );
            urlcon.setDoInput(
true );
            urlcon.setDoOutput(
true );

            urlcon.setRequestProperty(
" Content-type " " application/octest-stream " );
            oos 
=   new  ObjectOutputStream(urlcon.getOutputStream());
            oos.writeObject(list);
            
if  (oos  !=   null ) {
                oos.flush();
                oos.close();
            }

            ois 
=   new  ObjectInputStream(urlcon.getInputStream()); // 开始取得servlet中返回的数据

            Map mapRtn 
=  (Map) ois.readObject();

            
return  mapRtn;

        } 
catch  (IOException ioe) {
            ioe.printStackTrace();
            
return   null ;
        } 
catch  (ClassNotFoundException cnfe) {
            cnfe.printStackTrace();
            
return   null ;
        } 
finally  {
            
try  {
                
if  (ois  !=   null ) {
                    ois.close();
                }
            } 
catch  (IOException ioe) {
                ioe.printStackTrace();
            }
        }
    }
}


  应用的时候可以如下:
DataTransferUtil util = new  DataTransferUtil();
Map paraMap
= new  HashMap();
paraMap.put(
" method " , " import " );
Map map
= util.getData(paraMap,list,url); // 取得servlet返回的数据(经过封装)


  这儿第二个参数放了一个LIST,可以根据具体情况使用。只是到了Servet端的servlet获取的时候做相应的处理就OK了(马上可以看到)。
这样applet就把数据传输到url的servlet中去了。
servlet中发生了些什么呢?

response.setContentType( " application/octest-stream " );
        
// req.setCharacterEncoding("gb2312");
        log.debug( " is handlRequest. " );
        
// 准备传输数据
        ObjectOutputStream oos  =   null ;
        ObjectInputStream ois 
=   null ;
        Map rtnMap 
=   new  HashMap();


        
// 执行方法
         try  {
            String method 
=  (String)request.getHeader( " method " );
            ois 
=   new  ObjectInputStream( new  BufferedInputStream(request.getInputStream()));
            .

            
  呵呵,放在request中的数据request.getHeader取了出来,流中的数据也取了出来。
  最后要想往applet中返回结果,则同样做如下处理即可:

oos  =   new  ObjectOutputStream(response.getOutputStream());
oos.writeObject(rtnMap);   
 

   OK, 差不多啦!序列化也要注意些问题,如对象类型,前后顺序。


  小结:通过以上,可以实现如下功能:
  1:将做好的APPLET打成JAR包后,通过签名可以将其工嵌入到JSP中运行。
  2: 就可以实现在applet中调用JSP中JS,对程序做出相应的处理。
  3: 数据在applet与servelt通信。

   最后我们就可以在JSP Applet与Servlet三者之间就以放心地跑了。


  做项目过程看到的好的代码丢了还真舍不得!写得比较急,可能有蛮多的地方连语句都不通。敬请谅解!
   
    近来加班狂多(现在天都已经亮了,相信也有不少同仁跟我一样),又不能上网!都好几个月没更新了。挺想念这儿的,真的!愿与君共勉!





你可能感兴趣的:(在servlet JSP applet与JS之间穿梭)