一直想来涂些东西,越来越感觉自己好多好多东西都不懂,懂的东西又好肤浅!惭愧!惭愧!
这儿涂些关于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三者之间就以放心地跑了。
做项目过程看到的好的代码丢了还真舍不得!写得比较急,可能有蛮多的地方连语句都不通。敬请谅解!
近来加班狂多(现在天都已经亮了,相信也有不少同仁跟我一样),又不能上网!都好几个月没更新了。挺想念这儿的,真的!愿与君共勉!