0

クライアントの PC (具体的には LAN 共有) のファイル システムにアクセスする必要があるイントラネット サイト用の Java アプレットがあります。このアプレットには、次のような機能があります。

JSObject win;

public void init() {
    win=(JSObject) JSObject.getWindow(this);
    win.call("appletMsg", new Object[] {"<b>Applet Loaded</b>", "win"});
}

public void saveFile(String filepath, String filename) {
    File theDir = new File(filepath);
    try {
        if (theDir.exists()) { // This throws exception
            win.call("appletMsg", new Object[] {"Directory Exists", "win"});
        }
        else {
            win.call("appletMsg", new Object[] {"Creating Directory...", "msg"});
            if (theDir.mkdir()) {
                win.call("appletMsg", new Object[] {"Directory Created", "win"});
            }
            else win.call("appletMsg", new Object[] {"Directory Creation Failed!", "fail"});
        }
    }
    catch (Exception e) { // This exception is caught
        win.call("appletMsg", new Object[] {"Error Reading Directory!", "fail"});
        win.call("appletMsg", new Object[] {filepath, "fail"});
    }
    // More code for working with files, error happens above this
}

アプレットの背後にある Javascript

// call applet method
function save() {
    document.myApplet.saveFile('\\\\LOCATION\\DIR\\DIR\\', 'test.txt');
}

// output responses from applet to div
function appletMsg(response, type) {
    document.getElementById('output').innerHTML+='<br><span class='+type+'>'+response+'</span>';
}

トラブルシューティング/考え:

  • JS が Java メソッドを呼び出す前に、アプレットは機能していました (引数はパラメーター リストにあり、アプレットは必要に応じて完全にリロードされ、ファイル操作は init() メソッドにあり、この動作に戻りましたが、ひどい習慣です)
  • アプレットは自己証明書で署名されています
  • JFileChooser を init() メソッドに配置して、パスが正しいことを確認し、それを saveFile() メソッドに移動しましたが、ダイアログは表示されません。Java の .exists() 呼び出しのように JS エラーが表示されることはありません。try/catch で FilePermission 例外がスローされます。
  • これは init() では機能し、saveFile() では機能しないため、これは JavaScript 自体がファイル システムにアクセスするのを防ぐためだとしか思えません。
4

1 に答える 1

2

JavaScript からアプレット関数を呼び出せるようにするには、アクセス コントローラーを使用する必要があります。ドキュメントを参照してください。

だから試してみてください:

public void saveFile(String filepath, String filename) {
    AccessController.doPrivileged(new PrivilegedAction() {
        public Object run() {
            File theDir = new File(filepath);
            try {
                if (theDir.exists()) { // This throws exception
                    win.call("appletMsg", new Object[] { "Directory Exists", "win" });
                } else {
                    win.call("appletMsg", new Object[] { "Creating Directory...", "msg" });
                    if (theDir.mkdir()) {
                        win.call("appletMsg", new Object[] { "Directory Created", "win" });
                    } else
                        win.call("appletMsg", new Object[] { "Directory Creation Failed!", "fail" });
                }
            } catch (Exception e) { // This exception is caught
                win.call("appletMsg", new Object[] { "Error Reading Directory!", "fail" });
                win.call("appletMsg", new Object[] { filepath, "fail" });
            }
            // More code for working with files, error happens above this
        }
    });
}

自己署名証明書を使用しても機能します。セキュリティ警告が表示されるだけです。

特権コード セクションをできるだけ小さくすることを常に忘れないでください。

于 2013-09-12T06:53:28.220 に答える