使用 JNLP API 访问客户端

原文: https://docs.oracle.com/javase/tutorial/deployment/doingMoreWithRIA/usingJNLPAPI.html

使用 Java 网络启动协议(JNLP)启动时,富 Internet 应用程序(RIA)可以在用户的​​许可下访问客户端。考虑文本编辑器 applet 示例,以了解如何使用基于 JNLP API 的服务。文本编辑器有一个文本区域和标记为“打开”,“保存”和“另存为”的按钮。文本编辑器可用于打开现有文本文件,对其进行编辑,然后将其保存回磁盘。

接下来显示文本编辑器小程序。


Note: If you don’t see the applet running, you need to install at least the Java SE Development Kit (JDK) 6 update 10 release.



Note: If you don’t see the example running, you might need to enable the JavaScript interpreter in your browser so that the Deployment Toolkit script can function properly.


TextEditorTextEditorApplet 类布局用户界面并将其显示为小程序。 FileHandler 类包含有关使用基于 JNLP API 的服务的核心功能。

请记住,本主题中描述的技术也适用于 Java Web Start 应用程序。

要使用 JNLP 服务,请首先检索对服务的引用。 FileHandler类的initialize方法检索对 JNLP 服务的引用,如以下代码片段所示:

  1. private static synchronized void initialize() {
  2. ...
  3. try {
  4. fos = (FileOpenService)
  5. ServiceManager.lookup("javax.jnlp.FileOpenService");
  6. fss = (FileSaveService)
  7. ServiceManager.lookup("javax.jnlp.FileSaveService");
  8. } catch (UnavailableServiceException e) {
  9. ...
  10. }
  11. }

在引用所需服务之后,调用服务上的方法以执行必要的操作。 FileHandler类的open方法调用 FileOpenService 类的openFileDialog方法来显示文件选择器。 open方法返回所选文件的内容。

  1. public static String open() {
  2. initialize();
  3. try {
  4. fc = fos.openFileDialog(null, null);
  5. return readFromFile(fc);
  6. } catch (IOException ioe) {
  7. ioe.printStackTrace(System.out);
  8. return null;
  9. }
  10. }

类似地,FileHandler类的savesaveAs方法调用 FileSaveService 类的相应方法,以使用户能够选择文件名并将文本区域的内容保存到磁盘。

  1. public static void saveAs(String txt) {
  2. initialize();
  3. try {
  4. if (fc == null) {
  5. // If not already saved.
  6. // Save-as is like save
  7. save(txt);
  8. } else {
  9. fc = fss.saveAsFileDialog(null, null,
  10. fc);
  11. save(txt);
  12. }
  13. } catch (IOException ioe) {
  14. ioe.printStackTrace(System.out);
  15. }
  16. }

在运行时,当 RIA 尝试打开或保存文件时,用户会看到一个安全对话框,询问他们是否要允许该操作。仅当用户允许 RIA 访问其环境时,操作才会继续。

接下来显示 FileHandler 类的完整来源。

  1. // add javaws.jar to the classpath during compilation
  2. import javax.jnlp.FileOpenService;
  3. import javax.jnlp.FileSaveService;
  4. import javax.jnlp.FileContents;
  5. import javax.jnlp.ServiceManager;
  6. import javax.jnlp.UnavailableServiceException;
  7. import java.io.*;
  8. public class FileHandler {
  9. static private FileOpenService fos = null;
  10. static private FileSaveService fss = null;
  11. static private FileContents fc = null;
  12. // retrieves a reference to the JNLP services
  13. private static synchronized void initialize() {
  14. if (fss != null) {
  15. return;
  16. }
  17. try {
  18. fos = (FileOpenService) ServiceManager.lookup("javax.jnlp.FileOpenService");
  19. fss = (FileSaveService) ServiceManager.lookup("javax.jnlp.FileSaveService");
  20. } catch (UnavailableServiceException e) {
  21. fos = null;
  22. fss = null;
  23. }
  24. }
  25. // displays open file dialog and reads selected file using FileOpenService
  26. public static String open() {
  27. initialize();
  28. try {
  29. fc = fos.openFileDialog(null, null);
  30. return readFromFile(fc);
  31. } catch (IOException ioe) {
  32. ioe.printStackTrace(System.out);
  33. return null;
  34. }
  35. }
  36. // displays saveFileDialog and saves file using FileSaveService
  37. public static void save(String txt) {
  38. initialize();
  39. try {
  40. // Show save dialog if no name is already given
  41. if (fc == null) {
  42. fc = fss.saveFileDialog(null, null,
  43. new ByteArrayInputStream(txt.getBytes()), null);
  44. // file saved, done
  45. return;
  46. }
  47. // use this only when filename is known
  48. if (fc != null) {
  49. writeToFile(txt, fc);
  50. }
  51. } catch (IOException ioe) {
  52. ioe.printStackTrace(System.out);
  53. }
  54. }
  55. // displays saveAsFileDialog and saves file using FileSaveService
  56. public static void saveAs(String txt) {
  57. initialize();
  58. try {
  59. if (fc == null) {
  60. // If not already saved. Save-as is like save
  61. save(txt);
  62. } else {
  63. fc = fss.saveAsFileDialog(null, null, fc);
  64. save(txt);
  65. }
  66. } catch (IOException ioe) {
  67. ioe.printStackTrace(System.out);
  68. }
  69. }
  70. private static void writeToFile(String txt, FileContents fc) throws IOException {
  71. int sizeNeeded = txt.length() * 2;
  72. if (sizeNeeded > fc.getMaxLength()) {
  73. fc.setMaxLength(sizeNeeded);
  74. }
  75. BufferedWriter os = new BufferedWriter(new OutputStreamWriter(fc.getOutputStream(true)));
  76. os.write(txt);
  77. os.close();
  78. }
  79. private static String readFromFile(FileContents fc) throws IOException {
  80. if (fc == null) {
  81. return null;
  82. }
  83. BufferedReader br = new BufferedReader(new InputStreamReader(fc.getInputStream()));
  84. StringBuffer sb = new StringBuffer((int) fc.getLength());
  85. String line = br.readLine();
  86. while (line != null) {
  87. sb.append(line);
  88. sb.append("\n");
  89. line = br.readLine();
  90. }
  91. br.close();
  92. return sb.toString();
  93. }
  94. }

Note: To compile Java code that has a reference to classes in the javax.jnlp package, include <your JDK path>/jre/lib/javaws.jar in your classpath. At runtime, the Java Runtime Environment software automatically makes these classes available to RIAs.


下载文本编辑器小程序示例的源代码以进一步试验。