Jakarta EE & React file up- and download using Java 11 and TypeScript

Last Updated:  December 12, 2019 | Published: December 12, 2019

Given the latest release of Payara, we can now officially use it with Java 11 and Jakarta EE. I'm using this occasion to demonstrate how to create a Jakarta EE backend with a React frontend using TypeScript to up- and download a file. This example also includes a solution to create and bundle a React application with Maven and serve the result with Payara.

The final result will look like the following:

Jakarta EE React File application

Jakarta EE project setup

The sample project uses Maven, Java 11 and the following dependencies:

As the JAX-RS specification does not provide a standard for handling file upload as multipart data, I'm including proprietary Jersey dependencies for this. We can mark them with scope provided, as they are bundled with Payara and therefore don't need to be part of the .war file.

For this project, I'll demonstrate a solution to build the frontend application with Maven. Furthermore, the Payara Server will then serve the static files for the Single Page Application. We can achieve this while configuring the build section of our project:

First, the frontend-maven-plugin takes care of installing all npm dependencies, executing the frontend tests and building the React Single Page Application.  It also downloads (if not already present) the correct Node version. You can configure this with nodeVersion in the configuration section of the plugin. This will ensure each team member uses the same version to build the project.

The CI=true is specific for create-react-app. This will ensure to not run the tests and the frontend build in interactive mode and rather finish the process to proceed further Maven plugins.

Finally, we can configure the maven-war-plugin to include our frontend resources as web resources. When we now build the project with mvn package, it will build the frontend and backend application and bundle the frontend resources within our .war file.

Handling files with the Jakarta EE backend

Next, let's have a look at how to handle the file up- and download with our Jakarta EE backend. The backend provides two endpoints: one to upload a file and another to download a random file.

In the first place, we have to register the MultiPartFeature of Jersey for our application. There are multiple ways to do this. I'm using a JAX-RS configuration class to achieve this:

As a result of this, we can now use the proprietary Jersey feature for our JAX-RS resource.

For the file upload, we'll store the file in a list and include the original filename:

The FileContent class is a simple POJO to store the relevant information:

Our frontend application can request a random file on the same endpoint but has to use HTTP GET. To properly download a file, we have to set the content type to application/octet-stream and configure some HTTP headers:

React project setup

Next, let's have a look at the React project setup. With create-react-app we have a great solution for bootstrapping new React applications. I'm using this to place the frontend within the src/main folder with the following command:

To actually create a TypeScript based project, we can use the argument --template typescript.

For proper components and styling, I'm adding semantic-ui-react and semantic-ui-css to this default project:

File up- and download from React

Finally, let's have a look at React application written in TypeScript. It contains three components: FileUploadComponent, FileDownloadComponent, and App to wrap everything. All of these are using React's functional component approach.

Let's start with the FileUploadComponent:

Once we upload a file and submit the HTML form, the component will pass the uploaded file to the uploadFile function.

The FileDownloadComponent is even simpler, as it executes a download function whenever someone clicks the button:

Last but not least the App component orchestrates everything:

Our ApiClient uses the fetch API for making HTTP requests:

To actually download the incoming file from the backend directly, I'm using the following solution:

File handling for other project setups

Similar to this example, I've created several guides for handling files with different project setups. Besides Jakarta EE and React file handling, find other examples here:

The source code, with instructions on how to run this example, is available on GitHub.

Have fun up- and downloading files with Jakarta EE and React,

Phil

>