Send full path to file on client side using p: fileUpload

I use:

  • PrimeFaces 5.0
  • GlassFish 4.1
  • Netbeans 8.0.2

My case: I have an intranet web application where I want the client to browse the intranet network file system and send the full file path from the client to the server side. In other words, I do not need the contents of the file, but only the full path to the file, like on an intranet.

I tried to use <p:fileUpload>

for this:

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()

prints the following:

C: \ Users \ XXX \ AppData \ Roaming \ NetBeans \ 8.0.2 \ Config \ GF_4.1 \ domain1 \ Config \ file.txt

And, realPath

prints the following:

C: \ Users \ XXX \ Documents \ NetBeansProjects \ PROJECT \ distance \ gfdeploy \ PROJECT \ PROJECT-war_war \

However, I expect to see

\\ MACHINE \ Documents \ file.txt

How can I achieve this?

+3


source to share


1 answer


Basically you are looking for the wrong direction of the solution. And you are looking wrong at JSF / PrimeFaces. JSF is in the context of this question only as an HTML code generator.

HTML does not support sending the full client-side path to the server. True, older versions of Internet Explorer had an inconvenient security bug that the full path to the file was sent by the file name on the client side. But this is not related to HTML. The only purpose <input type="file">

is to send the file content from the client to the server that you have to read through getInputStream()

, and save to a fixed location
... The filename here is just additional metadata. This is usually never used as - to save the file to the server to avoid being overwritten by other downloads by the same file name. The file name is most often used as a prefix for the final file name on the server side, or is only remembered for re-display in Save As during upload. But what is it.

All your attempts have failed because here

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

      

.. getFileName()

only returns the file name , not the file path
. The constructor new File(...)

will interpret the file name relative to the "current working directory", that is, the directory that was open when the JVM (in your case, the server) was started. Basically, you are trying to find a non-existent file. The actual file is stored elsewhere, typically in an OS-controlled temporary location of the file outside of your control. However, this is also not what you are looking for.

And here,



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

      

.. getRealPath()

only converts the relative webcontent path to the absolute filesystem path
. In other words, it gives you the path to the deployment folder where all the contents of the extended WAR file are stored. Usually these are XHTML / JS / CSS files, etc. This is definitely not what you are looking for. Moreover, getRealPath()

there is no single sane use case in the real world. You should avoid using it.

You need to look for a solution in a different direction than HTML. You need a client side application capable of capturing the full path to a file on the client side and then submitting it to the server. HTML cannot do this (not even HTML5). CSS cannot do this. JS cannot do this. But Java can do it. You can use SwingJFileChooser

to browse and select the actual File

. You only need to execute it on the client side, not the server side. You can use an Applet for this, which you in turn can easily embed in any web page, even a JSF page; you know, this is just an HTML code generator.

Basically:

  • In the applet, grab the full path to the file via JFileChooser

    .

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

    Added benefit: you can use FileSystemView

    to restrict it to certain (network) drives or folders so the end user wins "randomly select totally unnecessary drives / folders.

  • Send the full path to the file as a request parameter via URLConnection

    to the server.

    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();
    // ...
    
          

  • Read it in servlet .

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

  • Don't forget to pass the session id as an applet parameter when you insert the applet into the JSF page.

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

    This way the servlet will have access to the exact same HTTP session as the JSF page and then you can exchange / exchange data between them.

+4


source







All Articles