使用 p:fileUpload 将完整的客户端文件路径发送到服务器端 [英] Send full client side file path to server side using p:fileUpload

查看:14
本文介绍了使用 p:fileUpload 将完整的客户端文件路径发送到服务器端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用:

  • PrimeFaces 5.0
  • 玻璃鱼 4.1
  • Netbeans 8.0.2

我的案例:我有一个内网web应用程序,我想让客户端浏览内网网盘文件系统并将完整的客户端文件路径发送到服务器端.换句话说,我不需要文件内容,只需要完整的文件路径,就像在内网中一样.

My case: I have an intranet web application where I'd like to let the client browse the intranet network disk file system and send the full client side file path to the server side. In other words, I do not need the file contents, but only the full file path, as it is in the intranet network.

为此我尝试使用 :

public void handleFileUpload(FileUploadEvent event) throws IOException {
    UploadedFile uploadedFile = event.getFile();
    InputStream inputStream = uploadedFile.getInputstream();

    File file = new File(uploadedFile.getFileName());
    System.out.println(file.getAbsolutePath());

    String realPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/");
    System.out.println(realPath);
}

file.getAbsolutePath() 打印以下内容:

C:UsersXXXAppDataRoamingNetBeans8.0.2configGF_4.1domain1configfile.txt

C:UsersXXXAppDataRoamingNetBeans8.0.2configGF_4.1domain1configfile.txt

而且,realPath 打印以下内容:

And, the realPath prints the following:

C:UsersXXXDocumentsNetBeansProjectsPROJECTdistgfdeployPROJECTPROJECT-war_war

C:UsersXXXDocumentsNetBeansProjectsPROJECTdistgfdeployPROJECTPROJECT-war_war

但是,我期待看到

\MACHINEDocumentsfile.txt

\MACHINEDocumentsfile.txt

我怎样才能做到这一点?

How can I achieve this?

推荐答案

您基本上是在寻找解决方案的错误方向.而且,您以错误的方式看待 JSF/PrimeFaces.JSF 在这个问题的上下文中只是一个 HTML 代码生成器.

You're basically looking in the wrong direction for the solution. And, you're looking at JSF/PrimeFaces in a wrong way. JSF is in the context of this question just a HTML code generator.

HTML 不支持将完整的客户端文件路径发送到服务器端.确实,较旧的 Internet Explorer 版本有一个笨拙的安全错误,即完整的客户端文件路径是沿着文件名发送的.但是,这不是 HTML 强制要求的. 的唯一目的是将文件内容从客户端发送到服务器,您应该通过 getInputStream() 阅读并自己保存在固定位置.文件名在这里只是附加的元数据.这通常不会按原样用于将文件保存在服务器中,以避免被其他上传的文件覆盖,但文件名巧合.文件名在服务器端最多用作最终文件名的前缀,或者仅被记住以便在下载期间在另存为"中重新显示.但仅此而已.

HTML does not support sending full client side file path to the server side. True, older Internet Explorer versions had the awkward security bug that the full client side file path was sent along the file name. But, this is not mandated by HTML. The sole purpose of <input type="file"> is to send the file content from client to server, which you're supposed to read via getInputStream() and save on a fixed location yourself. The filename is here just additional metadata. This is usually never used as-is to save the file in the server, to avoid overwrites by other uploads with coincidentally the same filename. The file name is at most used as prefix of the final file name in the server side, or only remembered in order to be redisplayed in "Save As" during a download. But that's it.

你所有的尝试都失败了,因为这里,

All your attempts failed because here,

File file = new File(uploadedFile.getFileName());
System.out.println(file.getAbsolutePath());

.. getFileName() 只返回文件名称,而不是文件路径.new File(...) 构造函数将解释相对于当前工作目录"的文件名,即JVM(在您的情况下,服务器)时打开的目录,开始了.基本上,您正在尝试定位一个不存在的文件.实际文件存储在其他地方,通常位于您无法控制的操作系统管理的临时文件位置.但是,这也不是您要查找的内容.

.. the getFileName() only returns the file name, not the file path. The new File(...) constructor will interpret the file name relative to the "current working directory", i.e. the directory which was open at the moment the JVM (in your case, the server), was started. Basically, you're attempting to locate a non-existing file. The actual file is stored elsewhere, usually in the OS-managed temporary file location beyond your control. However, this is also not what you're looking for.

这里,

String realPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/");
System.out.println(realPath);

.. getRealPath() 仅将 webcontent 相对路径转换为绝对磁盘文件系统路径.换句话说,它为您提供了部署文件夹的路径,其中存储了展开的 WAR 文件的所有内容.通常是 XHTML/JS/CSS 文件等.这也绝对不是你要找的.此外,getRealPath() 没有单一合理的现实世界用例.你绝对应该避免使用它.

.. the getRealPath() only converts the webcontent-relative path to absolute disk file system path. In other words, it gives you the path to the deploy folder where all contents of the expanded WAR file are stored. Usually it are the XHTML/JS/CSS files and such. This is also definitely not what you're looking for. Moreover, there is no single sensible real world use case for getRealPath(). You should absolutely avoid using it.

您需要从与 HTML 不同的方向寻找解决方案.您需要一个能够获取完整的客户端文件路径然后将其发送到服务器端的客户端应用程序.HTML 做不到(即使不是 HTML5).CSS 做不到.JS做不到.但是Java可以做到.您可以使用 Swing JFileChooser浏览并选择实际的 File.您只需要在客户端而不是服务器端执行它.您可以为此使用Applet,然后您可以轻松地将其嵌入任何网页,甚至是 JSF 页面;你知道,它只是一个 HTML 代码生成器.

You need to look for the solution in a different direction than HTML. You need a client side application capable of grabbing the full client side file path and then sending it to the server side. HTML can't do it (even not HTML5). CSS can't do it. JS can't do it. But Java can do it. You can use Swing JFileChooser to browse and pick the actual File. You only need to execute it in the client side instead of the server side. You can use an Applet for this which you in turn can easily embed in any webpage, even a JSF page; you know, it's just a HTML code generator.

基本上:

  1. 在小程序中,通过JFileChooser获取完整的文件路径.

JFileChooser fileChooser = new JFileChooser();
if (fileChooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
    File selectedFile = fileChooser.getSelectedFile();
    String selectedFileAbsolutePath = selectedFile.getAbsolutePath();
    // ...
} else {
    // User pressed cancel.
}

另外一个好处是,你可以使用FileSystemView 将其限制为某些(网络)驱动器或文件夹,以便最终用户不会意外选择完全不相关的驱动器/文件夹.

Additional advantage is, you can use FileSystemView to restrict it to certain (network) drives or folders, so that the enduser won't accidentally select completely irrelevant drives/folders.

通过URLConnection将完​​整的文件路径作为查询参数发送到服务器端.

Send the full file path as query parameter via URLConnection to server side.

String url = "/someServletURL?selectedFileAbsolutePath=" + URLDecoder.decode(selectedFileAbsolutePath, "UTF-8");
URLConnection connection = new URL(getCodeBase(), url).openConnection();
connection.setRequestProperty("Cookie", "JSESSIONID=" + getParameter("sessionId"));
InputStream response = connection.getInputStream();
// ...

  • servlet 中阅读.

    @WebServlet("/someServletURL")
    public class SomeServlet extends HttpServlet {
    
        @Override
        public void doGet(HttpServletRequest request, HttpServletResponse resposne) throws ServletException, IOException {
            String selectedFileAbsolutePath = request.getParameter("selectedFileAbsolutePath");
            // ...
        }
    
    }
    

  • 在 JSF 页面中嵌入小程序时,不要忘记将会话 ID 作为小程序参数传递.

  • Don't forget to pass session ID as applet parameter when embedding the applet in JSF page.

    <applet ...>
        <param name="sessionId" value="#{session.id}" />
    </applet>
    

    这样,servlet 将可以访问与 JSF 页面完全相同的 HTTP 会话,然后您可以在它们之间共享/通信数据.

    This way the servlet will have access to exactly the same HTTP session as the JSF page, and then you can share/communicate data between them.

    这篇关于使用 p:fileUpload 将完整的客户端文件路径发送到服务器端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆