写入ApplicationResources.properties文件时拒绝访问



为了在我正在开发的应用程序中提供双语支持,我们使用了Spring消息传递,它使用了两个文件,ApplicationResources.properties和ApplicationResources_fr.properties。这很好。

现在,我正试图通过让它更有活力来扩展这一点。应用程序将从数据库中读取键值对并插入它们,这给了我以下错误:

java.io.FileNotFoundException: ApplicationResources.properties (Access is denied)

我能够检查键值对,这样我就知道我使用的路径是正确的。我还通过右键单击和访问系统上的实际文件检查了Eclipse属性中的文件,它们不是只读的。我不相信它们是加密的,因为我可以用记事本++打开和查看。

这是我的测试代码,显示我可以查看它们

Properties test_prop = null;
InputStream is = null;
try {
test_prop = new Properties();
is = this.getClass().getResourceAsStream(en_path);
test_prop.load(is);
Set<Object> keys = test_prop.keySet();
boolean key_found = false;
for(Object k:keys) {
String key = (String)k;
if(key.equals("f12345"))    
{
key_found=true;
break;
}
}
System.out.println("Language Properties Test in DAO:" + (key_found? "Key Found" : "Key not found"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

这是我尝试写入文件的地方,并得到错误:

ResultSet rs = null;
try ( 
Connection connection = jdbcTemplate.getDataSource().getConnection();
CallableStatement callableStatement = connection.prepareCall(test_prod_cur);
)
{
callableStatement.registerOutParameter(1, OracleTypes.CURSOR);
callableStatement.executeUpdate();
rs = (ResultSet) callableStatement.getObject(1);
while (rs.next())
{
String thead = rs.getString(1);
//System.out.println(thead + " " + rs.getString(2) + " " + rs.getString(3));
en_prop.setProperty(keyheader+thead, rs.getString(2));
fr_prop.setProperty(keyheader+thead, rs.getString(3));
}
}
catch (SQLException e)
{
System.out.println("SQLException - bilingual values - CLUDAOImpl");
System.out.println(e.getMessage());
}
//add to properties files
//*       
try (OutputStream en_os = new FileOutputStream(en_path);)
{
en_prop.store(en_os, null);
} catch (IOException e) {
e.printStackTrace();
}
try(OutputStream fr_os = new FileOutputStream(en_path);)
{
fr_prop.store(fr_os, null);
} catch (IOException e) {
e.printStackTrace();
}

因此,数据库查询是成功的,这是用注释掉的system.out.println测试的

en_prop.store(en_os, null);
fr_prop.store(fr_os, null);

更新:我在java.util.Properties上搜索了一下,找到了上面的javadocs,哇,这简化了很多事情。我现在可以获取一个属性值,或者检查键是否存在于6行代码中(不包括try-catch)。

Properties prop = null;
InputStream is = null;
this.prop = new Properties();
is = this.getClass().getResourceAsStream(path);
prop.load(is);
this.prop.getProperty("key name"); //returns value of key, or null
this.prop.containsKey("key name"); //returns true if key exists

Update2:使用java.util.Properties时出现问题,即丢失原始文件的所有格式,因此空白、注释和排序都将丢失。在另一个回答中,有人建议使用Apache的Commons Configuration API。我打算试试。

因此,我最终创建了一个类来处理与ApplicationResources(_fr).properties文件的交互,而不是在DAO中进行交互。这是因为我计划在更多的地方使用它。我还开始使用java.util.Properties Javadocs中的方法,这些方法被证明非常有用,并简化了许多领域。

下面是我的新文件写入/属性存储代码。

try (
OutputStream en_os = new FileOutputStream(getClass().getResource(en_path).getFile(),false);
OutputStream fr_os = new FileOutputStream(getClass().getResource(fr_path).getFile(), false);
)
{
en_prop.store(en_os, null);
fr_prop.store(fr_os, null);
} catch (IOException e) {
e.printStackTrace();
}

让我们比较新的和原始的OutputStreams:

OutputStream en_os = new FileOutputStream(getClass().getResource(en_path).getFile(),false); //new
OutputStream en_os = new FileOutputStream(en_path); //original, Access is Denied

此答案不完整,原因如下

我无法解释为什么原始方法失败并导致"访问被拒绝错误"。

更让我担心的是,这实际上并没有改变我期望或想要的文件。我希望更改出现在项目导航器中的文件,但在查看时没有观察到更改。如果我使用一个绝对路径(C:\…)并覆盖文件,那么我可以按预期更改它,但由于服务器的更改及其糟糕的编程和危险,必须更改此路径。这种工作方法是更改某种临时文件或正在运行的文件(通过路径确认,因为显示新值的文件在tmp0文件夹中)。经过一些测试后,只有当原始文件发生更改时,才会在启动时覆盖此临时文件,否则新值将在整个应用程序启动过程中保持不变。

我也不确定这个文件的范围。我无法判断是否所有与网站互动的用户都会对同一文件进行更改。如果所有用户都在与该文件交互,那么可能会发生会话间的潜在泄漏。也有可能每个会话都有独立的值,并可能导致信息丢失。我怀疑所有用户都在与同一个资源交互,但还没有进行绝对肯定的测试更新:我已经确认所有用户都使用同一个临时文件进行交互。

相关内容

  • 没有找到相关文章

最新更新