加载小程序 jar 文件中已有的属性时如何阻止对服务器的请求?
我维护一个小程序,帮助用户将照片上传到我们的服务。小程序 jar
文件有一些 .properties
文件:
>> jar -tf applet.jar | grep prop
res/messages.properties
res/messages_ca.properties
res/messages_es.properties
...
这些文件在小程序初始化期间加载。
messages = ResourceBundle.getBundle("res.messages");
然而,此调用会向服务器生成 4 到 5 个请求,查找 jar
文件中没有的文件,然后再返回到 .properties
文件中包含的 .properties
文件。代码>.jar。
从服务器错误日志:
[error] File does not exist: /photos/res/messages.class
[error] File does not exist: /photos/res/messages_en.class
[error] File does not exist: /photos/res/messages_en.properties
[error] File does not exist: /photos/res/messages_en_US.class
[error] File does not exist: /photos/res/messages_en_US.properties
ResourceManager.getBundle 解释说这是完成的方式:
getBundle 然后迭代候选包名称以查找第一个可以实例化实际资源包的名称。对于每个候选包名称,它尝试创建一个资源包:
首先,它尝试使用候选包名称加载类。如果可以使用指定的类加载器找到并加载这样的类,分配与 ResourceBundle 兼容,可以从 ResourceBundle 访问,并且可以实例化,则 getBundle 创建此类的新实例并将其用作结果资源包。
否则,getBundle 会尝试查找属性资源文件。它通过替换所有“.”,从候选包名称生成路径名。带有“/”的字符并附加字符串“.properties”。它尝试使用 ClassLoader.getResource 查找具有此名称的“资源”。
我确信这样做有充分的理由,但就我而言,应该有五个失败的请求,这对我来说似乎是浪费。已知服务器上不存在的文件。
有什么方法可以教小程序仅在 .jar
文件中查找这些文件吗?
注意:我不是 Java 程序员,因此如果有比 ResourceManager.getBundle
更好的加载属性的方法,请告诉我。
I maintain an applet that helps users to upload photos to our service. The applet jar
file has a few .properties
files:
>> jar -tf applet.jar | grep prop
res/messages.properties
res/messages_ca.properties
res/messages_es.properties
...
These are loaded during applet initialization.
messages = ResourceBundle.getBundle("res.messages");
This call however generates 4 to 5 requests to the server looking for files that aren't in the jar
file, before falling back on to the .properties
file included in the .jar
.
From the server error log:
[error] File does not exist: /photos/res/messages.class
[error] File does not exist: /photos/res/messages_en.class
[error] File does not exist: /photos/res/messages_en.properties
[error] File does not exist: /photos/res/messages_en_US.class
[error] File does not exist: /photos/res/messages_en_US.properties
The documentation for ResourceManager.getBundle explains that this is the way it is done:
getBundle then iterates over the candidate bundle names to find the first one for which it can instantiate an actual resource bundle. For each candidate bundle name, it attempts to create a resource bundle:
First, it attempts to load a class using the candidate bundle name. If such a class can be found and loaded using the specified class loader, is assignment compatible with ResourceBundle, is accessible from ResourceBundle, and can be instantiated, getBundle creates a new instance of this class and uses it as the result resource bundle.
Otherwise, getBundle attempts to locate a property resource file. It generates a path name from the candidate bundle name by replacing all "." characters with "/" and appending the string ".properties". It attempts to find a "resource" with this name using ClassLoader.getResource.
I am sure there are good reasons for doing it this way, but in my case it seems wasteful to me that there should be five failed requests for files which are known to be non-existent on the server.
Is there any way to teach the applet to look for these files in the .jar
file only?
Note: I am not a Java programmer, so if there is a better way to load properties than ResourceManager.getBundle
, please let me know.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Java 1.6 引入了 ResourceBundle.Control类,如果您不支持 Java 1.4,它可能会提供一些帮助。就您而言,编写自己的包管理器并不是什么复杂的事情。
此演示代码将捆绑包加载限制为给定语言集的属性文件:
此代码模拟调用以检索西班牙语/西班牙语言环境的字符串:
由于语言集是
es
和ca
和CustomManager
仅支持语言(不支持国家/地区代码或变体),只能加载以下文件:您希望使用 语言环境 和 ClassLoader 支持,以及您想要在哪里管理语言列表,都取决于您。
警告:我不认为我在实施过程中违反了任何安全限制,但我只在桌面应用程序中测试了代码。
Java 1.6 introduced the ResourceBundle.Control class, which might have offered some help if you weren't supporting Java 1.4. As you are, it isn't rocket science to write your own bundle manager.
This demo code restricts bundle loading to properties files in a given set of languages:
This code simulates a call to retrieve strings for the Spanish/Spain locale:
Since the set of languages is
es
andca
andCustomManager
supports only languages (not country codes or variants) only the following files could be loaded:How sophisticated you want to get with Locale and ClassLoader support, and where you want to manage your language list, is up to you.
Caveat: I don't think I violated any security restrictions with the implementation, but I only tested the code in a desktop app.
只需在
有关更多详细信息,请参阅 http://docs。 oracle.com/javase/6/docs/technotes/guides/plugin/developer_guide/special_attributes.html#codebase。
Just set the
codebase_lookup
attribute tofalse
in your<applet>
tag configuration and your applet won't do any additional calls to the server for resources (e.g. i18n resource bundles).More details on http://docs.oracle.com/javase/6/docs/technotes/guides/plugin/developer_guide/special_attributes.html#codebase.
Jaime Hablutzel 解决方案效果很好。
遗憾的是,我还没有足够的声誉来投票。
当您实例化小程序时,将 codebase_lookup 设置为 false 会准确告诉类加载器小程序已使用 jar 文件中的所有所需类和资源进行部署,并避免不必要的代码库查找。
Jaime Hablutzel solution works fine.
It's a pity, that I still don't have enough reputation to vote it up.
Setting codebase_lookup to false when you instanciate the applet tells the classloader precisely that the applet is deployed with all the needed classes and resources within the jar files and to avoid the unnecessary codebase lookup.