1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.rest.annotation;
18
19 import static org.apache.juneau.http.HttpMethod.*;
20 import static org.junit.jupiter.api.Assertions.*;
21
22 import java.util.*;
23
24 import org.apache.http.client.config.*;
25 import org.apache.juneau.*;
26 import org.apache.juneau.annotation.*;
27 import org.apache.juneau.collections.*;
28 import org.apache.juneau.common.utils.*;
29 import org.apache.juneau.http.annotation.*;
30 import org.apache.juneau.json.*;
31 import org.apache.juneau.rest.*;
32 import org.apache.juneau.rest.httppart.*;
33 import org.apache.juneau.rest.mock.*;
34 import org.apache.juneau.testutils.pojos.*;
35 import org.junit.jupiter.api.*;
36
37 class Path_Test extends TestBase {
38
39
40
41
42
43 @Rest
44 public static class A {
45 @RestGet(path="/")
46 public void a(RestResponse res) {
47 res.setContent(GET);
48 }
49 @RestGet(path="/a")
50 public String b() {
51 return "GET /a";
52 }
53 @RestGet(path="/a/{foo}")
54 public String c(RestResponse res, @Path("foo") String foo) {
55 return "GET /a " + foo;
56 }
57 @RestGet(path="/a/{foo}/{bar}")
58 public String d(RestResponse res, @Path("foo") String foo, @Path("bar") String bar) {
59 return "GET /a " + foo + "," + bar;
60 }
61 @RestGet(path="/a/{foo}/{bar}/*")
62 public String e(@Path("foo") String foo, @Path("bar") int bar, @Path("/*") String remainder) {
63 return "GET /a "+foo+","+bar+",r="+remainder;
64 }
65 }
66
67 @Test void a01_basic() throws Exception {
68 var a = MockRestClient.buildLax(A.class);
69
70 a.get("/bad?noTrace=true")
71 .run()
72 .assertStatus(404);
73
74 a.get(null)
75 .run()
76 .assertContent("GET");
77 a.get()
78 .run()
79 .assertContent("GET");
80
81 a.get("/a")
82 .run()
83 .assertContent("GET /a");
84
85 a.get("/a/foo")
86 .run()
87 .assertContent("GET /a foo");
88
89 a.get("/a/foo/bar")
90 .run()
91 .assertContent("GET /a foo,bar");
92
93 a.get("/a/foo/123/baz")
94 .run()
95 .assertContent("GET /a foo,123,r=baz");
96
97
98
99
100
101 a.get("/a/x%2Fy")
102 .run()
103 .assertContent("GET /a x/y");
104 a.get("/a/x%2Fy/x%2Fy")
105 .run()
106 .assertContent("GET /a x/y,x/y");
107 }
108
109
110
111
112
113 @Rest
114 public static class B {
115 @RestGet(path="/a/{x}/foo")
116 public String a(@Path("x") int x) {
117 return String.valueOf(x);
118 }
119 @RestGet(path="/b/{x}/foo")
120 public String b(@Path("x") short x) {
121 return String.valueOf(x);
122 }
123 @RestGet(path="/c/{x}/foo")
124 public String c(@Path("x") long x) {
125 return String.valueOf(x);
126 }
127 @RestGet(path="/d/{x}/foo")
128 public String d(@Path("x") char x) {
129 return String.valueOf(x);
130 }
131 @RestGet(path="/e/{x}/foo")
132 public String e(@Path("x") float x) {
133 return String.valueOf(x);
134 }
135 @RestGet(path="/f/{x}/foo")
136 public String f(@Path("x") double x) {
137 return String.valueOf(x);
138 }
139 @RestGet(path="/g/{x}/foo")
140 public String g(@Path("x") byte x) {
141 return String.valueOf(x);
142 }
143 @RestGet(path="/h/{x}/foo")
144 public String h(@Path("x") boolean x) {
145 return String.valueOf(x);
146 }
147 }
148
149 @Test void b01_primitives() throws Exception {
150 var b = MockRestClient.buildLax(B.class);
151
152 b.get("/a/123/foo")
153 .run()
154 .assertContent("123");
155 b.get("/a/bad/foo?noTrace=true")
156 .run()
157 .assertStatus(400);
158
159 b.get("/b/123/foo")
160 .run()
161 .assertContent("123");
162 b.get("/b/bad/foo?noTrace=true")
163 .run()
164 .assertStatus(400);
165
166 b.get("/c/123/foo")
167 .run()
168 .assertContent("123");
169 b.get("/c/bad/foo?noTrace=true")
170 .run()
171 .assertStatus(400);
172
173 b.get("/d/c/foo")
174 .run()
175 .assertContent("c");
176 b.get("/d/bad/foo?noTrace=true")
177 .run()
178 .assertStatus(400);
179
180 b.get("/e/1.23/foo")
181 .run()
182 .assertContent("1.23");
183 b.get("/e/bad/foo?noTrace=true")
184 .run()
185 .assertStatus(400);
186
187 b.get("/f/1.23/foo")
188 .run()
189 .assertContent("1.23");
190 b.get("/f/bad/foo?noTrace=true")
191 .run()
192 .assertStatus(400);
193
194 b.get("/g/123/foo")
195 .run()
196 .assertContent("123");
197 b.get("/g/bad/foo?noTrace=true")
198 .run()
199 .assertStatus(400);
200
201 b.get("/h/true/foo")
202 .run()
203 .assertContent("true");
204 b.get("/h/bad/foo?noTrace=true")
205 .run()
206 .assertStatus(400);
207 }
208
209
210
211
212
213 @Rest
214 public static class C {
215 @RestGet(path="/a/{x}/foo")
216 public String a(@Path("x") Integer x) {
217 return String.valueOf(x);
218 }
219 @RestGet(path="/b/{x}/foo")
220 public String b(@Path("x") Short x) {
221 return String.valueOf(x);
222 }
223 @RestGet(path="/c/{x}/foo")
224 public String c(@Path("x") Long x) {
225 return String.valueOf(x);
226 }
227 @RestGet(path="/d/{x}/foo")
228 public String d(@Path("x") Character x) {
229 return String.valueOf(x);
230 }
231 @RestGet(path="/e/{x}/foo")
232 public String e(@Path("x") Float x) {
233 return String.valueOf(x);
234 }
235 @RestGet(path="/f/{x}/foo")
236 public String f(@Path("x") Double x) {
237 return String.valueOf(x);
238 }
239 @RestGet(path="/g/{x}/foo")
240 public String g(@Path("x") Byte x) {
241 return String.valueOf(x);
242 }
243 @RestGet(path="/h/{x}/foo")
244 public String h(@Path("x") Boolean x) {
245 return String.valueOf(x);
246 }
247 }
248
249 @Test void c01_primitiveObjects() throws Exception {
250 var c = MockRestClient.buildLax(C.class);
251
252 c.get("/a/123/foo")
253 .run()
254 .assertContent("123");
255 c.get("/a/bad/foo?noTrace=true")
256 .run()
257 .assertStatus(400);
258
259 c.get("/b/123/foo")
260 .run()
261 .assertContent("123");
262 c.get("/b/bad/foo?noTrace=true")
263 .run()
264 .assertStatus(400);
265
266 c.get("/c/123/foo")
267 .run()
268 .assertContent("123");
269 c.get("/c/bad/foo?noTrace=true")
270 .run()
271 .assertStatus(400);
272
273 c.get("/d/c/foo")
274 .run()
275 .assertContent("c");
276 c.get("/d/bad/foo?noTrace=true")
277 .run()
278 .assertStatus(400);
279
280 c.get("/e/1.23/foo")
281 .run()
282 .assertContent("1.23");
283 c.get("/e/bad/foo?noTrace=true")
284 .run()
285 .assertStatus(400);
286
287 c.get("/f/1.23/foo")
288 .run()
289 .assertContent("1.23");
290 c.get("/f/bad/foo?noTrace=true")
291 .run()
292 .assertStatus(400);
293
294 c.get("/g/123/foo")
295 .run()
296 .assertContent("123");
297 c.get("/g/bad/foo?noTrace=true")
298 .run()
299 .assertStatus(400);
300
301 c.get("/h/true/foo")
302 .run()
303 .assertContent("true");
304 c.get("/h/bad/foo?noTrace=true")
305 .run()
306 .assertStatus(400);
307 }
308
309
310
311
312
313 @Rest
314 public static class D {
315
316 @RestGet(path="/a/{uuid}")
317 public UUID a(RestResponse res, @Path("uuid") UUID uuid) {
318 return uuid;
319 }
320 }
321
322 @Test void d01_pojosConvertibleFromStrings() throws Exception {
323 var d = MockRestClient.build(D.class);
324
325 var uuid = UUID.randomUUID();
326 d.get("/a/" + uuid)
327 .run()
328 .assertContent(uuid.toString());
329 }
330
331
332
333
334
335 @Rest
336 public static class E {
337 @RestGet(path="/x/{foo}/{bar}")
338 public Object a(@Path String foo, @Path String bar) {
339 return JsonMap.of("m", "normal1", "foo", foo, "bar", bar);
340 }
341 @RestGet(path="/x/{foo}/x/{bar}/x")
342 public Object b(@Path String foo, @Path String bar) {
343 return JsonMap.of("m", "normal2", "foo", foo, "bar", bar);
344 }
345 @RestGet(path="/y/{0}/{1}")
346 public Object c(@Path String foo, @Path String bar) {
347 return JsonMap.of("m", "numbers1", "0", foo, "1", bar);
348 }
349 @RestGet(path="/y/{0}/y/{1}/y")
350 public Object d(@Path String foo, @Path String bar) {
351 return JsonMap.of("m", "numbers2", "0", foo, "1", bar);
352 }
353 @RestGet(path="/z/{1}/z/{0}/z")
354 public Object e(@Path String foo, @Path String bar) {
355 return JsonMap.of("m", "numbers3", "0", foo, "1", bar);
356 }
357 }
358
359 @Test void e01_withoutName() throws Exception {
360 var e = MockRestClient.build(E.class);
361 e.get("/x/x1/x2")
362 .run()
363 .assertContent("{m:'normal1',foo:'x1',bar:'x2'}");
364 e.get("/x/x1/x/x2/x")
365 .run()
366 .assertContent("{m:'normal2',foo:'x1',bar:'x2'}");
367 e.get("/y/y1/y2")
368 .run()
369 .assertContent("{m:'numbers1','0':'y1','1':'y2'}");
370 e.get("/y/y1/y/y2/y")
371 .run()
372 .assertContent("{m:'numbers2','0':'y1','1':'y2'}");
373 e.get("/z/z1/z/z2/z")
374 .run()
375 .assertContent("{m:'numbers3','0':'z2','1':'z1'}");
376 }
377
378
379
380
381
382 @Rest(path="/f/{a}/{b}")
383 public static class F {
384 @RestGet(path="/")
385 public String a(RequestPathParams path) {
386 return format("a: {0}", path.toString());
387 }
388 @RestGet(path="/*")
389 public String b(RequestPathParams path) {
390 return format("b: {0}", path.toString());
391 }
392 @RestGet(path="/fc")
393 public String c(RequestPathParams path) {
394 return format("c: {0}", path.toString());
395 }
396 @RestGet(path="/fd/{c}/{d}")
397 public String d(RequestPathParams path) {
398 return format("d: {0}", path.toString());
399 }
400 @RestGet(path="/fe/{a}/{b}")
401 public String e(RequestPathParams path) {
402 return format("e: {0}", path.toString());
403 }
404 @RestGet(path="/ff/{c}/{d}/*")
405 public String f(RequestPathParams path) {
406 return format("f: {0}", path.toString());
407 }
408 private String format(String msg, Object...args) {
409 return StringUtils.format(msg, args);
410 }
411 }
412
413 @Test void f01_pathVariablesOnClass() throws Exception {
414 var f = MockRestClient.createLax(F.class).servletPath("/f").defaultRequestConfig(RequestConfig.custom().setNormalizeUri(false).build()).build();
415 f.get("http://localhost/f/x1/x2")
416 .run()
417 .assertContent("a: {a:'x1',b:'x2'}");
418 f.get("http://localhost/f/x1")
419 .run()
420 .assertStatus(404);
421 f.get("http://localhost/f")
422 .run()
423 .assertStatus(404);
424 f.get("http://localhost/f//")
425 .run()
426 .assertStatus(404);
427 f.get("http://localhost/f/x/")
428 .run()
429 .assertStatus(404);
430 f.get("http://localhost/f//x")
431 .run()
432 .assertStatus(404);
433 f.get("http://localhost/f/x1/x2/foo")
434 .run()
435 .assertContent("b: {a:'x1',b:'x2','/**':'foo','/*':'foo'}");
436 f.get("http://localhost/f///foo")
437 .run()
438 .assertStatus(404);
439 f.get("http://localhost/f/x1//foo")
440 .run()
441 .assertStatus(404);
442 f.get("http://localhost/f//x2/foo")
443 .run()
444 .assertStatus(404);
445 f.get("http://localhost/f/x1/x2/fc")
446 .run()
447 .assertContent("c: {a:'x1',b:'x2'}");
448 f.get("http://localhost/f///a")
449 .run()
450 .assertStatus(404);
451 f.get("http://localhost/f/x1//a")
452 .run()
453 .assertStatus(404);
454 f.get("http://localhost/f//x2/a")
455 .run()
456 .assertStatus(404);
457 f.get("http://localhost/f/x1/x2/fd/x3/x4")
458 .run()
459 .assertContent("d: {a:'x1',b:'x2',c:'x3',d:'x4'}");
460 f.get("http://localhost/f//x2/b/x3/x4")
461 .run()
462 .assertStatus(404);
463 f.get("http://localhost/f/x1//b/x3/x4")
464 .run()
465 .assertStatus(404);
466 f.get("http://localhost/f/x1/x2/b//x4")
467 .run()
468 .assertStatus(200);
469 f.get("http://localhost/f/x1/x2/b/x3/")
470 .run()
471 .assertStatus(200);
472 f.get("http://localhost/f///b//")
473 .run()
474 .assertStatus(404);
475 f.get("http://localhost/f/x1/x2/fe/x3/x4")
476 .run()
477 .assertContent("e: {a:'x1, x3',b:'x2, x4'}");
478 f.get("http://localhost/f/x1/x2/ff/x3/x4")
479 .run()
480 .assertContent("f: {a:'x1',b:'x2',c:'x3',d:'x4'}");
481 f.get("http://localhost/f/x1/x2/ff/x3/x4/")
482 .run()
483 .assertContent("f: {a:'x1',b:'x2',c:'x3',d:'x4','/**':'','/*':''}");
484 f.get("http://localhost/f/x1/x2/ff/x3/x4/foo/bar")
485 .run()
486 .assertContent("f: {a:'x1',b:'x2',c:'x3',d:'x4','/**':'foo/bar','/*':'foo/bar'}");
487 }
488
489
490
491
492
493 @Rest(children={F.class})
494 public static class G {}
495
496
497 @Test void g01_pathVariablesOnChildClass() throws Exception {
498 var g = MockRestClient.createLax(G.class).defaultRequestConfig(RequestConfig.custom().setNormalizeUri(false).build()).build();
499 g.get("http://localhost/f/x1/x2")
500 .run()
501 .assertContent("a: {a:'x1',b:'x2'}");
502 g.get("http://localhost/f/x1")
503 .run()
504 .assertStatus(404);
505 g.get("http://localhost/f")
506 .run()
507 .assertStatus(404);
508 g.get("http://localhost/f//")
509 .run()
510 .assertStatus(404);
511 g.get("http://localhost/f/x1/")
512 .run()
513 .assertStatus(404);
514 g.get("http://localhost/f//x2")
515 .run()
516 .assertStatus(404);
517 g.get("http://localhost/f/x1/x2/fc")
518 .run()
519 .assertContent("c: {a:'x1',b:'x2'}");
520 g.get("http://localhost/f///a")
521 .run()
522 .assertStatus(404);
523 g.get("http://localhost/f/x1//a")
524 .run()
525 .assertStatus(404);
526 g.get("http://localhost/f//x2/a")
527 .run()
528 .assertStatus(404);
529 g.get("http://localhost/f/x1/x2/fd/x3/x4")
530 .run()
531 .assertContent("d: {a:'x1',b:'x2',c:'x3',d:'x4'}");
532 g.get("http://localhost/f//x2/b/x3/x4")
533 .run()
534 .assertStatus(404);
535 g.get("http://localhost/f/x1//b/x3/x4")
536 .run()
537 .assertStatus(404);
538 g.get("http://localhost/f/x1/x2/b//x4")
539 .run()
540 .assertStatus(200);
541 g.get("http://localhost/f/x1/x2/b/x3/")
542 .run()
543 .assertStatus(200);
544 g.get("http://localhost/f///b//")
545 .run()
546 .assertStatus(404);
547 g.get("http://localhost/f/x1/x2/fe/x3/x4")
548 .run()
549 .assertContent("e: {a:'x1, x3',b:'x2, x4'}");
550 g.get("http://localhost/f/x1/x2/ff/x3/x4")
551 .run()
552 .assertContent("f: {a:'x1',b:'x2',c:'x3',d:'x4'}");
553 g.get("http://localhost/f/x1/x2/ff/x3/x4/")
554 .run()
555 .assertContent("f: {a:'x1',b:'x2',c:'x3',d:'x4','/**':'','/*':''}");
556 g.get("http://localhost/f/x1/x2/ff/x3/x4/foo/bar")
557 .run()
558 .assertContent("f: {a:'x1',b:'x2',c:'x3',d:'x4','/**':'foo/bar','/*':'foo/bar'}");
559 }
560
561
562
563
564
565 @Rest(path="/h/{ha}/{hb}", children={F.class})
566 public static class H {}
567
568 @Test void h01_pathVariablesOnParentAndChildClass() throws Exception {
569 var h = MockRestClient.createLax(H.class).servletPath("/h").defaultRequestConfig(RequestConfig.custom().setNormalizeUri(false).build()).build();
570 h.get("http://localhost/h/ha1/hb1/f/x1/x2")
571 .run()
572 .assertContent("a: {a:'x1',b:'x2',ha:'ha1',hb:'hb1'}");
573
574 h.get("http://localhost/h/ha1/hb1/f/x1")
575 .run()
576 .assertStatus(404);
577 h.get("http://localhost/h/ha1/hb1/f")
578 .run()
579 .assertStatus(404);
580 h.get("http://localhost/h/ha1/hb1")
581 .run()
582 .assertStatus(404);
583 h.get("http://localhost/h/ha1")
584 .run()
585 .assertStatus(404);
586 h.get("http://localhost/h")
587 .run()
588 .assertStatus(404);
589 h.get("http://localhost/h//hb1/f/x1/x2")
590 .run()
591 .assertStatus(404);
592 h.get("http://localhost/h/ha1//f/x1/x2")
593 .run()
594 .assertStatus(404);
595 h.get("http://localhost/h/ha1/hb1/f//x2")
596 .run()
597 .assertStatus(404);
598 h.get("http://localhost/h/ha1/hb1/f/x1/")
599 .run()
600 .assertStatus(404);
601 h.get("http://localhost/h///f//")
602 .run()
603 .assertStatus(404);
604 h.get("http://localhost/h/ha1/hb1/f/x1/x2/foo")
605 .run()
606 .assertContent("b: {a:'x1',b:'x2',ha:'ha1',hb:'hb1','/**':'foo','/*':'foo'}");
607 h.get("http://localhost/h//hb1/f/x1/x2/foo")
608 .run()
609 .assertStatus(404);
610 h.get("http://localhost/h/ha1//f/x1/x2/foo")
611 .run()
612 .assertStatus(404);
613 h.get("http://localhost/h/ha1/hb1/f//x2/foo")
614 .run()
615 .assertStatus(404);
616 h.get("http://localhost/h/ha1/hb1/f/x1//foo")
617 .run()
618 .assertStatus(404);
619 h.get("http://localhost/h///f///foo")
620 .run()
621 .assertStatus(404);
622 h.get("http://localhost/h/ha1/hb1/f/x1/x2/fc")
623 .run()
624 .assertContent("c: {a:'x1',b:'x2',ha:'ha1',hb:'hb1'}");
625 h.get("http://localhost/h//hb1/f/x1/x2/a")
626 .run()
627 .assertStatus(404);
628 h.get("http://localhost/h/ha1//f/x1/x2/a")
629 .run()
630 .assertStatus(404);
631 h.get("http://localhost/h/ha1/hb1/f//x2/a")
632 .run()
633 .assertStatus(404);
634 h.get("http://localhost/h/ha1/hb1/f/x1//a")
635 .run()
636 .assertStatus(404);
637 h.get("http://localhost/h///f///a")
638 .run()
639 .assertStatus(404);
640 h.get("http://localhost/h/ha1/hb1/f/x1/x2/fd/x3/x4")
641 .run()
642 .assertContent("d: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',c:'x3',d:'x4'}");
643 h.get("http://localhost/h/ha1/hb1/f/x1/x2/fe/x3/x4")
644 .run()
645 .assertContent("e: {a:'x1, x3',b:'x2, x4',ha:'ha1',hb:'hb1'}");
646 h.get("http://localhost/h/ha1/hb1/f/x1/x2/ff/x3/x4")
647 .run()
648 .assertContent("f: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',c:'x3',d:'x4'}");
649 h.get("http://localhost/h/ha1/hb1/f/x1/x2/ff/x3/x4/")
650 .run()
651 .assertContent("f: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',c:'x3',d:'x4','/**':'','/*':''}");
652 h.get("http://localhost/h/ha1/hb1/f/x1/x2/ff/x3/x4/foo/bar")
653 .run()
654 .assertContent("f: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',c:'x3',d:'x4','/**':'foo/bar','/*':'foo/bar'}");
655 }
656
657
658
659
660
661 @Rest(path="/i/{ia}/{ib}", children={H.class})
662 public static class I {}
663
664 @Test void i01_pathVariablesOnParentAndChildClass() throws Exception {
665 var i = MockRestClient.createLax(I.class).servletPath("/i").build();
666 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/x2")
667 .run()
668 .assertContent("a: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
669 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1")
670 .run()
671 .assertStatus(404);
672 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f")
673 .run()
674 .assertStatus(404);
675 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1")
676 .run()
677 .assertStatus(404);
678 i.get("http://localhost/i/ia1/ib1/h/ha1")
679 .run()
680 .assertStatus(404);
681 i.get("http://localhost/i/ia1/ib1/h")
682 .run()
683 .assertStatus(404);
684 i.get("http://localhost/i/ia1/ib1")
685 .run()
686 .assertStatus(404);
687 i.get("http://localhost/i/ia1")
688 .run()
689 .assertStatus(404);
690 i.get("http://localhost/i")
691 .run()
692 .assertStatus(404);
693 i.get("http://localhost/i//ib1/h/ha1/hb1/f/x1/x2")
694 .run()
695 .assertStatus(404);
696 i.get("http://localhost/i/ia1//h/ha1/hb1/f/x1/x2")
697 .run()
698 .assertStatus(404);
699 i.get("http://localhost/i/ia1/ib1/h//hb1/f/x1/x2")
700 .run()
701 .assertStatus(404);
702 i.get("http://localhost/i/ia1/ib1/h/ha1//f/x1/x2")
703 .run()
704 .assertStatus(404);
705 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f//x2")
706 .run()
707 .assertStatus(404);
708 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/")
709 .run()
710 .assertStatus(404);
711 i.get("http://localhost/i///h///f//")
712 .run()
713 .assertStatus(404);
714 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/x2/foo")
715 .run()
716 .assertContent("b: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1','/**':'foo','/*':'foo'}");
717 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/x2/fc")
718 .run()
719 .assertContent("c: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
720 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/x2/fd/x3/x4")
721 .run()
722 .assertContent("d: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1',c:'x3',d:'x4'}");
723 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/x2/fe/x3/x4")
724 .run()
725 .assertContent("e: {a:'x1, x3',b:'x2, x4',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1'}");
726 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/x2/ff/x3/x4")
727 .run()
728 .assertContent("f: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1',c:'x3',d:'x4'}");
729 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/x2/ff/x3/x4/")
730 .run()
731 .assertContent("f: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1',c:'x3',d:'x4','/**':'','/*':''}");
732 i.get("http://localhost/i/ia1/ib1/h/ha1/hb1/f/x1/x2/ff/x3/x4/foo/bar")
733 .run()
734 .assertContent("f: {a:'x1',b:'x2',ha:'ha1',hb:'hb1',ia:'ia1',ib:'ib1',c:'x3',d:'x4','/**':'foo/bar','/*':'foo/bar'}");
735 }
736
737
738
739
740
741 @Rest(serializers=Json5Serializer.class)
742 public static class J {
743 @RestGet(path="/a/{f1}")
744 public Object a(@Path("f1") Optional<Integer> f1) {
745 assertNotNull(f1);
746 return f1;
747 }
748 @RestGet(path="/b/{f1}")
749 public Object b(@Path("f1") Optional<ABean> f1) {
750 assertNotNull(f1);
751 return f1;
752 }
753 @RestGet(path="/c/{f1}")
754 public Object c(@Path("f1") Optional<List<ABean>> f1) {
755 assertNotNull(f1);
756 return f1;
757 }
758 @RestGet(path="/d/{f1}")
759 public Object d(@Path("f1") List<Optional<ABean>> f1) {
760 return f1;
761 }
762 }
763
764 @Test void j01_optionalParam() throws Exception {
765 var j = MockRestClient.buildJson(J.class);
766 j.get("/a/123")
767 .run()
768 .assertStatus(200)
769 .assertContent("123");
770 j.get("/b/a=1,b=foo")
771 .run()
772 .assertStatus(200)
773 .assertContent("{a:1,b:'foo'}");
774 j.get("/c/@((a=1,b=foo))")
775 .run()
776 .assertStatus(200)
777 .assertContent("[{a:1,b:'foo'}]");
778 j.get("/d/@((a=1,b=foo))")
779 .run()
780 .assertStatus(200)
781 .assertContent("[{a:1,b:'foo'}]");
782 }
783
784
785
786
787
788 @Rest(path="/k1/{k1}",children=K2.class)
789 public static class K1 {}
790
791 @Rest(path="/k2")
792 public static class K2 {
793 @RestGet(path="/")
794 public String a(@Path("k1") @Schema(r=false) String k1) {
795 return k1 == null ? "nil" : k1;
796 }
797 @RestGet(path="/foo/{bar}")
798 public String b(@Path("k1") @Schema(r=false) String k1, @Path("bar") @Schema(r=false) String bar) {
799 return (k1 == null ? "nil" : k1) + "," + (bar == null ? "nil" : bar);
800 }
801 }
802
803 @Test void k01_basic() throws Exception {
804 var k1 = MockRestClient.build(K1.class);
805 var k2 = MockRestClient.build(K2.class);
806
807 k1.get("http://localhost/k1/foo/k2")
808 .run()
809 .assertStatus(200)
810 .assertContent("foo");
811 k1.get("http://localhost/k1/foo/k2/foo/xxx")
812 .run()
813 .assertStatus(200)
814 .assertContent("foo,xxx");
815 k2.get("/")
816 .run()
817 .assertStatus(200)
818 .assertContent("nil");
819 k2.get("/foo/xxx")
820 .run()
821 .assertStatus(200)
822 .assertContent("nil,xxx");
823 }
824
825
826
827
828
829 @Rest(path="/l1/{l1}",children=L2.class)
830 public static class L1 {}
831
832 @Rest(path="/l2")
833 public static class L2 {
834 @RestGet(path={"/","/{foo}"})
835 public String a(@Path("l1") @Schema(r=false) String l1, @Path("foo") @Schema(r=false) String foo) {
836 return "1," + (l1 == null ? "nil" : l1) + "," + (foo == null ? "nil" : foo);
837 }
838 @RestGet(path={"/foo","/foo/{foo}"})
839 public String b(@Path("l1") @Schema(r=false) String l1, @Path("foo") @Schema(r=false) String foo) {
840 return "2," + (l1 == null ? "nil" : l1) + "," + (foo == null ? "nil" : foo);
841 }
842 }
843
844 @Test void l01_multiplePaths() throws Exception {
845 var l1 = MockRestClient.build(L1.class);
846 var l2 = MockRestClient.build(L2.class);
847
848 l1.get("http://localhost/l1/l1foo/l2")
849 .run()
850 .assertStatus(200)
851 .assertContent("1,l1foo,nil");
852 l1.get("http://localhost/l1/l1foo/l2/l2foo")
853 .run()
854 .assertStatus(200)
855 .assertContent("1,l1foo,l2foo");
856 l1.get("http://localhost/l1/l1foo/l2/foo")
857 .run()
858 .assertStatus(200)
859 .assertContent("2,l1foo,nil");
860 l1.get("http://localhost/l1/l1foo/l2/foo/l2foo")
861 .run()
862 .assertStatus(200)
863 .assertContent("2,l1foo,l2foo");
864 l2.get("http://localhost/l2")
865 .run()
866 .assertStatus(200)
867 .assertContent("1,nil,nil");
868 l2.get("http://localhost/l2/l2foo")
869 .run()
870 .assertStatus(200)
871 .assertContent("1,nil,l2foo");
872 l2.get("http://localhost/l2/foo")
873 .run()
874 .assertStatus(200)
875 .assertContent("2,nil,nil");
876 l2.get("http://localhost/l2/foo/l2foo")
877 .run()
878 .assertStatus(200)
879 .assertContent("2,nil,l2foo");
880 }
881 }