0
# Resource Endpoints
1
2
The resource endpoints capabilities provide the core annotations and mechanisms for defining REST endpoints, mapping HTTP methods, and injecting request parameters into Java methods.
3
4
## Core Imports
5
6
```java
7
import javax.ws.rs.Path;
8
import javax.ws.rs.ApplicationPath;
9
import javax.ws.rs.GET;
10
import javax.ws.rs.POST;
11
import javax.ws.rs.PUT;
12
import javax.ws.rs.DELETE;
13
import javax.ws.rs.HEAD;
14
import javax.ws.rs.OPTIONS;
15
import javax.ws.rs.PATCH;
16
17
import javax.ws.rs.PathParam;
18
import javax.ws.rs.QueryParam;
19
import javax.ws.rs.HeaderParam;
20
import javax.ws.rs.CookieParam;
21
import javax.ws.rs.FormParam;
22
import javax.ws.rs.MatrixParam;
23
import javax.ws.rs.BeanParam;
24
import javax.ws.rs.DefaultValue;
25
26
import javax.ws.rs.Consumes;
27
import javax.ws.rs.Produces;
28
import javax.ws.rs.Encoded;
29
30
import javax.ws.rs.core.MediaType;
31
import javax.ws.rs.core.Response;
32
import javax.ws.rs.core.Context;
33
import javax.ws.rs.core.UriInfo;
34
import javax.ws.rs.core.HttpHeaders;
35
import javax.ws.rs.core.SecurityContext;
36
import javax.ws.rs.core.Request;
37
```
38
39
## Path Definition
40
41
### @Path Annotation
42
43
Identifies the URI path template for resources and sub-resources.
44
45
```java { .api }
46
@Target({ElementType.TYPE, ElementType.METHOD})
47
@Retention(RetentionPolicy.RUNTIME)
48
@Documented
49
public @interface Path {
50
String value();
51
}
52
```
53
54
**Usage Example:**
55
56
```java
57
@Path("/users")
58
public class UserResource {
59
60
@GET
61
@Path("/{id}")
62
public Response getUser(@PathParam("id") String userId) {
63
// Implementation
64
return Response.ok().build();
65
}
66
67
@GET
68
@Path("/{id}/orders/{orderId}")
69
public Response getUserOrder(@PathParam("id") String userId,
70
@PathParam("orderId") String orderId) {
71
// Nested path parameters
72
return Response.ok().build();
73
}
74
}
75
```
76
77
### @ApplicationPath Annotation
78
79
Identifies the application path that serves as the base URI for all resource URIs provided by @Path annotations.
80
81
```java { .api }
82
@Target({ElementType.TYPE})
83
@Retention(RetentionPolicy.RUNTIME)
84
@Documented
85
public @interface ApplicationPath {
86
String value();
87
}
88
```
89
90
**Usage Example:**
91
92
```java
93
@ApplicationPath("/api/v1")
94
public class MyApplication extends Application {
95
// Optional: configure resource classes, singletons, providers
96
@Override
97
public Set<Class<?>> getClasses() {
98
Set<Class<?>> classes = new HashSet<>();
99
classes.add(UserResource.class);
100
classes.add(OrderResource.class);
101
return classes;
102
}
103
}
104
```
105
106
## HTTP Method Annotations
107
108
### Standard HTTP Methods
109
110
```java { .api }
111
@Target({ElementType.METHOD})
112
@Retention(RetentionPolicy.RUNTIME)
113
@HttpMethod("GET")
114
@Documented
115
public @interface GET {
116
}
117
118
@Target({ElementType.METHOD})
119
@Retention(RetentionPolicy.RUNTIME)
120
@HttpMethod("POST")
121
@Documented
122
public @interface POST {
123
}
124
125
@Target({ElementType.METHOD})
126
@Retention(RetentionPolicy.RUNTIME)
127
@HttpMethod("PUT")
128
@Documented
129
public @interface PUT {
130
}
131
132
@Target({ElementType.METHOD})
133
@Retention(RetentionPolicy.RUNTIME)
134
@HttpMethod("DELETE")
135
@Documented
136
public @interface DELETE {
137
}
138
139
@Target({ElementType.METHOD})
140
@Retention(RetentionPolicy.RUNTIME)
141
@HttpMethod("HEAD")
142
@Documented
143
public @interface HEAD {
144
}
145
146
@Target({ElementType.METHOD})
147
@Retention(RetentionPolicy.RUNTIME)
148
@HttpMethod("OPTIONS")
149
@Documented
150
public @interface OPTIONS {
151
}
152
153
@Target({ElementType.METHOD})
154
@Retention(RetentionPolicy.RUNTIME)
155
@HttpMethod("PATCH")
156
@Documented
157
public @interface PATCH {
158
}
159
```
160
161
**Usage Example:**
162
163
```java
164
@Path("/products")
165
public class ProductResource {
166
167
@GET
168
public List<Product> getAllProducts() {
169
return productService.findAll();
170
}
171
172
@POST
173
public Response createProduct(Product product) {
174
Product created = productService.save(product);
175
return Response.status(Response.Status.CREATED).entity(created).build();
176
}
177
178
@PUT
179
@Path("/{id}")
180
public Response updateProduct(@PathParam("id") String id, Product product) {
181
Product updated = productService.update(id, product);
182
return Response.ok(updated).build();
183
}
184
185
@DELETE
186
@Path("/{id}")
187
public Response deleteProduct(@PathParam("id") String id) {
188
productService.delete(id);
189
return Response.noContent().build();
190
}
191
192
@PATCH
193
@Path("/{id}")
194
public Response patchProduct(@PathParam("id") String id,
195
Map<String, Object> updates) {
196
Product patched = productService.patch(id, updates);
197
return Response.ok(patched).build();
198
}
199
}
200
```
201
202
### Custom HTTP Methods
203
204
```java { .api }
205
@Target({ElementType.ANNOTATION_TYPE})
206
@Retention(RetentionPolicy.RUNTIME)
207
@Documented
208
public @interface HttpMethod {
209
String value();
210
}
211
```
212
213
**Usage Example:**
214
215
```java
216
// Define custom HTTP method annotation
217
@Target({ElementType.METHOD})
218
@Retention(RetentionPolicy.RUNTIME)
219
@HttpMethod("PURGE")
220
@Documented
221
public @interface PURGE {
222
}
223
224
// Use custom method
225
@Path("/cache")
226
public class CacheResource {
227
228
@PURGE
229
@Path("/{key}")
230
public Response purgeCache(@PathParam("key") String cacheKey) {
231
cacheService.purge(cacheKey);
232
return Response.noContent().build();
233
}
234
}
235
```
236
237
## Parameter Injection Annotations
238
239
### Path Parameters
240
241
```java { .api }
242
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
243
@Retention(RetentionPolicy.RUNTIME)
244
@Documented
245
public @interface PathParam {
246
String value();
247
}
248
```
249
250
### Query Parameters
251
252
```java { .api }
253
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
254
@Retention(RetentionPolicy.RUNTIME)
255
@Documented
256
public @interface QueryParam {
257
String value();
258
}
259
```
260
261
### Header Parameters
262
263
```java { .api }
264
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
265
@Retention(RetentionPolicy.RUNTIME)
266
@Documented
267
public @interface HeaderParam {
268
String value();
269
}
270
```
271
272
### Cookie Parameters
273
274
```java { .api }
275
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
276
@Retention(RetentionPolicy.RUNTIME)
277
@Documented
278
public @interface CookieParam {
279
String value();
280
}
281
```
282
283
### Form Parameters
284
285
```java { .api }
286
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
287
@Retention(RetentionPolicy.RUNTIME)
288
@Documented
289
public @interface FormParam {
290
String value();
291
}
292
```
293
294
### Matrix Parameters
295
296
```java { .api }
297
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
298
@Retention(RetentionPolicy.RUNTIME)
299
@Documented
300
public @interface MatrixParam {
301
String value();
302
}
303
```
304
305
### Bean Parameters
306
307
```java { .api }
308
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
309
@Retention(RetentionPolicy.RUNTIME)
310
@Documented
311
public @interface BeanParam {
312
}
313
```
314
315
**Parameter Injection Usage Examples:**
316
317
```java
318
@Path("/search")
319
public class SearchResource {
320
321
@GET
322
@Path("/{category}")
323
public Response search(@PathParam("category") String category,
324
@QueryParam("q") String query,
325
@QueryParam("limit") @DefaultValue("10") int limit,
326
@QueryParam("offset") @DefaultValue("0") int offset,
327
@HeaderParam("Accept-Language") String language,
328
@HeaderParam("User-Agent") String userAgent,
329
@CookieParam("sessionId") String sessionId) {
330
331
SearchRequest request = new SearchRequest(category, query, limit, offset);
332
request.setLanguage(language);
333
request.setUserAgent(userAgent);
334
request.setSessionId(sessionId);
335
336
SearchResults results = searchService.search(request);
337
return Response.ok(results).build();
338
}
339
340
// Matrix parameters example: /products;color=red;size=large
341
@GET
342
@Path("/products")
343
public Response findProducts(@MatrixParam("color") String color,
344
@MatrixParam("size") String size,
345
@MatrixParam("brand") List<String> brands) {
346
ProductFilter filter = new ProductFilter(color, size, brands);
347
List<Product> products = productService.findByFilter(filter);
348
return Response.ok(products).build();
349
}
350
351
// Form parameters for POST requests
352
@POST
353
@Path("/contact")
354
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
355
public Response submitContactForm(@FormParam("name") String name,
356
@FormParam("email") String email,
357
@FormParam("message") String message,
358
@FormParam("subscribe") boolean subscribe) {
359
360
ContactSubmission submission = new ContactSubmission(name, email, message, subscribe);
361
contactService.submit(submission);
362
return Response.ok().build();
363
}
364
}
365
```
366
367
### Bean Parameter Example
368
369
```java
370
// Parameter aggregator class
371
public class SearchParams {
372
@QueryParam("q")
373
private String query;
374
375
@QueryParam("limit")
376
@DefaultValue("10")
377
private int limit;
378
379
@QueryParam("offset")
380
@DefaultValue("0")
381
private int offset;
382
383
@HeaderParam("Accept-Language")
384
private String language;
385
386
// Getters and setters...
387
}
388
389
@Path("/items")
390
public class ItemResource {
391
392
@GET
393
public Response searchItems(@BeanParam SearchParams params) {
394
List<Item> items = itemService.search(params);
395
return Response.ok(items).build();
396
}
397
}
398
```
399
400
### Default Values
401
402
```java { .api }
403
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
404
@Retention(RetentionPolicy.RUNTIME)
405
@Documented
406
public @interface DefaultValue {
407
String value();
408
}
409
```
410
411
## Content Negotiation
412
413
### @Consumes Annotation
414
415
Specifies the media types that a resource method can accept.
416
417
```java { .api }
418
@Target({ElementType.TYPE, ElementType.METHOD})
419
@Retention(RetentionPolicy.RUNTIME)
420
@Documented
421
public @interface Consumes {
422
String[] value() default {"*/*"};
423
}
424
```
425
426
### @Produces Annotation
427
428
Specifies the media types that a resource method can produce.
429
430
```java { .api }
431
@Target({ElementType.TYPE, ElementType.METHOD})
432
@Retention(RetentionPolicy.RUNTIME)
433
@Documented
434
public @interface Produces {
435
String[] value() default {"*/*"};
436
}
437
```
438
439
**Content Negotiation Examples:**
440
441
```java
442
@Path("/api/v1/users")
443
@Produces(MediaType.APPLICATION_JSON) // Default for all methods in class
444
public class UserApiResource {
445
446
@GET
447
@Path("/{id}")
448
public User getUser(@PathParam("id") String id) {
449
// Returns JSON by default
450
return userService.findById(id);
451
}
452
453
@GET
454
@Path("/{id}")
455
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
456
public User getUserWithXml(@PathParam("id") String id) {
457
// Can return either XML or JSON based on Accept header
458
return userService.findById(id);
459
}
460
461
@POST
462
@Consumes(MediaType.APPLICATION_JSON)
463
public Response createUser(User user) {
464
// Only accepts JSON input
465
User created = userService.create(user);
466
return Response.status(Response.Status.CREATED).entity(created).build();
467
}
468
469
@PUT
470
@Path("/{id}")
471
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
472
@Produces(MediaType.APPLICATION_JSON)
473
public Response updateUser(@PathParam("id") String id, User user) {
474
// Accepts both JSON and XML input, returns JSON
475
User updated = userService.update(id, user);
476
return Response.ok(updated).build();
477
}
478
479
@POST
480
@Path("/upload")
481
@Consumes(MediaType.MULTIPART_FORM_DATA)
482
public Response uploadUserAvatar(@PathParam("id") String userId,
483
@FormParam("file") InputStream fileStream,
484
@FormParam("filename") String filename) {
485
avatarService.upload(userId, fileStream, filename);
486
return Response.ok().build();
487
}
488
}
489
```
490
491
## Encoding Control
492
493
### @Encoded Annotation
494
495
Disables automatic URI decoding for parameter values.
496
497
```java { .api }
498
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD,
499
ElementType.CONSTRUCTOR, ElementType.TYPE})
500
@Retention(RetentionPolicy.RUNTIME)
501
@Documented
502
public @interface Encoded {
503
}
504
```
505
506
**Usage Example:**
507
508
```java
509
@Path("/files")
510
public class FileResource {
511
512
@GET
513
@Path("/{filename}")
514
public Response getFile(@PathParam("filename") @Encoded String encodedFilename,
515
@QueryParam("path") @Encoded String encodedPath) {
516
// Parameters remain URL-encoded, useful for filenames with special chars
517
String actualFilename = URLDecoder.decode(encodedFilename, "UTF-8");
518
String actualPath = URLDecoder.decode(encodedPath, "UTF-8");
519
520
File file = fileService.getFile(actualPath, actualFilename);
521
return Response.ok(file).build();
522
}
523
}
524
```
525
526
## Context Injection
527
528
JAX-RS provides several context objects that can be injected into resource methods:
529
530
```java { .api }
531
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
532
@Retention(RetentionPolicy.RUNTIME)
533
@Documented
534
public @interface Context {
535
}
536
```
537
538
**Common Context Types:**
539
540
```java
541
@Path("/info")
542
public class InfoResource {
543
544
@GET
545
public Response getRequestInfo(@Context UriInfo uriInfo,
546
@Context HttpHeaders headers,
547
@Context SecurityContext securityContext) {
548
549
Map<String, Object> info = new HashMap<>();
550
info.put("requestUri", uriInfo.getRequestUri().toString());
551
info.put("baseUri", uriInfo.getBaseUri().toString());
552
info.put("pathParameters", uriInfo.getPathParameters());
553
info.put("queryParameters", uriInfo.getQueryParameters());
554
info.put("userPrincipal", securityContext.getUserPrincipal());
555
info.put("acceptHeader", headers.getHeaderString("Accept"));
556
557
return Response.ok(info).build();
558
}
559
}
560
```
561
562
## Types
563
564
### Media Type Constants
565
566
```java { .api }
567
public class MediaType {
568
public static final String APPLICATION_JSON = "application/json";
569
public static final String APPLICATION_XML = "application/xml";
570
public static final String APPLICATION_FORM_URLENCODED = "application/x-www-form-urlencoded";
571
public static final String MULTIPART_FORM_DATA = "multipart/form-data";
572
public static final String TEXT_PLAIN = "text/plain";
573
public static final String TEXT_HTML = "text/html";
574
public static final String TEXT_XML = "text/xml";
575
public static final String WILDCARD = "*/*";
576
577
public static final MediaType APPLICATION_JSON_TYPE = new MediaType("application", "json");
578
public static final MediaType APPLICATION_XML_TYPE = new MediaType("application", "xml");
579
public static final MediaType TEXT_PLAIN_TYPE = new MediaType("text", "plain");
580
public static final MediaType WILDCARD_TYPE = new MediaType("*", "*");
581
}
582
```