0
# Base Filtering Patterns
1
2
Abstract base class for filters that need path, MIME type, or HTTP method-based filtering capabilities. The IncludeExcludeBasedFilter provides a foundation for creating custom filters with flexible request matching criteria.
3
4
## Capabilities
5
6
### IncludeExcludeBasedFilter
7
8
Abstract base class providing common filtering patterns for servlet filters.
9
10
```java { .api }
11
/**
12
* Abstract base filter for include/exclude filtering based on paths, MIME types, and HTTP methods.
13
* Provides common functionality for filters that need to selectively process requests.
14
*/
15
public abstract class IncludeExcludeBasedFilter implements Filter {
16
/**
17
* Initialize the filter with include/exclude configuration parameters
18
* @param filterConfig Filter configuration containing include/exclude parameters
19
* @throws ServletException if configuration is invalid
20
*/
21
public void init(FilterConfig filterConfig) throws ServletException;
22
23
/**
24
* Clean up filter resources
25
*/
26
public void destroy();
27
28
/**
29
* Get string representation of the filter configuration
30
* @return String describing the include/exclude patterns
31
*/
32
public String toString();
33
34
/**
35
* Determine if the request should be filtered based on configured patterns
36
* @param httpRequest The HTTP request
37
* @param httpResponse The HTTP response
38
* @return true if the request should be processed by this filter
39
*/
40
protected boolean shouldFilter(HttpServletRequest httpRequest, HttpServletResponse httpResponse);
41
42
/**
43
* Guess the MIME type of the response for filtering decisions
44
* @param httpRequest The HTTP request
45
* @param httpResponse The HTTP response
46
* @return The guessed MIME type or null if cannot be determined
47
*/
48
protected String guessMimeType(HttpServletRequest httpRequest, HttpServletResponse httpResponse);
49
}
50
```
51
52
## Configuration Parameters
53
54
### Path Filtering
55
56
**includedPaths**: Comma-separated list of path specifications to include
57
**excludedPaths**: Comma-separated list of path specifications to exclude
58
59
Path specifications support three formats:
60
- **Regex patterns**: Start with `^` (e.g., `^/api/v\d+/.*`)
61
- **Servlet patterns**: Start with `/` for exact or prefix matching (e.g., `/admin/*`, `/api/users`)
62
- **Suffix patterns**: Start with `*.` for extension matching (e.g., `*.jsp`, `*.html`)
63
64
### MIME Type Filtering
65
66
**includedMimeTypes**: Comma-separated list of MIME types to include
67
**excludedMimeTypes**: Comma-separated list of MIME types to exclude
68
69
MIME type patterns support:
70
- **Exact matching**: `text/html`, `application/json`
71
- **Wildcard matching**: `text/*`, `image/*`, `application/*`
72
73
### HTTP Method Filtering
74
75
**includedHttpMethods**: Comma-separated list of HTTP methods to include
76
**excludedHttpMethods**: Comma-separated list of HTTP methods to exclude
77
78
Standard HTTP methods: `GET`, `POST`, `PUT`, `DELETE`, `HEAD`, `OPTIONS`, `PATCH`, `TRACE`
79
80
## Usage Examples
81
82
### Custom Security Filter
83
84
```java
85
import org.eclipse.jetty.ee10.servlets.IncludeExcludeBasedFilter;
86
import jakarta.servlet.*;
87
import jakarta.servlet.http.HttpServletRequest;
88
import jakarta.servlet.http.HttpServletResponse;
89
90
/**
91
* Custom security filter that adds security headers to specific paths
92
*/
93
public class SecurityHeaderFilter extends IncludeExcludeBasedFilter {
94
@Override
95
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
96
throws IOException, ServletException {
97
98
HttpServletRequest httpRequest = (HttpServletRequest) request;
99
HttpServletResponse httpResponse = (HttpServletResponse) response;
100
101
// Check if this request should be filtered
102
if (shouldFilter(httpRequest, httpResponse)) {
103
// Add security headers
104
httpResponse.setHeader("X-Frame-Options", "DENY");
105
httpResponse.setHeader("X-Content-Type-Options", "nosniff");
106
httpResponse.setHeader("X-XSS-Protection", "1; mode=block");
107
}
108
109
// Continue with the filter chain
110
chain.doFilter(request, response);
111
}
112
}
113
```
114
115
**Configuration**:
116
```xml
117
<filter>
118
<filter-name>SecurityHeaderFilter</filter-name>
119
<filter-class>com.example.SecurityHeaderFilter</filter-class>
120
<!-- Only apply to HTML pages -->
121
<init-param>
122
<param-name>includedMimeTypes</param-name>
123
<param-value>text/html</param-value>
124
</init-param>
125
<!-- Skip admin pages (they have their own security) -->
126
<init-param>
127
<param-name>excludedPaths</param-name>
128
<param-value>/admin/*</param-value>
129
</init-param>
130
</filter>
131
```
132
133
### Custom Logging Filter
134
135
```java
136
/**
137
* Logging filter that logs specific types of requests
138
*/
139
public class ApiLogFilter extends IncludeExcludeBasedFilter {
140
private static final Logger logger = LoggerFactory.getLogger(ApiLogFilter.class);
141
142
@Override
143
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
144
throws IOException, ServletException {
145
146
HttpServletRequest httpRequest = (HttpServletRequest) request;
147
HttpServletResponse httpResponse = (HttpServletResponse) response;
148
149
long startTime = System.currentTimeMillis();
150
151
try {
152
chain.doFilter(request, response);
153
} finally {
154
// Log if this request should be filtered
155
if (shouldFilter(httpRequest, httpResponse)) {
156
long duration = System.currentTimeMillis() - startTime;
157
logger.info("API Request: {} {} - Status: {} - Duration: {}ms",
158
httpRequest.getMethod(),
159
httpRequest.getRequestURI(),
160
httpResponse.getStatus(),
161
duration);
162
}
163
}
164
}
165
}
166
```
167
168
**Configuration**:
169
```xml
170
<filter>
171
<filter-name>ApiLogFilter</filter-name>
172
<filter-class>com.example.ApiLogFilter</filter-class>
173
<!-- Only log API endpoints -->
174
<init-param>
175
<param-name>includedPaths</param-name>
176
<param-value>/api/*</param-value>
177
</init-param>
178
<!-- Only log POST, PUT, DELETE (not GET) -->
179
<init-param>
180
<param-name>includedHttpMethods</param-name>
181
<param-value>POST,PUT,DELETE</param-value>
182
</init-param>
183
</filter>
184
```
185
186
### Custom Compression Filter
187
188
```java
189
/**
190
* Simple compression filter that compresses specific content types
191
*/
192
public class CompressionFilter extends IncludeExcludeBasedFilter {
193
@Override
194
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
195
throws IOException, ServletException {
196
197
HttpServletRequest httpRequest = (HttpServletRequest) request;
198
HttpServletResponse httpResponse = (HttpServletResponse) response;
199
200
// Check if client accepts gzip
201
String acceptEncoding = httpRequest.getHeader("Accept-Encoding");
202
boolean clientSupportsGzip = acceptEncoding != null &&
203
acceptEncoding.toLowerCase().contains("gzip");
204
205
if (clientSupportsGzip && shouldFilter(httpRequest, httpResponse)) {
206
// Wrap response with compression
207
GzipResponseWrapper wrappedResponse = new GzipResponseWrapper(httpResponse);
208
chain.doFilter(request, wrappedResponse);
209
wrappedResponse.finish();
210
} else {
211
chain.doFilter(request, response);
212
}
213
}
214
}
215
```
216
217
**Configuration**:
218
```xml
219
<filter>
220
<filter-name>CompressionFilter</filter-name>
221
<filter-class>com.example.CompressionFilter</filter-class>
222
<!-- Compress text content -->
223
<init-param>
224
<param-name>includedMimeTypes</param-name>
225
<param-value>text/html,text/css,text/javascript,application/json,application/xml</param-value>
226
</init-param>
227
<!-- Don't compress images -->
228
<init-param>
229
<param-name>excludedMimeTypes</param-name>
230
<param-value>image/*</param-value>
231
</init-param>
232
<!-- Only compress larger files -->
233
<init-param>
234
<param-name>excludedPaths</param-name>
235
<param-value>*.ico,/favicon.ico</param-value>
236
</init-param>
237
</filter>
238
```
239
240
### Custom Authentication Filter
241
242
```java
243
/**
244
* Authentication filter that checks tokens for specific endpoints
245
*/
246
public class TokenAuthFilter extends IncludeExcludeBasedFilter {
247
@Override
248
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
249
throws IOException, ServletException {
250
251
HttpServletRequest httpRequest = (HttpServletRequest) request;
252
HttpServletResponse httpResponse = (HttpServletResponse) response;
253
254
if (shouldFilter(httpRequest, httpResponse)) {
255
String authHeader = httpRequest.getHeader("Authorization");
256
257
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
258
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
259
"Missing or invalid authorization header");
260
return;
261
}
262
263
String token = authHeader.substring(7);
264
if (!validateToken(token)) {
265
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED,
266
"Invalid token");
267
return;
268
}
269
}
270
271
chain.doFilter(request, response);
272
}
273
274
private boolean validateToken(String token) {
275
// Implementation-specific token validation
276
return TokenService.isValid(token);
277
}
278
}
279
```
280
281
**Configuration**:
282
```xml
283
<filter>
284
<filter-name>TokenAuthFilter</filter-name>
285
<filter-class>com.example.TokenAuthFilter</filter-class>
286
<!-- Only protect API endpoints -->
287
<init-param>
288
<param-name>includedPaths</param-name>
289
<param-value>/api/*</param-value>
290
</init-param>
291
<!-- Skip authentication endpoints -->
292
<init-param>
293
<param-name>excludedPaths</param-name>
294
<param-value>/api/auth/*,/api/public/*</param-value>
295
</init-param>
296
<!-- Only for operations that modify data -->
297
<init-param>
298
<param-name>includedHttpMethods</param-name>
299
<param-value>POST,PUT,DELETE,PATCH</param-value>
300
</init-param>
301
</filter>
302
```
303
304
## Path Specification Patterns
305
306
### Exact Match
307
```
308
/admin/users
309
```
310
Matches only the exact path `/admin/users`.
311
312
### Prefix Match
313
```
314
/api/*
315
```
316
Matches any path starting with `/api/` including:
317
- `/api/users`
318
- `/api/products/123`
319
- `/api/v1/search`
320
321
### Suffix Match
322
```
323
*.jsp
324
*.html
325
*.css
326
```
327
Matches any path ending with the specified extension.
328
329
### Regex Match
330
```
331
^/user/\d+$
332
^/api/v\d+/.*
333
```
334
Matches paths using regular expression patterns. Must start with `^`.
335
336
## MIME Type Patterns
337
338
### Exact MIME Type
339
```
340
text/html
341
application/json
342
application/pdf
343
```
344
345
### Wildcard MIME Type
346
```
347
text/* # All text types
348
image/* # All image types
349
application/* # All application types
350
```
351
352
### Multiple MIME Types
353
```
354
text/html,text/css,text/javascript
355
```
356
357
## Advanced Configuration Examples
358
359
### Complex Path Filtering
360
361
```xml
362
<filter>
363
<filter-name>ComplexPathFilter</filter-name>
364
<filter-class>com.example.MyFilter</filter-class>
365
<!-- Include API and admin paths -->
366
<init-param>
367
<param-name>includedPaths</param-name>
368
<param-value>/api/*,/admin/*</param-value>
369
</init-param>
370
<!-- Exclude specific admin and API paths -->
371
<init-param>
372
<param-name>excludedPaths</param-name>
373
<param-value>/admin/login,/api/health,/api/public/*</param-value>
374
</init-param>
375
</filter>
376
```
377
378
### Content-Type Based Filtering
379
380
```xml
381
<filter>
382
<filter-name>ContentTypeFilter</filter-name>
383
<filter-class>com.example.MyFilter</filter-class>
384
<!-- Include JSON and XML responses -->
385
<init-param>
386
<param-name>includedMimeTypes</param-name>
387
<param-value>application/json,application/xml,text/xml</param-value>
388
</init-param>
389
<!-- Exclude binary content -->
390
<init-param>
391
<param-name>excludedMimeTypes</param-name>
392
<param-value>image/*,video/*,application/octet-stream</param-value>
393
</init-param>
394
</filter>
395
```
396
397
### Method-Specific Filtering
398
399
```xml
400
<filter>
401
<filter-name>WriteOperationFilter</filter-name>
402
<filter-class>com.example.MyFilter</filter-class>
403
<!-- Only filter write operations -->
404
<init-param>
405
<param-name>includedHttpMethods</param-name>
406
<param-value>POST,PUT,DELETE,PATCH</param-value>
407
</init-param>
408
<!-- Skip OPTIONS (preflight) -->
409
<init-param>
410
<param-name>excludedHttpMethods</param-name>
411
<param-value>OPTIONS</param-value>
412
</init-param>
413
</filter>
414
```
415
416
### Combined Filtering Strategy
417
418
```xml
419
<filter>
420
<filter-name>CombinedFilter</filter-name>
421
<filter-class>com.example.MyFilter</filter-class>
422
<!-- Filter API endpoints -->
423
<init-param>
424
<param-name>includedPaths</param-name>
425
<param-value>/api/*</param-value>
426
</init-param>
427
<!-- Only JSON responses -->
428
<init-param>
429
<param-name>includedMimeTypes</param-name>
430
<param-value>application/json</param-value>
431
</init-param>
432
<!-- Only write operations -->
433
<init-param>
434
<param-name>includedHttpMethods</param-name>
435
<param-value>POST,PUT,DELETE</param-value>
436
</init-param>
437
<!-- Skip health checks -->
438
<init-param>
439
<param-name>excludedPaths</param-name>
440
<param-value>/api/health,/api/status</param-value>
441
</init-param>
442
</filter>
443
```
444
445
## Implementation Guidelines
446
447
### Filter Logic Pattern
448
```java
449
@Override
450
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
451
throws IOException, ServletException {
452
453
HttpServletRequest httpRequest = (HttpServletRequest) request;
454
HttpServletResponse httpResponse = (HttpServletResponse) response;
455
456
// Check if this request should be processed
457
if (shouldFilter(httpRequest, httpResponse)) {
458
// Apply your filter logic here
459
processRequest(httpRequest, httpResponse);
460
}
461
462
// Always continue the chain
463
chain.doFilter(request, response);
464
}
465
```
466
467
### MIME Type Detection
468
The base class provides MIME type detection through:
469
- Response content type (if already set)
470
- Request URI extension mapping
471
- Servlet context MIME type mapping
472
473
### Performance Considerations
474
- Path matching is cached for performance
475
- MIME type detection may require response buffering
476
- Use specific patterns rather than broad wildcards when possible
477
478
## Common Use Cases
479
480
### Content Processing
481
Apply transformations only to specific content types (HTML, JSON, XML).
482
483
### Security Filters
484
Add security headers or authentication checks to sensitive paths.
485
486
### Performance Monitoring
487
Log or monitor specific API endpoints or operations.
488
489
### Content Compression
490
Compress responses for text-based content types.
491
492
### Caching Headers
493
Add cache control headers to static resources or API responses.