|
| 1 | +--- |
| 2 | +title: File Handling |
| 3 | +description: Handling file uploads. |
| 4 | +order: 60 |
| 5 | +--- |
| 6 | + |
| 7 | + |
| 8 | += File Handling |
| 9 | + |
| 10 | +The uploading of files may be handled either with Vaadin Flow using Java, or with Hilla using Lit and React. These are described in the two major sections here. |
| 11 | + |
| 12 | + |
| 13 | +== Handling Uploaded Files in Flow |
| 14 | + |
| 15 | +The Java Flow Upload component provides an API to handle directly uploaded file data, without having to set up an endpoint or a servlet. It uses a [classname]`Receiver` implementation to write the incoming file data into an [classname]`OutputStream`. |
| 16 | + |
| 17 | +The following built-in implementations of [classname]`Receiver` are available: |
| 18 | + |
| 19 | +- [classname]`MemoryBuffer`; |
| 20 | +- [classname]`MultiFileMemoryBuffer`; |
| 21 | +- [classname]`FileBuffer`; and |
| 22 | +- [classname]`MultiFileBuffer`. |
| 23 | + |
| 24 | +These are described in the sub-sections that follow. |
| 25 | + |
| 26 | + |
| 27 | +=== MemoryBuffer |
| 28 | + |
| 29 | +The [classname]`MemoryBuffer` can handle a single file upload at once. It does so by writing the file data into an in-memory buffer. |
| 30 | + |
| 31 | +Using [classname]`MemoryBuffer` will configure the component so that only a single file can be selected. |
| 32 | + |
| 33 | +[source,java] |
| 34 | +---- |
| 35 | +MemoryBuffer memoryBuffer = new MemoryBuffer(); |
| 36 | +
|
| 37 | +Upload upload = new Upload(memoryBuffer); |
| 38 | +upload.addSucceededListener(event -> { |
| 39 | + // Read the data from the buffer. |
| 40 | + InputStream fileData = memoryBuffer.getInputStream(); |
| 41 | +
|
| 42 | + // Get other information about the file. |
| 43 | + String fileName = event.getFileName(); |
| 44 | + String mimeType = event.getMIMEType(); |
| 45 | + long contentLength = event.getContentLength(); |
| 46 | +
|
| 47 | + // Do something with the file data... |
| 48 | +}); |
| 49 | +---- |
| 50 | + |
| 51 | + |
| 52 | +=== MultiFileMemoryBuffer |
| 53 | + |
| 54 | +The [classname]`MultiFileMemoryBuffer` is the same as [classname]`MemoryBuffer`, but it can handle multiple file uploads at once. It writes the file data into a set of in-memory buffers. |
| 55 | + |
| 56 | +[source,java] |
| 57 | +---- |
| 58 | +MultiFileMemoryBuffer multiFileMemoryBuffer = new MultiFileMemoryBuffer(); |
| 59 | +
|
| 60 | +Upload upload = new Upload(multiFileMemoryBuffer); |
| 61 | +upload.addSucceededListener(event -> { |
| 62 | + // Determine which file was uploaded |
| 63 | + String fileName = event.getFileName(); |
| 64 | +
|
| 65 | + // Read the data for that specific file. |
| 66 | + InputStream fileData = multiFileMemoryBuffer |
| 67 | + .getInputStream(fileName); |
| 68 | +
|
| 69 | + // Get other information about the file. |
| 70 | + String mimeType = event.getMIMEType(); |
| 71 | + long contentLength = event.getContentLength(); |
| 72 | +
|
| 73 | + // Do something with the file data... |
| 74 | +}); |
| 75 | +---- |
| 76 | + |
| 77 | + |
| 78 | +=== FileBuffer |
| 79 | + |
| 80 | +The [classname]`FileBuffer` can handle a single file upload at once. It saves the file on the file system, in the current working directory of the Java application. |
| 81 | + |
| 82 | +Using [classname]`FileBuffer` will configure the component so that only a single file can be selected. |
| 83 | + |
| 84 | +[source,java] |
| 85 | +---- |
| 86 | +FileBuffer fileBuffer = new FileBuffer(); |
| 87 | +
|
| 88 | +Upload upload = new Upload(fileBuffer); |
| 89 | +upload.addSucceededListener(event -> { |
| 90 | + // Get information about the file that was |
| 91 | + // written to the file system. |
| 92 | + FileData savedFileData = fileBuffer.getFileData(); |
| 93 | + String absolutePath = savedFileData.getFile().getAbsolutePath(); |
| 94 | +
|
| 95 | + System.out.printf("File saved to: %s%n", absolutePath); |
| 96 | +}); |
| 97 | +---- |
| 98 | + |
| 99 | + |
| 100 | +=== MultiFileBuffer |
| 101 | + |
| 102 | +The [classname]`MultiFileBuffer` works the same as [classname]`FileBuffer`, except that it can handle multiple file uploads at once. For each file, it saves the file on the file system, in the current working directory of the Java application. |
| 103 | + |
| 104 | +[source,java] |
| 105 | +---- |
| 106 | +MultiFileBuffer fileBuffer = new MultiFileBuffer(); |
| 107 | +
|
| 108 | +Upload upload = new Upload(fileBuffer); |
| 109 | +upload.addSucceededListener(event -> { |
| 110 | + // Determine which file was uploaded successfully |
| 111 | + String uploadFileName = event.getFileName(); |
| 112 | +
|
| 113 | + // Get information for that specific file |
| 114 | + FileData savedFileData = multiFileBuffer |
| 115 | + .getFileData(uploadFileName); |
| 116 | + String absolutePath = savedFileData.getFile().getAbsolutePath(); |
| 117 | +
|
| 118 | + System.out.printf("File saved to: %s%n", absolutePath); |
| 119 | +}); |
| 120 | +---- |
| 121 | + |
| 122 | + |
| 123 | +=== Custom Receiver Implementations |
| 124 | + |
| 125 | +For more advanced use cases, you can provide custom implementations for [classname]`Receiver` or [classname]`MultiFileReceiver`. You might do this, for example, to save files into a specific directory, or to upload them to cloud storage. |
| 126 | + |
| 127 | + |
| 128 | +== Handling Upload Requests in Lit and React |
| 129 | + |
| 130 | +When using the Upload web component standalone, you'll need an upload file handler or endpoint in your backend to handle the file upload request. By default, the Upload component sends a request with the method type `POST`, the content type `multipart/form-data`, and the request URL (i.e., the current browser location). |
| 131 | + |
| 132 | +Use the `target` attribute to specify a different URL that should handle the upload request. It's also possible to customize other aspects of the request, such as the method or request headers. |
| 133 | + |
| 134 | +[.example] |
| 135 | +-- |
| 136 | +ifdef::lit[] |
| 137 | +[source,html] |
| 138 | +---- |
| 139 | +<source-info group="TypeScript"></source-info> |
| 140 | +<vaadin-upload |
| 141 | + method="PUT" |
| 142 | + target="/api/upload-handler" |
| 143 | + headers='{ "X-API-KEY": "7f4306cb-bb25-4064-9475-1254c4eff6e5" }'> |
| 144 | +</vaadin-upload> |
| 145 | +---- |
| 146 | +endif::[] |
| 147 | + |
| 148 | +ifdef::react[] |
| 149 | +[source,jsx] |
| 150 | +---- |
| 151 | +<source-info group="React"></source-info> |
| 152 | +<Upload |
| 153 | + method="PUT" |
| 154 | + target="/api/upload-handler" |
| 155 | + headers='{ "X-API-KEY": "7f4306cb-bb25-4064-9475-1254c4eff6e5" }'> |
| 156 | +</Upload> |
| 157 | +---- |
| 158 | +endif::[] |
| 159 | +-- |
| 160 | + |
| 161 | +[discussion-id]`EB618652-4822-49DC-9A51-D71237EF100E` |
0 commit comments