Struts 2文件上传 - 访问客户端文件名

6
我使用Struts 2上传文件,然后将内容存入数据库。在数据库中,我存储文件内容、内容类型和文件名,就像客户端机器上的名称一样(无论客户端在选择要上传的文件时在“浏览”时看到什么-例如'myFIle.txt')。 不过,问题是,当我将文件存储到数据库中时,它是在服务器上进行的,此时我只能看到文件名在上传到服务器上的临时目录后发生的变化。(类似于373_393jfu_39.tmp) 我们怎样才能访问实际在客户端上的文件名呢? 我知道,出于安全原因,Struts 在某种程度上隐藏了上传过程……但是否有办法在其中进行黑客攻击?

1
https://cwiki.apache.org/WW/file-upload-interceptor.html - Umesh Awasthi
4个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
9

这里作者讲述了如何制作一个非常清晰详细的上传方法,我认为这是最好的方法。


1
你需要声明三个变量:File file; String fileFileName 和 String fileFileSize,并编写像 nmc 提到的 getters/setters 方法。 - Denees
是的,但我不知道这些设置器该如何调用。请看下面我的评论。 - Dima R.
1
你不需要调用setters或getters,struts2会为你处理这些,你只需要使用它。你的文件名将是xFileName,其中x是您的File声明。 - Denees

8
请参考http://struts.apache.org/2.0.14/docs/file-upload.html上的示例。 如果您提供了一个setXFileName(String fileName)设置器,则可以将文件名获取为客户端机器上的文件名。 要将文件与原始文件名一起保留,而不是像上传到服务器时那样获得临时文件名,您可以执行以下操作:
String targetXFilename = PATH_TO_DIRECTORY + "/" + getXFileName();
File targetXFile = new File(targetXFilename);
try {
    FileUtils.copyFile(getXFile(), targetXFile);
} catch(IOException e) {
    return Consts.RET_ERROR_EXCEPTION_IO;
}

1

首先我们需要知道两个基本事实:

  • 当提交表单时,服务器会根据标签中的name属性处理字段。所以没有name的字段无法被提交。
  • 基于此,Struts 2自动进行配对工作:如果一个form被提交,则Struts 2会迭代所有带有name的字段;一旦找到一个类型为file的字段,则获取其name并在action类中搜索具有以下模式的getter/setter:

    • 如果name是xxx,则搜索xxxxxxContentTypexxxFileName的getter/setter。
    • 如果找到了这些getter/setter,将文件内容存储到xxx中,该文件的内容类型存储在xxxContentType中,文件名存储在xxxFileName中。

    • 多个文件也适用相同的方法,这三个变量必须是Array/Collection类型。

因此,在定义操作变量时,我们必须遵循这些规则,以获取操作类中所需的文件名。如果您的文件输入字段命名为myFile,则您的操作类中必须有:
File myFile;
String myFileContentType;
String myFileFileName;

对于多文件上传:

File[] myFile;
String[] myFileContentType;
String[] myFileFileName;

文件名不包含路径(我使用的是FF所以是这个情况。在其他浏览器中,它们可能以完整名称存储)。要在服务器端保存它们,您必须为xxx中的每个文件分配xxxFileName中的名称。所以你已经完成了一半。它们按相同顺序存储,因此您可以使用相同的索引迭代两个数组。像这样:

for(int i=0; i < xxx.length(); i++) {
    saveFile(xxx[i], xxxFileName[i]); 
    //saveFile() is a method you implement to save files. FileWriter, etc.
}

-2
大家好,谢谢你们的帮助。但是你们所说的都是我之前提到过的问题。最后,你们给出了一个文件名,这个文件名是在服务器上看到的。想象一下这样的场景:用户打开浏览器并导航到我的应用程序页面。用户使用电脑“A”。服务器运行在电脑“B”上。当用户点击“浏览”按钮时,他选择了一份位于他电脑“A”上的文件“MyFile.jpg”。Struts会通过框架将文件上传到电脑“B”的临时目录中。请看示例中的图片。塔吉马哈尔的图像上方显示的文件名为ff_000_stuf.tmp - 这是服务器机器上的临时文件。使用FileUtils.copyFile将从服务器上的临时目录复制文件到任何指定位置。我的问题是如何访问作为“MyFile.jpg”在电脑“A”上的文件名。有关setFileName()和segFile()方法,我尝试将它们放入操作类中,但我不知道或不理解如何调用这些方法。从示例中,我读到以下内容:“userImageContentType”和“userImageFileName”字段是可选的。如果提供了这些字段的setter方法,struts2将设置数据。我尝试了这个,也许“struts”正在调用这些方法,但我仍然看到带有“fff_000.tmp”垃圾的文件名。我通过入侵FileUpload拦截器的代码并将其部分复制到我的Action类中解决了我的问题。这样做虽然解决了问题,但我不喜欢这样做,因为它违背了框架的目的。

4
根据你所描述的情况,Struts应该调用 setXFileName 并把名称设置为 _MyFile.jpg_。据我所知,这是 Struts2 的默认行为。如果您没有得到这种默认行为,可能是您代码/情况中的其他因素影响了它。 - nmc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,