To serve static files (e.g., HTML, CSS, JavaScript, images) using a Jakarta Servlet, you can follow these steps. Jakarta Servlets provide a way to read files from a directory (or resources) and serve them as HTTP responses.
Here’s a guide on how to achieve it:
1. Directory Structure
Your project structure should look something like this:
src/main/resources/static/
├── index.html
├── styles.css
├── script.js
└── images/
└── logo.png
All the static files (HTML, CSS, JavaScript, images, etc.) should be placed in a directory (e.g., static
) within your resources or web-app deployment directory.
2. Servlet Implementation
Create a custom Servlet
to handle requests for static files. The servlet will read files from the static
folder and write the content to the HTTP response.
Here’s an example:
package org.kodejava.servlet;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLConnection;
@WebServlet("/static/*")
public class StaticFileServlet extends HttpServlet {
private static final String STATIC_DIR = "/static/"; // Path to static files directory
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the requested file path from the URL
String requestedFile = req.getPathInfo();
if (requestedFile == null || requestedFile.equals("/")) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "File name is missing");
return;
}
// Locate the static file
File file = new File(getServletContext().getRealPath(STATIC_DIR + requestedFile));
// Ensure the file exists and is not a directory
if (!file.exists() || file.isDirectory()) {
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "File not found");
return;
}
// Set the content type based on the file type
String mimeType = URLConnection.guessContentTypeFromName(file.getName());
if (mimeType == null) {
mimeType = "application/octet-stream"; // Default binary type
}
resp.setContentType(mimeType);
// Write the file content to the response
try (FileInputStream fis = new FileInputStream(file);
OutputStream os = resp.getOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
}
}
}
3. Explanation of the Code
- Annotation:
- The
@WebServlet("/static/*")
annotation maps all requests starting with/static/
to this servlet.
- The
- Requested Path:
req.getPathInfo()
retrieves the path of the resource the user requested (/static/styles.css
becomes/styles.css
).
- File Retrieval:
- The static directory location is derived using
getServletContext().getRealPath()
.
- The static directory location is derived using
- MIME Type:
URLConnection.guessContentTypeFromName()
determines the file type so the browser knows how to handle the response.
- File Output:
- The file is read using an input stream and written to the output stream of the HTTP response in chunks.
4. Web Deployment Descriptor (Optional Alternative)
If you’re not using annotations, you can register the servlet in the WEB-INF/web.xml
file as follows:
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
version="10.0">
<servlet>
<servlet-name>StaticFileServlet</servlet-name>
<servlet-class>org.kodejava.servlet.StaticFileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>StaticFileServlet</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
</web-app>
5. Test the Static File Server
Place some static files (e.g., index.html
, styles.css
) in your static
directory. Start your server and access them via URLs like:
- http://localhost:8080/static/index.html
- http://localhost:8080/static/styles.css
6. Additional Considerations
- Security:
- Be cautious about serving sensitive files. Use checks to block access to directories outside your static folder.
- Caching:
- Consider adding HTTP headers for caching, such as
Cache-Control
orETag
.
- Consider adding HTTP headers for caching, such as
- Alternative: Use Jakarta Servlet
DefaultServlet
:- Many Jakarta Servlet containers (e.g., Tomcat) have a
DefaultServlet
for serving static resources without custom code. You can configure it with<servlet>
and<servlet-mapping>
inweb.xml
.
- Many Jakarta Servlet containers (e.g., Tomcat) have a
Here’s a simple example:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
If you configure this, files from /static/
will be served directly without writing a custom servlet.
Maven dependencies
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.1.0</version>
<scope>provided</scope>
</dependency>