Collection of utility servlets and filters for Jakarta EE 10 web applications including CORS, DoS protection, QoS management, header manipulation, and server-sent events.
—
Filter for setting, adding, or modifying HTTP headers on responses with flexible configuration syntax. The HeaderFilter provides a simple way to manipulate HTTP headers based on include/exclude patterns.
Filter that extends IncludeExcludeBasedFilter to provide HTTP header manipulation capabilities.
/**
* Filter for setting or adding headers to HTTP responses.
* Extends IncludeExcludeBasedFilter to support path, MIME type, and method filtering.
*/
public class HeaderFilter extends IncludeExcludeBasedFilter {
/**
* Initialize the filter with configuration parameters
* @param filterConfig Filter configuration containing headerConfig parameter
* @throws ServletException if configuration is invalid
*/
public void init(FilterConfig filterConfig) throws ServletException;
/**
* Process the request and apply header modifications to the response
* @param request The servlet request
* @param response The servlet response
* @param chain The filter chain
* @throws IOException if I/O error occurs
* @throws ServletException if servlet error occurs
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException;
/**
* Get string representation of the filter configuration
* @return String describing the filter setup
*/
public String toString();
}The primary configuration parameter that defines header operations.
Format: [action] [header name]: [header value]
Actions:
set - Set header value (replaces existing)add - Add header value (allows multiple values)setDate - Set header with date formattingaddDate - Add header with date formattingSyntax: Comma-separated list of header operations.
HeaderFilter inherits all configuration options from IncludeExcludeBasedFilter:
<!-- Web.xml configuration -->
<filter>
<filter-name>HeaderFilter</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>set X-Frame-Options: DENY, set X-Content-Type-Options: nosniff</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>HeaderFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping><filter>
<filter-name>SecurityHeaderFilter</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>
set X-Frame-Options: SAMEORIGIN,
set X-Content-Type-Options: nosniff,
set X-XSS-Protection: 1; mode=block,
set Referrer-Policy: strict-origin-when-cross-origin,
set Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline',
set Strict-Transport-Security: max-age=31536000; includeSubDomains
</param-value>
</init-param>
</filter><filter>
<filter-name>CacheHeaderFilter</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>
set Cache-Control: public, max-age=3600,
set Expires: Thu, 01 Jan 2025 00:00:00 GMT,
add Vary: Accept-Encoding
</param-value>
</init-param>
<!-- Only apply to static resources -->
<init-param>
<param-name>includedPaths</param-name>
<param-value>/static/*,/assets/*,*.css,*.js,*.png,*.jpg,*.gif</param-value>
</init-param>
</filter><filter>
<filter-name>DateHeaderFilter</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>
setDate Last-Modified: 2024-01-01T00:00:00Z,
addDate X-Generated: now
</param-value>
</init-param>
</filter><filter>
<filter-name>ApiHeaderFilter</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>
set X-API-Version: v1.2.0,
add X-Powered-By: Jetty,
set Access-Control-Max-Age: 3600
</param-value>
</init-param>
<!-- Only apply to API endpoints -->
<init-param>
<param-name>includedPaths</param-name>
<param-value>/api/*</param-value>
</init-param>
<!-- Only for JSON responses -->
<init-param>
<param-name>includedMimeTypes</param-name>
<param-value>application/json</param-value>
</init-param>
</filter><filter>
<filter-name>PostHeaderFilter</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>
set X-CSRF-Protection: enabled,
set X-Request-ID: auto-generated
</param-value>
</init-param>
<!-- Only apply to POST and PUT requests -->
<init-param>
<param-name>includedHttpMethods</param-name>
<param-value>POST,PUT</param-value>
</init-param>
</filter><!-- Multiple header filters for different purposes -->
<!-- Global security headers -->
<filter>
<filter-name>GlobalSecurityHeaders</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>
set X-Frame-Options: SAMEORIGIN,
set X-Content-Type-Options: nosniff
</param-value>
</init-param>
</filter>
<!-- API-specific headers -->
<filter>
<filter-name>ApiHeaders</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>
set X-API-Version: v2.1,
add X-Rate-Limit-Window: 3600
</param-value>
</init-param>
<init-param>
<param-name>includedPaths</param-name>
<param-value>/api/*</param-value>
</init-param>
</filter>
<!-- Static resource headers -->
<filter>
<filter-name>StaticResourceHeaders</filter-name>
<filter-class>org.eclipse.jetty.ee10.servlets.HeaderFilter</filter-class>
<init-param>
<param-name>headerConfig</param-name>
<param-value>
set Cache-Control: public, max-age=86400,
add Vary: Accept-Encoding
</param-value>
</init-param>
<init-param>
<param-name>includedPaths</param-name>
<param-value>*.css,*.js,*.png,*.jpg,*.gif,*.ico</param-value>
</init-param>
</filter>
<!-- Filter mappings -->
<filter-mapping>
<filter-name>GlobalSecurityHeaders</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>ApiHeaders</filter-name>
<url-pattern>/api/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>StaticResourceHeaders</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>import org.eclipse.jetty.ee10.servlets.HeaderFilter;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletContext;
public class HeaderFilterConfig {
public static void configureSecurityHeaders(ServletContext context) {
FilterRegistration.Dynamic headerFilter = context.addFilter("SecurityHeaders",
HeaderFilter.class);
// Security headers configuration
String securityHeaders = String.join(",",
"set X-Frame-Options: DENY",
"set X-Content-Type-Options: nosniff",
"set X-XSS-Protection: 1; mode=block",
"set Referrer-Policy: strict-origin-when-cross-origin",
"set Content-Security-Policy: default-src 'self'"
);
headerFilter.setInitParameter("headerConfig", securityHeaders);
headerFilter.addMappingForUrlPatterns(null, false, "/*");
}
public static void configureCacheHeaders(ServletContext context) {
FilterRegistration.Dynamic cacheFilter = context.addFilter("CacheHeaders",
HeaderFilter.class);
String cacheHeaders = String.join(",",
"set Cache-Control: public, max-age=3600",
"add Vary: Accept-Encoding, Accept"
);
cacheFilter.setInitParameter("headerConfig", cacheHeaders);
cacheFilter.setInitParameter("includedPaths", "/static/*,*.css,*.js");
cacheFilter.addMappingForUrlPatterns(null, false, "/*");
}
}Replaces any existing header with the specified name.
set X-Frame-Options: DENYResults in: X-Frame-Options: DENY
Adds a header value without removing existing values (allows multiple values).
add Vary: Accept-Encoding
add Vary: Accept-LanguageResults in:
Vary: Accept-Encoding
Vary: Accept-LanguageSets a header with date formatting. Supports various date formats.
setDate Last-Modified: 2024-01-01T00:00:00Z
setDate Expires: +3600 (current time + 3600 seconds)Adds a date header without removing existing date headers.
addDate X-Generated: now
addDate X-Cache-Date: +86400HeaderFilter inherits path matching from IncludeExcludeBasedFilter:
/admin/users - matches exactly/api/* - matches all paths starting with /api/*.css - matches all paths ending with .css^/user/\d+$ - matches paths with regex patternFilter headers based on response content type:
<init-param>
<param-name>includedMimeTypes</param-name>
<param-value>text/html,application/json</param-value>
</init-param>
<init-param>
<param-name>excludedMimeTypes</param-name>
<param-value>image/*,application/octet-stream</param-value>
</init-param>Apply headers only to specific HTTP methods:
<init-param>
<param-name>includedHttpMethods</param-name>
<param-value>GET,POST</param-value>
</init-param>
<init-param>
<param-name>excludedHttpMethods</param-name>
<param-value>OPTIONS,HEAD</param-value>
</init-param>X-Frame-Options - Clickjacking protectionX-Content-Type-Options - MIME type sniffing protectionX-XSS-Protection - XSS filter controlContent-Security-Policy - Content security policyStrict-Transport-Security - HTTPS enforcementCache-Control - Browser and proxy caching directivesExpires - Absolute expiration timeETag - Entity tag for conditional requestsLast-Modified - Last modification timestampX-API-Version - API version informationX-Rate-Limit-* - Rate limiting informationX-Request-ID - Request tracing identifierAccess-Control-Allow-Origin - Allowed originsAccess-Control-Allow-Methods - Allowed methodsAccess-Control-Max-Age - Preflight cache durationInstall with Tessl CLI
npx tessl i tessl/maven-org-eclipse-jetty-ee10--jetty-ee10-servlets