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.http.annotation; 014 015import static java.lang.annotation.ElementType.*; 016import static java.lang.annotation.RetentionPolicy.*; 017 018import java.lang.annotation.*; 019 020import org.apache.juneau.jsonschema.annotation.Schema; 021import org.apache.juneau.*; 022import org.apache.juneau.annotation.*; 023import org.apache.juneau.httppart.*; 024import org.apache.juneau.json.*; 025import org.apache.juneau.jsonschema.*; 026 027/** 028 * REST request body annotation. 029 * 030 * <p> 031 * Identifies a POJO to be used as the body of an HTTP request. 032 * 033 * <p> 034 * Can be used in the following locations: 035 * <ul> 036 * <li>Arguments and argument-types of server-side <ja>@RestMethod</ja>-annotated methods. 037 * <li>Arguments and argument-types of client-side <ja>@RemoteMethod</ja>-annotated interfaces. 038 * <li>Methods and return types of server-side and client-side <ja>@Request</ja>-annotated interfaces. 039 * </ul> 040 * 041 * <h5 class='topic'>Arguments and argument-types of server-side @RestMethod-annotated methods</h5> 042 * 043 * <p> 044 * On server-side REST, this annotation can be applied to method parameters or parameter classes to identify them as the body of an HTTP request. 045 * 046 * <h5 class='section'>Examples:</h5> 047 * <p class='bcode w800'> 048 * <jc>// Used on parameter</jc> 049 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>) 050 * <jk>public void</jk> addPet(<ja>@Body</ja> Pet pet) {...} 051 * </p> 052 * <p class='bcode w800'> 053 * <jc>// Used on class</jc> 054 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>) 055 * <jk>public void</jk> addPet(Pet pet) {...} 056 * 057 * <ja>@Body</ja> 058 * <jk>public class</jk> Pet {...} 059 * </p> 060 * 061 * <p> 062 * This is functionally equivalent to the following code... 063 * <p class='bcode w800'> 064 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>) 065 * <jk>public void</jk> addPet(RestRequest req) { 066 * Pet pet = req.getBody().asType(Pet.<jk>class</jk>); 067 * ... 068 * } 069 * </p> 070 * 071 * <p> 072 * Also used to populate the auto-generated Swagger documentation. 073 * 074 * <h5 class='section'>Examples:</h5> 075 * <p class='bcode w800'> 076 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>) 077 * <jk>public void</jk> addPet(Pet pet) {...} 078 * 079 * <ja>@Body</ja>( 080 * description=<js>"Pet object to add to the store"</js>, 081 * required=<jk>true</jk>, 082 * example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 083 * ) 084 * <jk>public class</jk> Pet {...} 085 * </p> 086 * 087 * <p> 088 * Swagger documentation values are coalesced from multiple sources in the following order of precedence: 089 * <ol> 090 * <li><ja>@Body</ja> annotation on parameter. 091 * <li><ja>@Body</ja> annotation on parameter class. 092 * <li><ja>@Body</ja> annotation on parent classes and interfaces. 093 * <li><ja>@MethodSwagger(value)</ja> annotation. 094 * <li>Localized resource bundle property <js>"[method-name].produces"</js>. 095 * <li><ja>@ResourceSwagger(value)</ja> annotation. 096 * <li>Localized classpath resource file <js>"[enclosing-class].[simple-class-name]_[locale].json"</js> (if it's an inner or member class). 097 * <li>Default classpath resource file <js>"[enclosing-class].[simple-class-name].json"</js> (if it's an inner or member class). 098 * <li>Localized classpath resource file <js>"[simple-class-name]_[locale].json"</js>. 099 * <li>Default classpath resource file <js>"[simple-class-name].json"</js>. 100 * </ol> 101 * 102 * <ul class='seealso'> 103 * <li class='link'>{@doc RestBodyAnnotation} 104 * <li class='link'>{@doc RestSwagger} 105 * <li class='extlink'>{@doc ExtSwaggerParameterObject} 106 * </ul> 107 * 108 * <h5 class='topic'>Arguments and argument-types of client-side @RemoteResource-annotated interfaces</h5> 109 * 110 * <ul class='seealso'> 111 * <li class='link'>{@doc RestcBody} 112 * </ul> 113 * 114 * <h5 class='topic'>Methods and return types of server-side and client-side @Request-annotated interfaces</h5> 115 * 116 * <ul class='seealso'> 117 * <li class='link'>{@doc RestRequestAnnotation} 118 * <li class='link'>{@doc RestcRequest} 119 * </ul> 120 * 121 * <div class='warn'> 122 * If using this annotation on a Spring bean, note that you are likely to encounter issues when using on parameterized 123 * types such as <code>List<MyBean></code>. This is due to the fact that Spring uses CGLIB to recompile classes 124 * at runtime, and CGLIB was written before generics were introduced into Java and is a virtually-unsupported library. 125 * Therefore, parameterized types will often be stripped from class definitions and replaced with unparameterized types 126 * (e.g. <code>List</code>). Under these circumstances, you are likely to get <code>ClassCastExceptions</code> 127 * when trying to access generalized <code>OMaps</code> as beans. The best solution to this issue is to either 128 * specify the parameter as a bean array (e.g. <code>MyBean[]</code>) or declare the method as final so that CGLIB 129 * will not try to recompile it. 130 * </div> 131 */ 132@Documented 133@Target({PARAMETER,FIELD,METHOD,TYPE}) 134@Retention(RUNTIME) 135@Inherited 136public @interface Body { 137 138 //================================================================================================================= 139 // Attributes common to all Swagger Parameter objects 140 //================================================================================================================= 141 142 /** 143 * <mk>description</mk> field of the {@doc ExtSwaggerParameterObject}. 144 * 145 * <p> 146 * A brief description of the body. This could contain examples of use. 147 * 148 * <h5 class='section'>Examples:</h5> 149 * <p class='bcode w800'> 150 * <jc>// Used on parameter</jc> 151 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 152 * <jk>public void</jk> addPet( 153 * <ja>@Body</ja>(description=<js>"Pet object to add to the store"</js>) Pet input 154 * ) {...} 155 * </p> 156 * <p class='bcode w800'> 157 * <jc>// Used on class</jc> 158 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 159 * <jk>public void</jk> addPet(Pet input) {...} 160 * 161 * <ja>@Body</ja>(description=<js>"Pet object to add to the store"</js>) 162 * <jk>public class</jk> Pet {...} 163 * </p> 164 * 165 * <h5 class='section'>Used for:</h5> 166 * <ul class='spaced-list'> 167 * <li> 168 * Server-side generated Swagger documentation. 169 * </ul> 170 * 171 * <ul class='notes'> 172 * <li> 173 * The format is plain text. 174 * <br>Multiple lines are concatenated with newlines. 175 * <li> 176 * Supports {@doc RestSvlVariables} 177 * (e.g. <js>"$L{my.localized.variable}"</js>). 178 * </ul> 179 */ 180 String[] description() default {}; 181 182 /** 183 * Synonym for {@link #description()}. 184 */ 185 String[] d() default {}; 186 187 /** 188 * <mk>required</mk> field of the {@doc ExtSwaggerParameterObject}. 189 * 190 * <p> 191 * Determines whether the body is mandatory. 192 * 193 * <p> 194 * If validation fails during serialization or parsing, the part serializer/parser will throw a {@link SchemaValidationException}. 195 * <br>On the client-side, this gets converted to a <c>RestCallException</c> which is thrown before the connection is made. 196 * <br>On the server-side, this gets converted to a <c>BadRequest</c> (400). 197 * 198 * <h5 class='section'>Examples:</h5> 199 * <p class='bcode w800'> 200 * <jc>// Used on parameter</jc> 201 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 202 * <jk>public void</jk> addPet( 203 * <ja>@Body</ja>(required=<jk>true</jk>) Pet input 204 * ) {...} 205 * </p> 206 * <p class='bcode w800'> 207 * <jc>// Used on class</jc> 208 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 209 * <jk>public void</jk> addPet(Pet input) {...} 210 * 211 * <ja>@Body</ja>(required=<jk>true</jk>) 212 * <jk>public class</jk> Pet {...} 213 * </p> 214 * 215 * <h5 class='section'>Used for:</h5> 216 * <ul class='spaced-list'> 217 * <li> 218 * Server-side schema-based parsing validation. 219 * <li> 220 * Server-side generated Swagger documentation. 221 * <li> 222 * Client-side schema-based serializing validation. 223 * </ul> 224 * 225 * <ul class='notes'> 226 * <li> 227 * Supports {@doc RestSvlVariables} 228 * (e.g. <js>"$L{my.localized.variable}"</js>). 229 * </ul> 230 */ 231 boolean required() default false; 232 233 /** 234 * Synonym for {@link #required()}. 235 */ 236 boolean r() default false; 237 238 //================================================================================================================= 239 // Attributes specific to in=body 240 //================================================================================================================= 241 242 /** 243 * <mk>schema</mk> field of the {@doc ExtSwaggerParameterObject}. 244 * 245 * <p> 246 * The schema defining the type used for the body parameter. 247 * 248 * <p> 249 * This is a required attribute per the swagger definition. 250 * However, if not explicitly specified, the value will be auto-generated using {@link JsonSchemaSerializer}. 251 * 252 * <h5 class='section'>Used for:</h5> 253 * <ul class='spaced-list'> 254 * <li> 255 * Server-side schema-based parsing and parsing validation. 256 * <li> 257 * Server-side generated Swagger documentation. 258 * <li> 259 * Client-side schema-based serializing and serializing validation. 260 * </ul> 261 * 262 * <ul class='notes'> 263 * <li> 264 * Supports {@doc RestSvlVariables} 265 * (e.g. <js>"$L{my.localized.variable}"</js>). 266 * </ul> 267 */ 268 Schema schema() default @Schema; 269 270 //================================================================================================================= 271 // Other 272 //================================================================================================================= 273 274 /** 275 * A serialized example of the body of a request. 276 * 277 * <p> 278 * This is the {@doc SimplifiedJson} of an example of the body. 279 * 280 * <p> 281 * This value is converted to a POJO and then serialized to all the registered serializers on the REST method to produce examples for all 282 * supported language types. 283 * <br>These values are then used to automatically populate the {@link #examples} field. 284 * 285 * <h5 class='section'>Example:</h5> 286 * <p class='bcode w800'> 287 * <jc>// A JSON representation of a PetCreate object.</jc> 288 * <ja>@Body</ja>( 289 * example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 290 * ) 291 * </p> 292 * <p> 293 * <img class='bordered' src='doc-files/Body_Example.png' style='width:860px'> 294 * 295 * <p> 296 * There are several other options for defining this example: 297 * <ul class='spaced-list'> 298 * <li> 299 * Defining an <js>"x-example"</js> field in the inherited Swagger JSON body field (classpath file or <code><ja>@ResourceSwagger</ja>(value)</code>/<code><ja>@MethodSwagger</ja>(value)</code>). 300 * <li> 301 * Defining an <js>"x-example"</js> field in the Swagger Schema Object for the body (including referenced <js>"$ref"</js> schemas). 302 * <li> 303 * Allowing Juneau to auto-generate a code example. 304 * </ul> 305 * 306 * <p> 307 * The latter is important because Juneau also supports auto-generation of JSON-Schema from POJO classes using {@link JsonSchemaSerializer} which has several of it's own 308 * options for auto-detecting and calculation POJO examples. 309 * 310 * <p> 311 * In particular, examples can be defined via static methods, fields, and annotations on the classes themselves. 312 * 313 * <p class='bcode w800'> 314 * <jc>// Annotation on class.</jc> 315 * <ja>@Example</ja>(<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>) 316 * <jk>public class</jk> PetCreate { 317 * ... 318 * } 319 * </p> 320 * <p class='bcode w800'> 321 * <jc>// Annotation on static method.</jc> 322 * <jk>public class</jk> PetCreate { 323 * 324 * <ja>@Example</ja> 325 * <jk>public static</jk> PetCreate <jsm>sample</jsm>() { 326 * <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>}); 327 * } 328 * } 329 * </p> 330 * <p class='bcode w800'> 331 * <jc>// Static method with specific name 'example'.</jc> 332 * <jk>public class</jk> PetCreate { 333 * 334 * <jk>public static</jk> PetCreate <jsm>example</jsm>() { 335 * <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>}); 336 * } 337 * } 338 * </p> 339 * <p class='bcode w800'> 340 * <jc>// Static field.</jc> 341 * <jk>public class</jk> PetCreate { 342 * 343 * <ja>@Example</ja> 344 * <jk>public static</jk> PetCreate <jsf>EXAMPLE</jsf> = <jk>new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>}); 345 * } 346 * </p> 347 * 348 * <p> 349 * Examples can also be specified via generic properties as well using the {@link BeanContext#BEAN_examples} property at either the class or method level. 350 * <p class='bcode w800'> 351 * <jc>// Examples defined at class level.</jc> 352 * <ja>@Rest</ja>( 353 * properties={ 354 * <ja>@Property</ja>( 355 * name=<jsf>BEAN_examples</jsf>, 356 * value=<js>"{'org.apache.juneau.examples.rest.petstore.PetCreate': {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}}"</js> 357 * ) 358 * } 359 * ) 360 * </p> 361 * 362 * <h5 class='section'>Used for:</h5> 363 * <ul class='spaced-list'> 364 * <li> 365 * Server-side generated Swagger documentation. 366 * </ul> 367 * 368 * <ul class='seealso'> 369 * <li class='ja'>{@link Example} 370 * <li class='jc'>{@link BeanContext} 371 * <ul> 372 * <li class='jf'>{@link BeanContext#BEAN_examples BEAN_examples} 373 * </ul> 374 * <li class='jc'>{@link JsonSchemaSerializer} 375 * <ul> 376 * <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_addExamplesTo JSONSCHEMA_addExamplesTo} 377 * <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_allowNestedExamples JSONSCHEMA_allowNestedExamples} 378 * </ul> 379 * </ul> 380 * 381 * <ul class='notes'> 382 * <li> 383 * The format is any {@doc SimplifiedJson} if the object can be converted to a POJO using {@link JsonParser#DEFAULT} or a simple String if the object 384 * has a schema associated with it meancan be converted from a String. 385 * <br>Multiple lines are concatenated with newlines. 386 * <li> 387 * The format of this object can also be a simple String if the body has a schema associated with it, meaning it's meant to be treated as an HTTP part. 388 * <li> 389 * Supports {@doc RestSvlVariables} 390 * (e.g. <js>"$L{my.localized.variable}"</js>). 391 * </ul> 392 */ 393 String[] example() default {}; 394 395 /** 396 * Synonym for {@link #example()}. 397 */ 398 String[] ex() default {}; 399 400 /** 401 * Serialized examples of the body of a request. 402 * 403 * <p> 404 * This is a {@doc SimplifiedJson} object whose keys are media types and values are string representations of that value. 405 * 406 * <p> 407 * In general you won't need to populate this value directly since it will automatically be calculated based on the value provided in the {@link #example()} field. 408 * <br>However, this field allows you to override the behavior and show examples for only specified media types or different examples for different media types. 409 * 410 * <p class='bcode w800'> 411 * <jc>// A JSON representation of a PetCreate object.</jc> 412 * <ja>@Body</ja>( 413 * examples={ 414 * <js>"'application/json':'{name:\\'Doggie\\',species:\\'Dog\\'}',"</js>, 415 * <js>"'text/uon':'(name:Doggie,species=Dog)'"</js> 416 * } 417 * ) 418 * </p> 419 * 420 * <h5 class='section'>Used for:</h5> 421 * <ul class='spaced-list'> 422 * <li> 423 * Server-side generated Swagger documentation. 424 * </ul> 425 * 426 * <ul class='notes'> 427 * <li> 428 * The format is a {@doc SimplifiedJson} object with string keys (media type) and string values (example for that media type) . 429 * <li> 430 * The leading/trailing <c>{ }</c> characters are optional. 431 * <li> 432 * Multiple lines are concatenated with newlines so that you can format the value to be readable: 433 * <li> 434 * Supports {@doc RestSvlVariables} 435 * (e.g. <js>"$L{my.localized.variable}"</js>). 436 * <li> 437 * Resolution of variables is delayed until request time and occurs before parsing. 438 * <br>This allows you to, for example, pull in a JSON construct from a properties file based on the locale of the HTTP request. 439 * </ul> 440 */ 441 String[] examples() default {}; 442 443 /** 444 * Synonym for {@link #examples()}. 445 */ 446 String[] exs() default {}; 447 448 /** 449 * Free-form value for the {@doc ExtSwaggerParameterObject}. 450 * 451 * <p> 452 * This is a {@doc SimplifiedJson} object that makes up the swagger information for this parameter-info. 453 * 454 * <p> 455 * The following are completely equivalent ways of defining the swagger description of the body: 456 * <p class='bcode w800'> 457 * <jc>// Normal</jc> 458 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 459 * <jk>public void</jk> addPet( 460 * <ja>@Body</ja>( 461 * description=<js>"Pet object to add to the store"</js>, 462 * required=<jk>true</jk>, 463 * example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 464 * ) Pet input 465 * ) {...} 466 * </p> 467 * <p class='bcode w800'> 468 * <jc>// Free-form</jc> 469 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 470 * <jk>public void</jk> addPet( 471 * <ja>@Body</ja>({ 472 * <js>"description: 'Pet object to add to the store',"</js>, 473 * <js>"required: true,"</js>, 474 * <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 475 * }) Pet input 476 * ) {...} 477 * </p> 478 * <p class='bcode w800'> 479 * <jc>// Free-form with variables</jc> 480 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 481 * <jk>public void</jk> addPet( 482 * <ja>@Body</ja>(<js>"$L{petObjectSwagger}"</js>) Pet input 483 * ) {...} 484 * </p> 485 * <p class='bcode w800'> 486 * <mc>// Contents of MyResource.properties</mc> 487 * <mk>petObjectSwagger</mk> = <mv>{ description: "Pet object to add to the store", required: true, example: {name:"Doggie",price:9.99,species:"Dog",tags:["friendly","cute"]} }</mv> 488 * </p> 489 * 490 * <p> 491 * The reasons why you may want to use this field include: 492 * <ul> 493 * <li>You want to pull in the entire Swagger JSON definition for this body from an external source such as a properties file. 494 * <li>You want to add extra fields to the Swagger documentation that are not officially part of the Swagger specification. 495 * </ul> 496 * 497 * <h5 class='section'>Used for:</h5> 498 * <ul class='spaced-list'> 499 * <li> 500 * Server-side generated Swagger documentation. 501 * </ul> 502 * 503 * <ul class='notes'> 504 * <li> 505 * The format is a {@doc SimplifiedJson} object. 506 * <li> 507 * Schema-based serialization is NOT affected by values defined in this annotation. 508 * <br>It only affects the generated Swagger documentation. 509 * <li> 510 * The leading/trailing <c>{ }</c> characters are optional. 511 * <br>The following two example are considered equivalent: 512 * <p class='bcode w800'> 513 * <ja>@Body</ja>(<js>"{description: 'Pet object to add to the store'}"</js>) 514 * </p> 515 * <p class='bcode w800'> 516 * <ja>@Body</ja>(<js>"description: 'Pet object to add to the store'"</js>) 517 * </p> 518 * <li> 519 * Multiple lines are concatenated with newlines so that you can format the value to be readable. 520 * <li> 521 * Supports {@doc RestSvlVariables} 522 * (e.g. <js>"$L{my.localized.variable}"</js>). 523 * <li> 524 * Values defined in this field supersede values pulled from the Swagger JSON file and are superseded by individual values defined on this annotation. 525 * </ul> 526 */ 527 String[] value() default {}; 528 529 /** 530 * Equivalent to {@link #value()}. 531 * 532 * <p> 533 * The following are entirely equivalent: 534 * 535 * <p class='bcode w800'> 536 * <ja>@Body</ja>({ 537 * <js>"description: 'Pet object to add to the store',"</js>, 538 * <js>"required: true,"</js>, 539 * <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 540 * }) 541 * </p> 542 * <p class='bcode w800'> 543 * <ja>@Body</ja>(api={ 544 * <js>"description: 'Pet object to add to the store',"</js>, 545 * <js>"required: true,"</js>, 546 * <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 547 * }) 548 * </p> 549 * 550 * <h5 class='section'>Used for:</h5> 551 * <ul class='spaced-list'> 552 * <li> 553 * Server-side generated Swagger documentation. 554 * </ul> 555 * 556 * <ul class='notes'> 557 * <li> 558 * If you specify both {@link #value()} and {@link #api()}, {@link #value()} will be ignored. 559 * </ul> 560 */ 561 String[] api() default {}; 562}