2011年4月22日 星期五

Java小技巧(1)

在寫java程式時,常會須要引用其他的工具程式,
若是寫桌面應用程式或動態Web應用程式,比較沒什麼問題,
但若是寫applet就有點麻煩了,一堆安全性、權限問題。
目前是建立一支前導程式,把權限全開,
然後再載入各個jar檔,最後載入主要的panel。
這樣只要把前導程式的jar檔做簽署就可以了,其他jar檔都不用簽署。
前導程式的jar檔會包含兩個檔,一個是前導程式的class,另一個是policy檔

前導程式
/**
 * @author 天使之風
 * applet前導程式
 */
package tw.angelwind.applet;

import java.awt.BorderLayout;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.URLConnection;
import java.security.Policy;
import java.util.ArrayList;

import javax.swing.JApplet;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;

public class Precursor extends JApplet {
    
    private static final long serialVersionUID = 1394497673904909317L;

    private JPanel jContentPane = null;
    
    private ClassLoader loader = null;  //@jve:decl-index=0:
    
    /**
     * This is the xxx default constructor
     */
    public Precursor() {
        super();
    }

    /**
     * This method initializes this
     * 
     * @return void
     */
    public void init() {
        //改變look and feel
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        
        this.setSize(521, 267);
        this.setContentPane(getJContentPane());

        //開啟全部權限
        System.setProperty("java.security.policy", getClass().getClassLoader().getResource("java.policy").toString());
        Policy.getPolicy().refresh();

        //下載並載入各須要使用的jar檔
        downloadLibrary();
        
        //動態載入主要的panel
        try {
            Class<JPanel> c = (Class<JPanel>)loader.loadClass("tw.angelwind.ui.ImageViewer");
            Constructor<JPanel> constructor = c.getConstructor();
            this.setContentPane(constructor.newInstance());
        }
        catch (Exception e) {
            e.printStackTrace();
        }        
    }

    private void downloadLibrary() {
        //建立各jar檔下載後要存放的地方
        String path = System.getProperty("user.home");
        File jarPath = new File(path, "angelwind/jar");
        jarPath.mkdirs();
        
        /**
         * 指定要下載並載入的jar檔,
         * 這些jar檔需要跟此預載程式的jar檔放在同一層
         */
        String libraies = "ftp4j-1.5.1.jar,commons-io-1.4.jar,viewer-1.0.jar";
        
        //開始比對並下載jar檔
        int buffsize = 4096;
        byte[] buff = new byte[buffsize];
        int len = 0;
        if(libraies != null) {
            ArrayList<URL> list = new ArrayList<URL>();
            for(String libName: libraies.split(",")) {
                try {
                    File jar = new File(jarPath, libName);
                    list.add(jar.toURI().toURL());
                    URL url = new URL(this.getCodeBase(), libName);
                    URLConnection conn = url.openConnection();
                    if(jar.isFile()) {
                        conn.setIfModifiedSince(jar.lastModified());
                    }
                    conn.connect();
                    if(conn.getLastModified() > jar.lastModified() || !jar.isFile()) {
                        System.out.println("下載 " + libName);
                        InputStream input = conn.getInputStream();
                        FileOutputStream output = new FileOutputStream(jar);
                        try {
                            while((len = input.read(buff, 0, buffsize)) > 0) {
                                output.write(buff, 0, len);
                            }
                        }
                        finally {
                            output.close();
                        }
                        System.out.println("下載 " + libName + "-完成");
                    }
                }
                catch(IOException e) {
                    e.printStackTrace();
                    JOptionPane.showMessageDialog(this, e.getMessage(), "錯誤", JOptionPane.ERROR_MESSAGE);
                }
            }
            
            //載入各jar檔
            loader = URLClassLoader.newInstance(list.toArray(new URL[0]));
            System.out.println("load jar 完成");
        }
    }
    
    /**
     * This method initializes jContentPane
     * 
     * @return javax.swing.JPanel
     */
    private JPanel getJContentPane() {
        if (jContentPane == null) {
            jContentPane = new JPanel();
            jContentPane.setLayout(new BorderLayout());
        }
        return jContentPane;
    }

}  //  @jve:decl-index=0:visual-constraint="10,10"

policy檔
java.policy
/* AUTOMATICALLY GENERATED ON Mon Dec 06 00:57:35 CST 2010*/
/* DO NOT EDIT */

grant {
  permission java.security.AllPermission;
};


網頁上使用前導程式的html code
<applet archive="viewerpre.jar" id="myapplet"
    name="myapplet" codebase="." 
    code="tw.angelwind.applet" 
    width="80%" height="600" MAYSCRIPT>
</applet>

4 則留言:

  1. 你好
    我想嘗試做做看 類似悠閒農夫的程式
    自動訓練 自動收錢這樣的 我不知道知該從哪邊下手@@

    回覆刪除
  2. 我也不知道你會什麼...
    因此也無從給任何建議@@

    回覆刪除
  3. 可以跟你索取source code嗎?@@

    回覆刪除
    回覆
    1. 不知道你要的是哪個source code?
      如果是農夫的,現在已經放出囉

      刪除