001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.rest.annotation; 014 015import static java.lang.annotation.ElementType.*; 016import static java.lang.annotation.RetentionPolicy.*; 017 018import java.lang.annotation.*; 019 020import org.apache.juneau.*; 021import org.apache.juneau.annotation.*; 022import org.apache.juneau.config.*; 023import org.apache.juneau.encoders.*; 024import org.apache.juneau.httppart.*; 025import org.apache.juneau.parser.*; 026import org.apache.juneau.rest.*; 027import org.apache.juneau.serializer.*; 028import org.apache.juneau.utils.*; 029 030/** 031 * Used to denote that a class is a REST resource and to associate metadata on it. 032 * 033 * <div class='warn'> 034 * <b>Deprecated</b> - Use {@link Rest} 035 * </div> 036 * 037 * <p> 038 * Usually used on a subclass of {@link RestServlet}, but can be used to annotate any class that you want to expose as 039 * a REST resource. 040 * 041 * <ul class='seealso'> 042 * <li class='link'>{@doc juneau-rest-server.Rest} 043 * </ul> 044 */ 045@SuppressWarnings("deprecation") 046@Documented 047@Target(TYPE) 048@Retention(RUNTIME) 049@Inherited 050@PropertyStoreApply(RestResourceConfigApply.class) 051@Deprecated 052public @interface RestResource { 053 054 /** 055 * Allow body URL parameter. 056 * 057 * <p> 058 * When enabled, the HTTP body content on PUT and POST requests can be passed in as text using the <js>"body"</js> 059 * URL parameter. 060 * <br> 061 * For example: 062 * <p class='bcode w800'> 063 * ?body=(name='John%20Smith',age=45) 064 * </p> 065 * 066 * <ul class='notes'> 067 * <li> 068 * Supports {@doc DefaultRestSvlVariables} 069 * (e.g. <js>"$L{my.localized.variable}"</js>). 070 * </ul> 071 * 072 * <ul class='seealso'> 073 * <li class='jf'>{@link RestContext#REST_allowBodyParam} 074 * </ul> 075 */ 076 String allowBodyParam() default ""; 077 078 /** 079 * Configuration property: Allowed header URL parameters. 080 * 081 * <p> 082 * When specified, allows headers such as <js>"Accept"</js> and <js>"Content-Type"</js> to be passed in as URL query 083 * parameters. 084 * <br> 085 * For example: 086 * <p class='bcode w800'> 087 * ?Accept=text/json&Content-Type=text/json 088 * </p> 089 * 090 * <ul class='notes'> 091 * <li> 092 * Supports {@doc DefaultRestSvlVariables} 093 * (e.g. <js>"$L{my.localized.variable}"</js>). 094 * <li> 095 * Use <js>"*"</js> to represent all methods. 096 * <li> 097 * Use <js>"NONE"</js> (case insensitive) to suppress inheriting a value from a parent class. 098 * </ul> 099 * 100 * <ul class='seealso'> 101 * <li class='jf'>{@link RestContext#REST_allowedHeaderParams} 102 * </ul> 103 */ 104 String allowedHeaderParams() default ""; 105 106 /** 107 * Configuration property: Allowed method headers. 108 * 109 * <p> 110 * A comma-delimited list of HTTP method names that are allowed to be passed as values in an <c>X-Method</c> HTTP header 111 * to override the real HTTP method name. 112 * <p> 113 * Allows you to override the actual HTTP method with a simulated method. 114 * <br>For example, if an HTTP Client API doesn't support <c>PATCH</c> but does support <c>POST</c> (because 115 * <c>PATCH</c> is not part of the original HTTP spec), you can add a <c>X-Method: PATCH</c> header on a normal 116 * <c>HTTP POST /foo</c> request call which will make the HTTP call look like a <c>PATCH</c> request in any of the REST APIs. 117 * 118 * <ul class='notes'> 119 * <li> 120 * Supports {@doc DefaultRestSvlVariables} 121 * (e.g. <js>"$L{my.localized.variable}"</js>). 122 * <li> 123 * Method names are case-insensitive. 124 * <li> 125 * Use <js>"*"</js> to represent all methods. 126 * <li> 127 * Use <js>"NONE"</js> (case insensitive) to suppress inheriting a value from a parent class. 128 * </ul> 129 */ 130 String allowedMethodHeaders() default ""; 131 132 /** 133 * Allowed method parameters. 134 * 135 * <p> 136 * When specified, the HTTP method can be overridden by passing in a <js>"method"</js> URL parameter on a regular 137 * GET request. 138 * <br> 139 * For example: 140 * <p class='bcode w800'> 141 * ?method=OPTIONS 142 * </p> 143 * 144 * <ul class='notes'> 145 * <li> 146 * Supports {@doc DefaultRestSvlVariables} 147 * (e.g. <js>"$L{my.localized.variable}"</js>). 148 * <li> 149 * Use <js>"*"</js> to represent all methods. 150 * <li> 151 * Use <js>"NONE"</js> (case insensitive) to suppress inheriting a value from a parent class. 152 * </ul> 153 * 154 * <ul class='seealso'> 155 * <li class='jf'>{@link RestContext#REST_allowedMethodParams} 156 * </ul> 157 */ 158 String allowedMethodParams() default ""; 159 160 /** 161 * Allow header URL parameters. 162 * 163 * <p> 164 * When enabled, headers such as <js>"Accept"</js> and <js>"Content-Type"</js> to be passed in as URL query 165 * parameters. 166 * <br> 167 * For example: 168 * <p class='bcode w800'> 169 * ?Accept=text/json&Content-Type=text/json 170 * </p> 171 * 172 * <ul class='notes'> 173 * <li> 174 * Supports {@doc DefaultRestSvlVariables} 175 * (e.g. <js>"$L{my.localized.variable}"</js>). 176 * </ul> 177 * 178 * <ul class='seealso'> 179 * <li class='jf'>{@link RestContext#REST_allowHeaderParams} 180 * </ul> 181 */ 182 String allowHeaderParams() default ""; 183 184 /** 185 * Default request attributes. 186 * 187 * <p> 188 * Specifies default values for request attributes if they're not already set on the request. 189 * 190 * <ul class='notes'> 191 * <li> 192 * Supports {@doc DefaultRestSvlVariables} 193 * (e.g. <js>"$L{my.localized.variable}"</js>). 194 * </ul> 195 * 196 * <ul class='seealso'> 197 * <li class='jf'>{@link RestContext#REST_reqAttrs} 198 * </ul> 199 */ 200 String[] attrs() default {}; 201 202 /** 203 * Class-level bean filters. 204 * 205 * <p> 206 * Shortcut to add bean filters to the bean contexts of all serializers and parsers on all methods in the class. 207 * 208 * <ul class='seealso'> 209 * <li class='jf'>{@link BeanContext#BEAN_beanFilters} 210 * </ul> 211 */ 212 Class<?>[] beanFilters() default {}; 213 214 /** 215 * REST call handler. 216 * 217 * <p> 218 * This class handles the basic lifecycle of an HTTP REST call. 219 * 220 * <ul class='seealso'> 221 * <li class='jf'>{@link RestContext#REST_callHandler} 222 * </ul> 223 */ 224 Class<? extends RestCallHandler> callHandler() default RestCallHandler.Null.class; 225 226 /** 227 * REST children. 228 * 229 * <p> 230 * Defines children of this resource. 231 * 232 * <ul class='seealso'> 233 * <li class='jf'>{@link RestContext#REST_children} 234 * </ul> 235 */ 236 Class<?>[] children() default {}; 237 238 /** 239 * Classpath resource finder. 240 * 241 * <p> 242 * Used to retrieve localized files from the classpath. 243 * 244 * <ul class='seealso'> 245 * <li class='jf'>{@link RestContext#REST_classpathResourceFinder} 246 * </ul> 247 */ 248 Class<? extends ClasspathResourceFinder> classpathResourceFinder() default ClasspathResourceFinder.Null.class; 249 250 /** 251 * Client version header. 252 * 253 * <p> 254 * Specifies the name of the header used to denote the client version on HTTP requests. 255 * 256 * <ul class='notes'> 257 * <li> 258 * Supports {@doc DefaultRestSvlVariables} 259 * (e.g. <js>"$L{my.localized.variable}"</js>). 260 * </ul> 261 * 262 * <ul class='seealso'> 263 * <li class='jf'>{@link RestContext#REST_clientVersionHeader} 264 * </ul> 265 */ 266 String clientVersionHeader() default ""; 267 268 /** 269 * Optional location of configuration file for this servlet. 270 * 271 * <p> 272 * The configuration file . 273 * 274 * <ul class='notes'> 275 * <li> 276 * Supports {@doc DefaultRestSvlVariables} 277 * (e.g. <js>"$L{my.localized.variable}"</js>). 278 * <li> 279 * Use the keyword <c>SYSTEM_DEFAULT</c> to refer to the system default configuration 280 * returned by the {@link Config#getSystemDefault()}. 281 * </ul> 282 * 283 * <ul class='seealso'> 284 * <li class='jm'>{@link RestContextBuilder#config(Config)} 285 * </ul> 286 */ 287 String config() default ""; 288 289 /** 290 * Class-level response converters. 291 * 292 * <p> 293 * Associates one or more {@link RestConverter converters} with a resource class. 294 * 295 * <ul class='seealso'> 296 * <li class='jf'>{@link RestContext#REST_converters} 297 * </ul> 298 */ 299 Class<? extends RestConverter>[] converters() default {}; 300 301 /** 302 * Default <c>Accept</c> header. 303 * 304 * <p> 305 * The default value for the <c>Accept</c> header if not specified on a request. 306 * 307 * <p> 308 * This is a shortcut for using {@link #defaultRequestHeaders()} for just this specific header. 309 * 310 * <ul class='notes'> 311 * <li> 312 * Supports {@doc DefaultRestSvlVariables} 313 * (e.g. <js>"$L{my.localized.variable}"</js>). 314 * </ul> 315 */ 316 String defaultAccept() default ""; 317 318 /** 319 * Default character encoding. 320 * 321 * <p> 322 * The default character encoding for the request and response if not specified on the request. 323 * 324 * <ul class='notes'> 325 * <li> 326 * Supports {@doc DefaultRestSvlVariables} 327 * (e.g. <js>"$L{my.localized.variable}"</js>). 328 * </ul> 329 * 330 * <ul class='seealso'> 331 * <li class='jf'>{@link RestContext#REST_defaultCharset} 332 * </ul> 333 */ 334 String defaultCharset() default ""; 335 336 /** 337 * Default <c>Content-Type</c> header. 338 * 339 * <p> 340 * The default value for the <c>Content-Type</c> header if not specified on a request. 341 * 342 * <p> 343 * This is a shortcut for using {@link #defaultRequestHeaders()} for just this specific header. 344 * 345 * <ul class='notes'> 346 * <li> 347 * Supports {@doc DefaultRestSvlVariables} 348 * (e.g. <js>"$L{my.localized.variable}"</js>). 349 * </ul> 350 */ 351 String defaultContentType() default ""; 352 353 /** 354 * Default request headers. 355 * 356 * <p> 357 * Specifies default values for request headers if they're not passed in through the request. 358 * 359 * <ul class='notes'> 360 * <li> 361 * Supports {@doc DefaultRestSvlVariables} 362 * (e.g. <js>"$L{my.localized.variable}"</js>). 363 * </ul> 364 * 365 * <ul class='seealso'> 366 * <li class='jf'>{@link RestContext#REST_reqHeaders} 367 * </ul> 368 */ 369 String[] defaultRequestHeaders() default {}; 370 371 /** 372 * Default response headers. 373 * 374 * <p> 375 * Specifies default values for response headers if they're not set after the Java REST method is called. 376 * 377 * <ul class='notes'> 378 * <li> 379 * Supports {@doc DefaultRestSvlVariables} 380 * (e.g. <js>"$L{my.localized.variable}"</js>). 381 * </ul> 382 * 383 * <ul class='seealso'> 384 * <li class='jf'>{@link RestContext#REST_resHeaders} 385 * </ul> 386 */ 387 String[] defaultResponseHeaders() default {}; 388 389 /** 390 * Optional servlet description. 391 * 392 * <p> 393 * It is used to populate the Swagger description field. 394 * <br>This value can be retrieved programmatically through the {@link RestRequest#getResourceDescription()} method. 395 * 396 * <ul class='notes'> 397 * <li> 398 * Supports {@doc DefaultRestSvlVariables} 399 * (e.g. <js>"$L{my.localized.variable}"</js>). 400 * <li> 401 * The format is plain-text. 402 * <br>Multiple lines are concatenated with newlines. 403 * </ul> 404 * 405 * <ul class='seealso'> 406 * <li class='jm'>{@link RestInfoProvider#getDescription(RestRequest)} 407 * </ul> 408 */ 409 String[] description() default {}; 410 411 /** 412 * Compression encoders. 413 * 414 * <p> 415 * These can be used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses. 416 * 417 * <ul class='seealso'> 418 * <li class='jf'>{@link RestContext#REST_encoders} 419 * </ul> 420 */ 421 Class<? extends Encoder>[] encoders() default {}; 422 423 /** 424 * Shortcut for setting {@link #properties()} of simple boolean types. 425 * 426 * <ul class='notes'> 427 * <li> 428 * Supports {@doc DefaultRestSvlVariables} 429 * (e.g. <js>"$L{my.localized.variable}"</js>). 430 * <li> 431 * Setting a flag is equivalent to setting the same property to <js>"true"</js>. 432 * </ul> 433 */ 434 String[] flags() default {}; 435 436 /** 437 * Class-level guards. 438 * 439 * <p> 440 * Associates one or more {@link RestGuard RestGuards} with all REST methods defined in this class. 441 * 442 * <ul class='seealso'> 443 * <li class='jf'>{@link RestContext#REST_guards} 444 * </ul> 445 */ 446 Class<? extends RestGuard>[] guards() default {}; 447 448 /** 449 * Provides HTML-doc-specific metadata on this method. 450 * 451 * <p> 452 * Used to customize the output from the HTML Doc serializer. 453 * <p class='bcode w800'> 454 * <ja>@RestResource</ja>( 455 * path=<js>"/addressBook"</js>, 456 * 457 * <jc>// Links on the HTML rendition page. 458 * // "request:/..." URIs are relative to the request URI. 459 * // "servlet:/..." URIs are relative to the servlet URI. 460 * // "$C{...}" variables are pulled from the config file.</jc> 461 * htmldoc=<ja>@HtmlDoc</ja>( 462 * <jc>// Widgets for $W variables.</jc> 463 * widgets={ 464 * PoweredByJuneau.<jk>class</jk>, 465 * ContentTypeLinks.<jk>class</jk> 466 * } 467 * navlinks={ 468 * <js>"up: request:/.."</js>, 469 * <js>"options: servlet:/?method=OPTIONS"</js>, 470 * <js>"stats: servlet:/stats"</js>, 471 * <js>"source: $C{Source/gitHub}/org/apache/juneau/examples/rest/addressbook/AddressBookResource.java"</js>, 472 * }, 473 * aside={ 474 * <js>"<div style='max-width:400px;min-width:200px'>"</js>, 475 * <js>" <p>Proof-of-concept resource that shows off the capabilities of working with POJO resources.</p>"</js>, 476 * <js>" <p>Provides examples of: </p>"</js>, 477 * <js>" <ul>"</js>, 478 * <js>" <li>XML and RDF namespaces"</js>, 479 * <js>" <li>Swagger documentation"</js>, 480 * <js>" <li>Widgets"</js>, 481 * <js>" </ul>"</js>, 482 * <js>" <p style='text-weight:bold;text-decoration:underline;'>Available Content Types</p>"</js>, 483 * <js>" $W{ContentTypeLinks}"</js>, 484 * <js>"</div>"</js> 485 * }, 486 * footer=<js>"$W{PoweredByJuneau}"</js> 487 * ) 488 * ) 489 * </p> 490 * 491 * <ul class='seealso'> 492 * <li class='link'>{@doc juneau-rest-server.HtmlDocAnnotation} 493 * </ul> 494 */ 495 HtmlDoc htmldoc() default @HtmlDoc; 496 497 /** 498 * Configuration property: REST info provider. 499 * 500 * <p> 501 * Class used to retrieve title/description/swagger information about a resource. 502 * 503 * <ul class='seealso'> 504 * <li class='jf'>{@link RestContext#REST_infoProvider} 505 * </ul> 506 */ 507 Class<? extends RestInfoProvider> infoProvider() default RestInfoProvider.Null.class; 508 509 /** 510 * REST logger. 511 * 512 * <p> 513 * Specifies the logger to use for logging. 514 * 515 * <ul class='seealso'> 516 * <li class='jf'>{@link RestContext#REST_logger} 517 * </ul> 518 */ 519 Class<? extends RestLogger> logger() default RestLogger.Null.class; 520 521 /** 522 * Specifies the logger to use for logging of HTTP requests and responses. 523 * 524 * <ul class='seealso'> 525 * <li class='jf'>{@link RestContext#REST_callLogger} 526 * <li class='link'>{@doc juneau-rest-server.LoggingAndDebugging} 527 * </ul> 528 */ 529 Class<? extends RestCallLogger> callLogger() default RestCallLogger.Null.class; 530 531 /** 532 * Specifies rules on how to handle logging of HTTP requests/responses. 533 * 534 * <ul class='seealso'> 535 * <li class='jf'>{@link RestContext#REST_callLoggerConfig} 536 * <li class='link'>{@doc juneau-rest-server.LoggingAndDebugging} 537 * </ul> 538 */ 539 Logging logging() default @Logging; 540 541 /** 542 * The maximum allowed input size (in bytes) on HTTP requests. 543 * 544 * <p> 545 * Useful for alleviating DoS attacks by throwing an exception when too much input is received instead of resulting 546 * in out-of-memory errors which could affect system stability. 547 * 548 * <ul class='notes'> 549 * <li> 550 * Supports {@doc DefaultRestSvlVariables} 551 * (e.g. <js>"$L{my.localized.variable}"</js>). 552 * </ul> 553 * 554 * <ul class='seealso'> 555 * <li class='jf'>{@link RestContext#REST_maxInput} 556 * </ul> 557 */ 558 String maxInput() default ""; 559 560 /** 561 * Messages. 562 * 563 * Identifies the location of the resource bundle for this class. 564 * 565 * <ul class='notes'> 566 * <li> 567 * Supports {@doc DefaultRestSvlVariables} 568 * (e.g. <js>"$L{my.localized.variable}"</js>). 569 * </ul> 570 * 571 * <ul class='seealso'> 572 * <li class='jf'>{@link RestContext#REST_messages} 573 * </ul> 574 */ 575 String messages() default ""; 576 577 /** 578 * Configuration property: MIME types. 579 * 580 * <p> 581 * Defines MIME-type file type mappings. 582 * 583 * <ul class='notes'> 584 * <li> 585 * Supports {@doc DefaultRestSvlVariables} 586 * (e.g. <js>"$L{my.localized.variable}"</js>). 587 * </ul> 588 * 589 * <ul class='seealso'> 590 * <li class='jf'>{@link RestContext#REST_mimeTypes} 591 * </ul> 592 */ 593 String[] mimeTypes() default {}; 594 595 /** 596 * Java method parameter resolvers. 597 * 598 * <p> 599 * By default, the Juneau framework will automatically Java method parameters of various types (e.g. 600 * <c>RestRequest</c>, <c>Accept</c>, <c>Reader</c>). 601 * <br>This setting allows you to provide your own resolvers for your own class types that you want resolved. 602 * 603 * <ul class='seealso'> 604 * <li class='jf'>{@link RestContext#REST_paramResolvers} 605 * </ul> 606 */ 607 Class<? extends RestMethodParam>[] paramResolvers() default {}; 608 609 /** 610 * Parser listener. 611 * 612 * <p> 613 * Specifies the parser listener class to use for listening to non-fatal parsing errors. 614 * 615 * <ul class='seealso'> 616 * <li class='jf'>{@link Parser#PARSER_listener} 617 * </ul> 618 */ 619 Class<? extends ParserListener> parserListener() default ParserListener.Null.class; 620 621 /** 622 * Parsers. 623 * 624 * <p> 625 * If no value is specified, the parsers are inherited from parent class. 626 * <br>Otherwise, this value overrides the parsers defined on the parent class. 627 * 628 * <p> 629 * Use {@link Inherit} to inherit parsers defined on the parent class. 630 * 631 * <p> 632 * Use {@link None} to suppress inheriting parsers defined on the parent class. 633 * 634 * <ul class='seealso'> 635 * <li class='jf'>{@link RestContext#REST_parsers} 636 * </ul> 637 */ 638 Class<?>[] parsers() default {}; 639 640 /** 641 * HTTP part parser. 642 * 643 * <p> 644 * Specifies the {@link HttpPartParser} to use for parsing headers, query/form parameters, and URI parts. 645 * 646 * <ul class='seealso'> 647 * <li class='jf'>{@link RestContext#REST_partParser} 648 * </ul> 649 */ 650 Class<? extends HttpPartParser> partParser() default HttpPartParser.Null.class; 651 652 /** 653 * HTTP part serializer. 654 * 655 * <p> 656 * Specifies the {@link HttpPartSerializer} to use for serializing headers, query/form parameters, and URI parts. 657 * 658 * <ul class='seealso'> 659 * <li class='jf'>{@link RestContext#REST_partSerializer} 660 * </ul> 661 */ 662 Class<? extends HttpPartSerializer> partSerializer() default HttpPartSerializer.Null.class; 663 664 /** 665 * Resource path. 666 * 667 * <p> 668 * Used in the following situations: 669 * <ul class='spaced-list'> 670 * <li> 671 * On child resources (resource classes attached to parents via the {@link #children()} annotation) to identify 672 * the subpath used to access the child resource relative to the parent. 673 * <li> 674 * On top-level {@link RestServlet} classes deployed as Spring beans when <c>JuneauRestInitializer</c> is being used. 675 * </ul> 676 * 677 * <h5 class='topic'>On child resources</h5> 678 * <p> 679 * The typical usage is to define a path to a child resource relative to the parent resource. 680 * 681 * <h5 class='figure'>Example:</h5> 682 * <p class='bpcode'> 683 * <ja>@RestResource</ja>( 684 * children={ChildResource.<jk>class</jk>} 685 * ) 686 * <jk>public class</jk> TopLevelResource <jk>extends</jk> BasicRestServlet {...} 687 * 688 * <ja>@RestResource</ja>( 689 * path=<js>"/child"</js>, 690 * children={GrandchildResource.<jk>class</jk>} 691 * ) 692 * <jk>public class</jk> ChildResource {...} 693 * 694 * <ja>@RestResource</ja>( 695 * path=<js>"/grandchild"</js> 696 * ) 697 * <jk>public class</jk> GrandchildResource { 698 * <ja>@RestMethod</ja>( 699 * path=<js>"/"</js> 700 * ) 701 * <jk>public</jk> String sayHello() { 702 * <jk>return</jk> <js>"Hello!"</js>; 703 * } 704 * } 705 * </p> 706 * <p> 707 * In the example above, assuming the <c>TopLevelResource</c> servlet is deployed to path <c>/myContext/myServlet</c>, 708 * then the <c>sayHello</c> method is accessible through the URI <c>/myContext/myServlet/child/grandchild</c>. 709 * 710 * <p> 711 * Note that in this scenario, the <c>path</c> attribute is not defined on the top-level resource. 712 * Specifying the path on the top-level resource has no effect, but can be used for readability purposes. 713 * 714 * <h5 class='topic'>On top-level resources deployed as Spring beans</h5> 715 * <p> 716 * The path can also be used on top-level resources deployed as Spring beans when used with the <c>JuneauRestInitializer</c> 717 * Spring Boot initializer class: 718 * 719 * <h5 class='figure'>Example:</h5> 720 * <p class='bpcode'> 721 * <ja>@SpringBootApplication</ja> 722 * <ja>@Controller</ja> 723 * <jk>public class</jk> App { 724 * 725 * <jc>// Our entry-point method.</jc> 726 * <jk>public static void</jk> main(String[] args) { 727 * <jk>new</jk> SpringApplicationBuilder(App.<jk>class</jk>) 728 * .initializers(<jk>new</jk> JuneauRestInitializer(App.<jk>class</jk>)) 729 * .run(args); 730 * } 731 * 732 * <jc>// Our top-level servlet.</jc> 733 * <ja>@Bean</ja> 734 * <ja>@JuneauRestRoot</ja> 735 * <jk>public</jk> MyResource getMyResource() { 736 * <jk>return new</jk> MyResource(); 737 * } 738 * } 739 * 740 * <ja>@RestResource</ja>( 741 * path=<js>"/myResource"</js> 742 * ) 743 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {...} 744 * </p> 745 * 746 * <p> 747 * In this case, the servlet will get registered using the path defined on the resource class. 748 * 749 * <h5 class='topic'>Path variables</h5> 750 * <p> 751 * The path can contain variables that get resolved to {@link org.apache.juneau.http.annotation.Path @Path} parameters 752 * or access through the {@link RestRequest#getPathMatch()} method. 753 * 754 * <h5 class='figure'>Example:</h5> 755 * <p class='bpcode'> 756 * <ja>@RestResource</ja>( 757 * path=<js>"/myResource/{foo}/{bar}"</js> 758 * ) 759 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 760 * 761 * <ja>@RestMethod</ja>( 762 * path=<js>"/{baz}"</js> 763 * ) 764 * <jk>public void</jk> String doX(<ja>@Path</ja> String foo, <ja>@Path</ja> <jk>int</jk> bar, <ja>@Path</ja> MyPojo baz) { 765 * ... 766 * } 767 * } 768 * </p> 769 * 770 * <p> 771 * Variables can be used on either top-level or child resources and can be defined on multiple levels. 772 * 773 * <p> 774 * All variables in the path must be specified or else the target will not resolve and a <c>404</c> will result. 775 * 776 * <p> 777 * When variables are used on a path of a top-level resource deployed as a Spring bean in a Spring Boot application, 778 * the first part of the URL must be a literal which will be used as the servlet path of the registered servlet. 779 * 780 * <ul class='notes'> 781 * <li> 782 * The leading slash is optional. <js>"/myResource"</js> and <js>"myResource"</js> is equivalent. 783 * <li> 784 * The paths <js>"/myResource"</js> and <js>"/myResource/*"</js> are equivalent. 785 * <li> 786 * Paths must not end with <js>"/"</js> (per the servlet spec). 787 * </ul> 788 * 789 * <ul class='seealso'> 790 * <li class='jf'>{@link RestContext#REST_path} 791 * </ul> 792 */ 793 String path() default ""; 794 795 /** 796 * Class-level POJO swaps. 797 * 798 * <p> 799 * Shortcut to add POJO swaps to the bean contexts of all serializers and parsers on all methods in the class. 800 * 801 * <ul class='seealso'> 802 * <li class='jf'>{@link BeanContext#BEAN_pojoSwaps} 803 * </ul> 804 */ 805 Class<?>[] pojoSwaps() default {}; 806 807 /** 808 * Class-level properties. 809 * 810 * <p> 811 * Shortcut to add properties to the bean contexts of all serializers and parsers on all methods in the class. 812 * 813 * <p> 814 * Any of the properties defined on {@link RestContext} or any of the serializers and parsers can be specified. 815 * 816 * <p> 817 * Property values will be converted to the appropriate type. 818 * 819 * <ul class='notes'> 820 * <li> 821 * Supports {@doc DefaultRestSvlVariables} 822 * (e.g. <js>"$L{my.localized.variable}"</js>). 823 * </ul> 824 * 825 * <ul class='seealso'> 826 * <li class='jm'>{@link RestContextBuilder#set(String,Object)} 827 * <li class='jm'>{@link RestContextBuilder#set(java.util.Map)} 828 * </ul> 829 */ 830 Property[] properties() default {}; 831 832 /** 833 * Render response stack traces in responses. 834 * 835 * <p> 836 * Render stack traces in HTTP response bodies when errors occur. 837 * 838 * <ul class='notes'> 839 * <li> 840 * Supports {@doc DefaultRestSvlVariables} 841 * (e.g. <js>"$L{my.localized.variable}"</js>). 842 * </ul> 843 * 844 * <ul class='seealso'> 845 * <li class='jf'>{@link RestContext#REST_renderResponseStackTraces} 846 * </ul> 847 */ 848 String renderResponseStackTraces() default ""; 849 850 /** 851 * REST resource resolver. 852 * 853 * <p> 854 * The resolver used for resolving child resources. 855 * 856 * <ul class='seealso'> 857 * <li class='jf'>{@link RestContext#REST_resourceResolver} 858 * </ul> 859 */ 860 Class<? extends RestResourceResolver> resourceResolver() default RestResourceResolver.Null.class; 861 862 /** 863 * Response handlers. 864 * 865 * <p> 866 * Specifies a list of {@link ResponseHandler} classes that know how to convert POJOs returned by REST methods or 867 * set via {@link RestResponse#setOutput(Object)} into appropriate HTTP responses. 868 * 869 * <ul class='seealso'> 870 * <li class='jf'>{@link RestContext#REST_responseHandlers} 871 * </ul> 872 */ 873 Class<? extends ResponseHandler>[] responseHandlers() default {}; 874 875 /** 876 * Declared roles. 877 * 878 * <p> 879 * A comma-delimited list of all possible user roles. 880 * 881 * <p> 882 * Used in conjunction with {@link #roleGuard()} is used with patterns. 883 * 884 * <h5 class='section'>Example:</h5> 885 * <p class='bcode w800'> 886 * <ja>@RestResource</ja>( 887 * rolesDeclared=<js>"ROLE_ADMIN,ROLE_READ_WRITE,ROLE_READ_ONLY,ROLE_SPECIAL"</js>, 888 * roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js> 889 * ) 890 * <jk>public class</jk> MyResource <jk>extends</jk> RestServlet { 891 * ... 892 * } 893 * </p> 894 * 895 * <ul class='seealso'> 896 * <li class='jf'>{@link RestContext#REST_rolesDeclared} 897 * </ul> 898 */ 899 String rolesDeclared() default ""; 900 901 /** 902 * Role guard. 903 * 904 * <p> 905 * An expression defining if a user with the specified roles are allowed to access methods on this class. 906 * 907 * <h5 class='section'>Example:</h5> 908 * <p class='bcode w800'> 909 * <ja>@RestResource</ja>( 910 * path=<js>"/foo"</js>, 911 * roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js> 912 * ) 913 * <jk>public class</jk> MyResource <jk>extends</jk> RestServlet { 914 * ... 915 * } 916 * </p> 917 * 918 * <ul class='notes'> 919 * <li> 920 * Supports any of the following expression constructs: 921 * <ul> 922 * <li><js>"foo"</js> - Single arguments. 923 * <li><js>"foo,bar,baz"</js> - Multiple OR'ed arguments. 924 * <li><js>"foo | bar | baz"</js> - Multiple OR'ed arguments, pipe syntax. 925 * <li><js>"foo || bar || baz"</js> - Multiple OR'ed arguments, Java-OR syntax. 926 * <li><js>"fo*"</js> - Patterns including <js>'*'</js> and <js>'?'</js>. 927 * <li><js>"fo* & *oo"</js> - Multiple AND'ed arguments, ampersand syntax. 928 * <li><js>"fo* && *oo"</js> - Multiple AND'ed arguments, Java-AND syntax. 929 * <li><js>"fo* || (*oo || bar)"</js> - Parenthesis. 930 * </ul> 931 * <li> 932 * AND operations take precedence over OR operations (as expected). 933 * <li> 934 * Whitespace is ignored. 935 * <li> 936 * <jk>null</jk> or empty expressions always match as <jk>false</jk>. 937 * <li> 938 * If patterns are used, you must specify the list of declared roles using {@link #rolesDeclared()} or {@link RestContext#REST_rolesDeclared}. 939 * <li> 940 * Supports {@doc DefaultRestSvlVariables} 941 * (e.g. <js>"$L{my.localized.variable}"</js>). 942 * </ul> 943 * 944 * <ul class='seealso'> 945 * <li class='jf'>{@link RestContext#REST_roleGuard} 946 * </ul> 947 */ 948 String roleGuard() default ""; 949 950 /** 951 * Serializer listener. 952 * 953 * <p> 954 * Specifies the serializer listener class to use for listening to non-fatal serialization errors. 955 * 956 * <ul class='seealso'> 957 * <li class='jf'>{@link Serializer#SERIALIZER_listener} 958 * </ul> 959 */ 960 Class<? extends SerializerListener> serializerListener() default SerializerListener.Null.class; 961 962 /** 963 * Serializers. 964 * 965 * <p> 966 * If no value is specified, the serializers are inherited from parent class. 967 * <br>Otherwise, this value overrides the serializers defined on the parent class. 968 * 969 * <p> 970 * Use {@link Inherit} to inherit serializers defined on the parent class. 971 * 972 * <p> 973 * Use {@link None} to suppress inheriting serializers defined on the parent class. 974 * 975 * <ul class='seealso'> 976 * <li class='jf'>{@link RestContext#REST_serializers} 977 * </ul> 978 */ 979 Class<?>[] serializers() default {}; 980 981 /** 982 * Optional site name. 983 * 984 * <p> 985 * The site name is intended to be a title that can be applied to the entire site. 986 * 987 * <p> 988 * This value can be retrieved programmatically through the {@link RestRequest#getSiteName()} method. 989 * 990 * <p> 991 * One possible use is if you want to add the same title to the top of all pages by defining a header on a 992 * common parent class like so: 993 * <p class='bcode w800'> 994 * htmldoc=<ja>@HtmlDoc</ja>( 995 * header={ 996 * <js>"<h1>$R{siteName}</h1>"</js>, 997 * <js>"<h2>$R{resourceTitle}</h2>"</js> 998 * } 999 * ) 1000 * </p> 1001 * 1002 * <ul class='notes'> 1003 * <li> 1004 * Supports {@doc DefaultRestSvlVariables} 1005 * (e.g. <js>"$L{my.localized.variable}"</js>). 1006 * </ul> 1007 * 1008 * <ul class='seealso'> 1009 * <li class='jm'>{@link RestInfoProvider#getSiteName(RestRequest)} 1010 * </ul> 1011 */ 1012 String siteName() default ""; 1013 1014 /** 1015 * Static file response headers. 1016 * 1017 * <p> 1018 * Used to customize the headers on responses returned for statically-served files. 1019 * 1020 * <h5 class='section'>Example:</h5> 1021 * <p class='bcode w800'> 1022 * <jc>// Option #1 - Defined via annotation resolving to a config file setting with default value.</jc> 1023 * <ja>@RestResource</ja>( 1024 * staticFileResponseHeaders={ 1025 * <js>"Cache-Control: $C{REST/cacheControl,nocache}"</js>, 1026 * <js>"My-Header: $C{REST/myHeaderValue}"</js> 1027 * } 1028 * ) 1029 * <jk>public class</jk> MyResource { 1030 * 1031 * <jc>// Option #2 - Defined via builder passed in through resource constructor.</jc> 1032 * <jk>public</jk> MyResource(RestContextBuilder builder) <jk>throws</jk> Exception { 1033 * 1034 * <jc>// Using method on builder.</jc> 1035 * builder 1036 * .staticFileResponseHeader(<js>"Cache-Control"</js>, <js>"nocache"</js>); 1037 * .staticFileResponseHeaders(<js>"My-Header: foo"</js>); 1038 * 1039 * <jc>// Same, but using property.</jc> 1040 * builder 1041 * .addTo(<jsf>REST_staticFileResponseHeaders</jsf>, <js>"Cache-Control"</js>, <js>"nocache"</js>); 1042 * .addTo(<jsf>REST_staticFileResponseHeaders</jsf>, <js>"My-Header"</js>, <js>"foo"</js>); 1043 * } 1044 * 1045 * <jc>// Option #3 - Defined via builder passed in through init method.</jc> 1046 * <ja>@RestHook</ja>(<jsf>INIT</jsf>) 1047 * <jk>public void</jk> init(RestContextBuilder builder) <jk>throws</jk> Exception { 1048 * builder.staticFileResponseHeader(<js>"Cache-Control"</js>, <js>"nocache"</js>); 1049 * } 1050 * } 1051 * </p> 1052 * 1053 * <p> 1054 * Note that headers can also be specified per path-mapping via the {@link RestResource#staticFiles() @RestResource(staticFiles)} annotation. 1055 * <p class='bcode w800'> 1056 * <ja>@RestResource</ja>( 1057 * staticFiles={ 1058 * <js>"htdocs:docs:{'Cache-Control':'max-age=86400, public'}"</js> 1059 * } 1060 * ) 1061 * </p> 1062 * 1063 * <ul class='notes'> 1064 * <li> 1065 * Supports {@doc DefaultRestSvlVariables} 1066 * (e.g. <js>"$L{my.localized.variable}"</js>). 1067 * </ul> 1068 * 1069 * <ul class='seealso'> 1070 * <li class='jf'>{@link RestContext#REST_staticFileResponseHeaders} 1071 * </ul> 1072 */ 1073 String[] staticFileResponseHeaders() default {}; 1074 1075 /** 1076 * Static file mappings. 1077 * 1078 * <p> 1079 * Used to define paths and locations of statically-served files such as images or HTML documents 1080 * from the classpath or file system. 1081 * 1082 * <p> 1083 * The format of the value is one of the following: 1084 * <ol class='spaced-list'> 1085 * <li><js>"path:location"</js> 1086 * <li><js>"path:location:headers"</js> 1087 * </ol> 1088 * 1089 * <p> 1090 * An example where this class is used is in the {@link RestResource#staticFiles} annotation: 1091 * <p class='bcode w800'> 1092 * <jk>package</jk> com.foo.mypackage; 1093 * 1094 * <ja>@RestResource</ja>( 1095 * path=<js>"/myresource"</js>, 1096 * staticFiles={ 1097 * <js>"htdocs:docs"</js>, 1098 * <js>"styles:styles"</js> 1099 * } 1100 * ) 1101 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet {...} 1102 * </p> 1103 * 1104 * <p> 1105 * In the example above, given a GET request to the following URL... 1106 * <p class='bcode w800'> 1107 * /myresource/htdocs/foobar.html 1108 * </p> 1109 * <br>...the servlet will attempt to find the <c>foobar.html</c> file in the following location: 1110 * <ol class='spaced-list'> 1111 * <li><c>com.foo.mypackage.docs</c> package. 1112 * </ol> 1113 * 1114 * <p> 1115 * The location is interpreted as an absolute path if it starts with <js>'/'</js>. 1116 * <p class='bcode w800'> 1117 * <ja>@RestResource</ja>( 1118 * staticFiles={ 1119 * <js>"htdocs:/docs"</js> 1120 * } 1121 * ) 1122 * </p> 1123 * <p> 1124 * In the example above, given a GET request to the following URL... 1125 * <p class='bcode w800'> 1126 * /myresource/htdocs/foobar.html 1127 * </p> 1128 * <br>...the servlet will attempt to find the <c>foobar.html</c> file in the following location: 1129 * <ol class='spaced-list'> 1130 * <li><c>docs</c> package (typically under <c>src/main/resources/docs</c> in your workspace). 1131 * <li><c>[working-dir]/docs</c> directory at runtime. 1132 * </ol> 1133 * 1134 * <p> 1135 * Response headers can be specified for served files by adding a 3rd section that consists of a {@doc SimpleJson} object. 1136 * <p class='bcode w800'> 1137 * <ja>@RestResource</ja>( 1138 * staticFiles={ 1139 * <js>"htdocs:docs:{'Cache-Control':'max-age=86400, public'}"</js> 1140 * } 1141 * ) 1142 * </p> 1143 * 1144 * <p> 1145 * The same path can map to multiple locations. Files are searched in the order 1146 * <p class='bcode w800'> 1147 * <ja>@RestResource</ja>( 1148 * staticFiles={ 1149 * <jc>// Search in absolute location '/htdocs/folder' before location 'htdocs.package' relative to servlet package.</jc> 1150 * <js>"htdocs:/htdocs/folder,htdocs:htdocs.package"</js> 1151 * } 1152 * ) 1153 * </p> 1154 * 1155 * <ul class='notes'> 1156 * <li> 1157 * Mappings are cumulative from super classes. 1158 * <li> 1159 * Child resources can override mappings made on parent class resources. 1160 * <br>When both parent and child resources map against the same path, files will be search in the child location 1161 * and then the parent location. 1162 * <li> 1163 * Supports {@doc DefaultRestSvlVariables} 1164 * (e.g. <js>"$L{my.localized.variable}"</js>). 1165 * </ul> 1166 * 1167 * <ul class='seealso'> 1168 * <li class='jf'>{@link RestContext#REST_staticFiles} 1169 * </ul> 1170 */ 1171 String[] staticFiles() default {}; 1172 1173 /** 1174 * Supported accept media types. 1175 * 1176 * <p> 1177 * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource. 1178 * 1179 * <ul class='notes'> 1180 * <li> 1181 * Supports {@doc DefaultRestSvlVariables} 1182 * (e.g. <js>"$L{my.localized.variable}"</js>). 1183 * </ul> 1184 * 1185 * <ul class='seealso'> 1186 * <li class='jf'>{@link RestContext#REST_produces} 1187 * </ul> 1188 */ 1189 String[] produces() default {}; 1190 1191 /** 1192 * Supported content media types. 1193 * 1194 * <p> 1195 * Overrides the media types inferred from the parsers that identify what media types can be consumed by the resource. 1196 * 1197 * <ul class='notes'> 1198 * <li> 1199 * Supports {@doc DefaultRestSvlVariables} 1200 * (e.g. <js>"$L{my.localized.variable}"</js>). 1201 * </ul> 1202 * 1203 * <ul class='seealso'> 1204 * <li class='jf'>{@link RestContext#REST_consumes} 1205 * </ul> 1206 */ 1207 String[] consumes() default {}; 1208 1209 /** 1210 * Provides swagger-specific metadata on this resource. 1211 * 1212 * <p> 1213 * Used to populate the auto-generated OPTIONS swagger documentation. 1214 * 1215 * <h5 class='section'>Example:</h5> 1216 * <p class='bcode w800'> 1217 * <ja>@RestResource</ja>( 1218 * path=<js>"/addressBook"</js>, 1219 * 1220 * <jc>// Swagger info.</jc> 1221 * swagger=@ResourceSwagger({ 1222 * <js>"contact:{name:'John Smith',email:'john@smith.com'},"</js>, 1223 * <js>"license:{name:'Apache 2.0',url:'http://www.apache.org/licenses/LICENSE-2.0.html'},"</js>, 1224 * <js>"version:'2.0',</js>, 1225 * <js>"termsOfService:'You are on your own.',"</js>, 1226 * <js>"tags:[{name:'Java',description:'Java utility',externalDocs:{description:'Home page',url:'http://juneau.apache.org'}}],"</js>, 1227 * <js>"externalDocs:{description:'Home page',url:'http://juneau.apache.org'}"</js> 1228 * }) 1229 * ) 1230 * </p> 1231 * 1232 * <ul class='seealso'> 1233 * <li class='ja'>{@link ResourceSwagger} 1234 * <li class='jm'>{@link RestInfoProvider#getSwagger(RestRequest)} 1235 * </ul> 1236 */ 1237 ResourceSwagger swagger() default @ResourceSwagger; 1238 1239 /** 1240 * Optional servlet title. 1241 * 1242 * <p> 1243 * It is used to populate the Swagger title field. 1244 * <br>This value can be retrieved programmatically through the {@link RestRequest#getResourceTitle()} method. 1245 * 1246 * <ul class='notes'> 1247 * <li> 1248 * Supports {@doc DefaultRestSvlVariables} 1249 * (e.g. <js>"$L{my.localized.variable}"</js>). 1250 * <li> 1251 * Corresponds to the swagger field <c>/info/title</c>. 1252 * </ul> 1253 * 1254 * <ul class='seealso'> 1255 * <li class='jm'>{@link RestInfoProvider#getTitle(RestRequest)} 1256 * </ul> 1257 */ 1258 String[] title() default {}; 1259 1260 /** 1261 * Resource authority path. 1262 * 1263 * <p> 1264 * Overrides the authority path value for this resource and any child resources. 1265 * 1266 * <ul class='notes'> 1267 * <li> 1268 * Supports {@doc DefaultRestSvlVariables} 1269 * (e.g. <js>"$L{my.localized.variable}"</js>). 1270 * </ul> 1271 * 1272 * <ul class='seealso'> 1273 * <li class='jf'>{@link RestContext#REST_uriAuthority} 1274 * </ul> 1275 */ 1276 String uriAuthority() default ""; 1277 1278 /** 1279 * Resource context path. 1280 * 1281 * <p> 1282 * Overrides the context path value for this resource and any child resources. 1283 * 1284 * <ul class='notes'> 1285 * <li> 1286 * Supports {@doc DefaultRestSvlVariables} 1287 * (e.g. <js>"$L{my.localized.variable}"</js>). 1288 * </ul> 1289 * 1290 * <ul class='seealso'> 1291 * <li class='jf'>{@link RestContext#REST_uriContext} 1292 * </ul> 1293 */ 1294 String uriContext() default ""; 1295 1296 /** 1297 * URI-resolution relativity. 1298 * 1299 * <p> 1300 * Specifies how relative URIs should be interpreted by serializers. 1301 * 1302 * <p> 1303 * See {@link UriResolution} for possible values. 1304 * 1305 * <ul class='notes'> 1306 * <li> 1307 * Supports {@doc DefaultRestSvlVariables} 1308 * (e.g. <js>"$L{my.localized.variable}"</js>). 1309 * </ul> 1310 * 1311 * <ul class='seealso'> 1312 * <li class='jf'>{@link RestContext#REST_uriRelativity} 1313 * </ul> 1314 */ 1315 String uriRelativity() default ""; 1316 1317 /** 1318 * URI-resolution. 1319 * 1320 * <p> 1321 * Specifies how relative URIs should be interpreted by serializers. 1322 * 1323 * <p> 1324 * See {@link UriResolution} for possible values. 1325 * 1326 * <ul class='notes'> 1327 * <li> 1328 * Supports {@doc DefaultRestSvlVariables} 1329 * (e.g. <js>"$L{my.localized.variable}"</js>). 1330 * </ul> 1331 * 1332 * <ul class='seealso'> 1333 * <li class='jf'>{@link RestContext#REST_uriResolution} 1334 * </ul> 1335 */ 1336 String uriResolution() default ""; 1337 1338 /** 1339 * Configuration property: Use classpath resource caching. 1340 * 1341 * <p> 1342 * When enabled, resources retrieved via {@link RestRequest#getClasspathReaderResource(String, boolean)} (and related 1343 * methods) will be cached in memory to speed subsequent lookups. 1344 * 1345 * <ul class='notes'> 1346 * <li> 1347 * Supports {@doc DefaultRestSvlVariables} 1348 * (e.g. <js>"$L{my.localized.variable}"</js>). 1349 * </ul> 1350 * 1351 * <ul class='seealso'> 1352 * <li class='jf'>{@link RestContext#REST_useClasspathResourceCaching} 1353 * </ul> 1354 */ 1355 String useClasspathResourceCaching() default ""; 1356 1357 /** 1358 * Use stack trace hashes. 1359 * 1360 * <p> 1361 * When enabled, the number of times an exception has occurred will be determined based on stack trace hashsums, 1362 * made available through the {@link RestException#getOccurrence()} method. 1363 * 1364 * <ul class='notes'> 1365 * <li> 1366 * Supports {@doc DefaultRestSvlVariables} 1367 * (e.g. <js>"$L{my.localized.variable}"</js>). 1368 * </ul> 1369 * 1370 * <ul class='seealso'> 1371 * <li class='jf'>{@link RestContext#REST_useStackTraceHashes} 1372 * </ul> 1373 */ 1374 String useStackTraceHashes() default ""; 1375 1376 /** 1377 * Enable debug mode. 1378 * 1379 * <p> 1380 * Enables the following: 1381 * <ul class='spaced-list'> 1382 * <li> 1383 * HTTP request/response bodies are cached in memory for logging purposes. 1384 * </ul> 1385 * 1386 * <p> 1387 * Possible values (case insensitive): 1388 * <ul> 1389 * <li><js>"true"</js> - Debug is enabled for all requests. 1390 * <li><js>"false"</js> - Debug is disabled for all requests. 1391 * <li><js>"per-request"</js> - Debug is enabled only for requests that have a <c class='snippet'>X-Debug: true</c> header. 1392 * </ul> 1393 * 1394 * <ul class='notes'> 1395 * <li> 1396 * Supports {@doc DefaultRestSvlVariables} 1397 * (e.g. <js>"$L{my.localized.variable}"</js>). 1398 * </ul> 1399 * 1400 * <ul class='seealso'> 1401 * <li class='jf'>{@link RestContext#REST_debug} 1402 * </ul> 1403 */ 1404 String debug() default ""; 1405}