在java開發(fā)的早期,重點(diǎn)被放在了客戶端開發(fā)。語言中對(duì)于applet和安全下載的支持
對(duì)于萬維網(wǎng)(WWW)的發(fā)布看上去是個(gè)不錯(cuò)的主意。但是現(xiàn)實(shí)是java最大的成功在于服務(wù)器端,java的強(qiáng)大功能和適應(yīng)性贏得了服務(wù)器端開發(fā)者的心。同時(shí),客戶端的開發(fā)落后了。棘手的開發(fā)問題限制了applet的效用,開發(fā)者被迫轉(zhuǎn)向基于瀏覽器的瘦客戶端。
Java Network Launching Protocol (JNLP,java網(wǎng)絡(luò)加載協(xié)議) 承諾改變這個(gè)現(xiàn)狀。通過JCP(Java Community Process)的JSR-56的開發(fā),
JNLP解決了很多先前用java開發(fā)針對(duì)客戶端的功能的問題。一個(gè)JNLP客戶端是一個(gè)應(yīng)用程序或者說服務(wù),它可以從宿主于網(wǎng)絡(luò)的資源中加載應(yīng)用程序。如果你使用JNLP打包一個(gè)應(yīng)用程序,那么一個(gè)JNLP客戶端能夠:
o 為該應(yīng)用探測(cè),安裝并且使用正確版本的JRE(java運(yùn)行時(shí)環(huán)境)
o 從瀏覽器或者桌面加載應(yīng)用程序
o 當(dāng)新版本的應(yīng)用出現(xiàn)時(shí)自動(dòng)下載最新的版本。
o 為了加速啟動(dòng)速度在本機(jī)緩存應(yīng)用程序需要的類
o 可以作為applet或者應(yīng)用程序運(yùn)行
o 在必要的情況下下載原始的庫(kù)
o 以安全的方式使用諸如文件系統(tǒng)這樣的本機(jī)資源
o 自動(dòng)定位和加載外部依賴資源
Sun 提供了一個(gè)實(shí)現(xiàn)JNLP的稱為Java Web Start(JWS)的參考實(shí)現(xiàn)。讓我們使用它開發(fā)一個(gè)使用JFC Swing的簡(jiǎn)單應(yīng)用。為了做這個(gè),你需要從http://java.sun.com/products/javawebstart下載JWS。(譯者注:JDK的新版本JDK1.4已經(jīng)內(nèi)置JWS,無須另外下載。)
下面是應(yīng)用程序的代碼:
//File HelloJNLP.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class HelloJNLP extends JFrame {
public HelloJNLP() {
super("Hello JNLP");
String loadedFrom = this.getClass().getClassLoader().toString();
JLabel jl = new JLabel("loaded by " + loadedFrom);
JEditorPane jtp = new JEditorPane("text/plain",
"Edit this text");
getContentPane().add(jl, BorderLayout.NORTH);
getContentPane().add(jtp, BorderLayout.CENTER);
}
public static void main(String [] args) {
JFrame f = new HelloJNLP();
f.setBounds(100,100,325,250);
f.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
f.setVisible(true);
f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.out.println("Shutting down...");
System.exit(0);
}
});
}
}
JNLP的核心是一個(gè)發(fā)布清單(deployment manifest)。它是一個(gè)使用.jnlp做
擴(kuò)展名的XML文件(JNLP規(guī)范簡(jiǎn)單的稱之為"JNLP 文件")。要發(fā)布HelloJNLP,你需要在JNLP文件中描述它,就像下面這樣:
<?xml version="1.0" encoding="UTF-8"?>
<!-- file Hello.jnlp -->
<jnlp codebase="http://staff.develop.com/halloway/TechTips/May2001"
href="http://staff.develop.com/halloway/TechTips/May2001/Hello.jnlp">
<information>
<title>Hello</title>
<vendor>Tech Tips Sample May 2001</vendor>
<icon href="HelloJNLP.jpg"/>
</information>
<resources>
<j2se version="1.2+"/>
<jar href="HelloJNLP.jar"/>
</resources>
<application-desc main-class="HelloJNLP"/>
</jnlp>
這個(gè)清單包含客戶端需要下載和使用HelloJNLP的所有信息:
o jnlp元素的codebase屬性指出搜索應(yīng)用程序資源的頂級(jí)URL。
o information元素指出一個(gè)JNLP用戶接口可以顯示給客戶端的信息。
o j2se元素指出客戶端必須有1.2版本或者更新的J2SE(tm)。(這是對(duì)于applet開發(fā)的一個(gè)大的提高,因?yàn)樗3J芟抻跒g覽器提供的VM(虛擬機(jī)))
o jar元素指出程序的JAR文件的相對(duì)于jnlp codebase位置。
o application-desc元素指出要運(yùn)行的類。你可以添加子元素用以指定命令行參數(shù)或者系統(tǒng)屬性。
要將這個(gè)應(yīng)用程序發(fā)布給一個(gè)web服務(wù)器,你需要執(zhí)行以下的步驟:
1. 修改jnlp的codebase和hrefURL為你自己的web服務(wù)器的合適的URL。
2. 將JNLP文件發(fā)布到web服務(wù)器。
3. 編譯并打包HelloJNLP.java并發(fā)布到web服務(wù)器。例如:
jar cvf HelloJNLP.jar HelloJNLP.class HelloJNLP$1.class
4. 創(chuàng)建一個(gè)圖標(biāo)HelloJNLP.jpg并將之安裝在web服務(wù)器上。你可以使用
http://staff.develop.com/halloway/TechTips/May2001/HelloJNLP.jpg
5. 設(shè)置你的web服務(wù)器的mime-type關(guān)聯(lián):.jnlp映射到mime-type application/x-java-jnlp-file。例如,對(duì)于Apache,添加如下一行到mime.types:
application/x-java-jnlp-file jnlp
重新啟動(dòng)web服務(wù)器。
從客戶端執(zhí)行那個(gè)應(yīng)用程序,首先確認(rèn)你已經(jīng)安裝了JWS。然后簡(jiǎn)單的在瀏覽器中指向該jnlp文件。JWS客戶端將下載該jnlp文件,下載必要的資源,加載應(yīng)用程序。你所看到的將是在一個(gè)編輯區(qū)中顯示的文本"Edit this text" 。如果你在配置web服務(wù)器上有問題或者不能使用web服務(wù)器,你可以從
http://staff.develop.com/halloway/TechTips/May2001/Hello.jnlp
加載這個(gè)程序。
注意HelloJNLP不是作為一個(gè)applet運(yùn)行在瀏覽器中,而是作為一個(gè)獨(dú)立的應(yīng)用程序。
當(dāng)你關(guān)閉程序時(shí),HelloJNLP使用System.out打印消息"Shutting down...",然而沒有控制臺(tái)可見??刂婆_(tái)是JWS的諸多設(shè)置中缺省設(shè)置為"off"的其中一個(gè)。這是你可以修改的一對(duì)設(shè)置中的一個(gè)值,就像下面這樣:
1. 編輯JWS安裝目錄中的javaws.cfg文件。添加一行"javaws.cfg.forceUpdate=true"。
這會(huì)導(dǎo)致JWS在啟動(dòng)應(yīng)用程序前自動(dòng)檢查更新的版本。
2. 運(yùn)行JWS。使用菜單File->Preferences,進(jìn)入Advanced標(biāo)簽并且選擇"Show Java Console"。(由于JDK1.4中的本機(jī)化,JWS將顯示中文的界面,所以此處的因?yàn)楸蛔詣?dòng)顯示為對(duì)應(yīng)的中文)同意,選擇"Log Output"將日志輸出到你選擇的文件。當(dāng)你在調(diào)試時(shí)并且需要捕獲System.out和System.err時(shí)是非常有用的。
HelloJNLP顯示一個(gè)編輯器,但是編輯器的內(nèi)容在你關(guān)閉程序后將丟失。將下面的代碼添加到HelloJNLP.java會(huì)自動(dòng)的將編輯器的狀態(tài)存儲(chǔ)到客戶端的硬盤上:
//changes to HelloJNLP.java
import java.io.*;
import java.net.*;
import javax.jnlp.*;
//replace the constructor with this new version:
JEditorPane jtp;
public HelloJNLP() {
super("Hello JNLP, Second Version");
String loadedFrom = this.getClass().getClassLoader().toString();
JLabel jl = new JLabel("loaded by " + loadedFrom);
jtp = new JEditorPane("text/plain", "Edit this text");
readEditorContents();
getContentPane().add(jl, BorderLayout.NORTH);
getContentPane().add(jtp, BorderLayout.CENTER);
addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.out.println("Shutting down...");
try {
writeEditorContents();
}
catch (Exception ex) {
System.out.println("Yoinks!");
ex.printStackTrace();
}
System.exit(0);
}
});
}
//add these helper methods
private void writeEditorContents() throws
UnavailableServiceException, IOException {
System.out.println("writeEditorContents");
PersistenceService ps = (PersistenceService)
ServiceManager.lookup("javax.jnlp.PersistenceService");
BasicService bs = (BasicService)
ServiceManager.lookup("javax.jnlp.BasicService");
URL baseURL = bs.getCodeBase();
System.out.println("CodeBase was " + baseURL);
URL editorURL = new URL(baseURL, "Editor");
try {
ps.create(editorURL, 1024);
}
catch (Exception e) {
e.printStackTrace();
}
FileContents fc = ps.get(editorURL);
DataOutputStream os = new DataOutputStream(
fc.getOutputStream(false));
String s = jtp.getText();
os.writeUTF(s);
os.flush();
os.close();
}
private void readEditorContents() {
try {
PersistenceService ps = (PersistenceService)
ServiceManager.lookup("javax.jnlp.PersistenceService");
BasicService bs = (BasicService)
ServiceManager.lookup("javax.jnlp.BasicService");
URL baseURL = bs.getCodeBase();
URL editorURL = new URL(baseURL, "Editor");
FileContents fc = ps.get(editorURL);
DataInputStream is = new DataInputStream(fc.getInputStream());
jtp.setText(is.readUTF());
is.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
(譯者注:正常編譯需要在CLASSPATH中添加javaws.jar的路徑,在windows下為C:Program FilesJava Web Start目錄下)
JNLP API定義了一套的服務(wù)用以繞過安全沙盒使得一些通常的客戶端操作可以使用。
在writeEditorContents方法中,BasicService查找應(yīng)用程序的代碼目錄,然后
PersistenceService將編輯區(qū)的內(nèi)容緩存在本機(jī)硬盤上,這些內(nèi)容被鍵入到一個(gè)和應(yīng)用程序目錄相對(duì)的URL下。 PersistenceService提供的名字/值對(duì)數(shù)據(jù)和瀏覽器的cookies很相似。JWS通過一對(duì)被稱為"muffins"的東西實(shí)現(xiàn)了這個(gè), muffins不時(shí)候用來存儲(chǔ)大數(shù)據(jù),他們應(yīng)該用于在客戶端緩存小的標(biāo)識(shí)符。然后這些標(biāo)識(shí)符能被用于在服務(wù)器上定位大的信息。
在web服務(wù)器上重新發(fā)布修改過的應(yīng)用程序,然后試著從客戶端運(yùn)行它--依然通過URL。如果你沒有web服務(wù)器,你可以從
http://staff.develop.com/halloway/TechTips/May2001/Hello2.jnlp 運(yùn)行這個(gè)新版本。JWS自動(dòng)探測(cè)程序被改變并運(yùn)行新的版本。你可以通過檢查標(biāo)題條的字符串來證實(shí)這點(diǎn),它現(xiàn)在將顯示"Hello JNLP,Second Version." 修改編輯區(qū)的內(nèi)容,然后關(guān)閉它。當(dāng)你再次加載該程序時(shí),你的改變會(huì)出現(xiàn)。(當(dāng)你第一次運(yùn)行新版的程序時(shí)你會(huì)在控制臺(tái)看到一個(gè)異常,這是因?yàn)閞eadEditorContents 第一次不能找到muffin。)
(譯者注:實(shí)際上第一次運(yùn)行時(shí)出現(xiàn)的異常導(dǎo)致程序無法正常結(jié)束,從而使得編輯區(qū)的內(nèi)容無法寫入客戶端,下次運(yùn)行時(shí)也相當(dāng)于第一次運(yùn)行。即此程序無法展示文章的特性,可能是于筆者的JWS的版本有關(guān),筆者使用的是最新的1.0.1_02(build b03))
JNLP提供了比這里演示的更多的服務(wù)。例如,你可以:
o 很好的控制程序如何被下載
o 描述各個(gè)JAR之間的依賴關(guān)系
o 下載并運(yùn)行本機(jī)代碼安裝程序
o 對(duì)簽名的代碼授予附件的權(quán)限
o 請(qǐng)求指定版本的程序或者applet
要了解更多有關(guān)JNLP的情況,請(qǐng)到
http://java.sun.com/products/javawebstart/download-spec.html
下載JNLP規(guī)范。
要了解更多JWS的情況,請(qǐng)參考http://java.sun.com/products/javawebstart/
只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。 | ||
![]() |
||
網(wǎng)站導(dǎo)航:
博客園
IT新聞
Chat2DB
C++博客
博問
管理
|
||
相關(guān)文章:
|
||
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
29 | 30 | 1 | 2 | 3 | 4 | 5 | |||
6 | 7 | 8 | 9 | 10 | 11 | 12 | |||
13 | 14 | 15 | 16 | 17 | 18 | 19 | |||
20 | 21 | 22 | 23 | 24 | 25 | 26 | |||
27 | 28 | 29 | 30 | 31 | 1 | 2 | |||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
常用鏈接
留言簿(3)
隨筆檔案
文章分類
文章檔案
相冊(cè)
搜索
最新評(píng)論

- 1.?re: 自動(dòng)生成32位永不重復(fù)ID
- 444
- --22
- 2.?re: 根據(jù)拼音首字母查詢?nèi)嗣?C#版)[未登錄]
- 好用,謝謝
- --123
- 3.?re: java中生成32位隨機(jī)ID [未登錄]
- 手術(shù)
- --想
- 4.?re: Jocky混淆JAVA代碼(保護(hù)你的JAVA項(xiàng)目)
- 求支持 JDK 1.7的版本
- --pro
- 5.?re: Jocky混淆JAVA代碼(保護(hù)你的JAVA項(xiàng)目)
- 8530
- --ss