| <!-- |
| /*************************************************************************************************************************** |
| * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations under the License. |
| ***************************************************************************************************************************/ |
| --> |
| |
| @Response |
| |
| <p> |
| The {@link oaj.http.annotation.Response @Response} annotation is used to identify schema information about an HTTP response. |
| </p> |
| <ul class='javatree'> |
| <li class='ja'>{@link oaj.http.annotation.Response} |
| <ul> |
| <li class='jf'>{@link oaj.http.annotation.Response#api() api} - Free-form Swagger JSON. |
| <li class='jf'>{@link oaj.http.annotation.Response#code() code} - HTTP status code. |
| <li class='jf'>{@link oaj.http.annotation.Response#description() description} - Description. |
| <li class='jf'>{@link oaj.http.annotation.Response#example() example} - Serialized example. |
| <li class='jf'>{@link oaj.http.annotation.Response#examples() examples} - Serialized examples per media type. |
| <li class='jf'>{@link oaj.http.annotation.Response#headers() headers} - Swagger about headers added to response. |
| <li class='jf'>{@link oaj.http.annotation.Response#partSerializer() partSerializer} - Override the part serializer. |
| <li class='jf'>{@link oaj.http.annotation.Response#schema() schema} - Swagger schema. |
| <li class='jf'>{@link oaj.http.annotation.Response#value() value} - Free-form Swagger JSON. |
| </ul> |
| </ul> |
| <p> |
| It can be used in the following locations: |
| </p> |
| <ul> |
| <li>Exception classes thrown from <ja>@RestMethod</ja>-annotated methods. |
| <li>Return type classes of <ja>@RestMethod</ja>-annotated methods. |
| <li><ja>@RestMethod</ja>-annotated methods themselves. |
| <li>Arguments and argument-types of <ja>@RestMethod</ja>-annotated methods. |
| </ul> |
| |
| <p> |
| When the <ja>@Response</ja> annotation is applied to classes, the following annotations can be used on |
| public non-static methods of the class to identify parts of a response: |
| </p> |
| <ul class='javatree'> |
| <li class='ja'>{@link oaj.http.annotation.ResponseStatus} |
| <li class='ja'>{@link oaj.http.annotation.ResponseHeader} |
| <li class='ja'>{@link oaj.http.annotation.ResponseBody} |
| </ul> |
| |
| <h5 class='topic'>@Resource on exception classes</h5> |
| <p> |
| When applied to an exception class, this annotation defines Swagger schema and information on non-200 return types. |
| </p> |
| <p> |
| The following example shows the <ja>@Response</ja> annotation used to define an exception for an invalid login attempt: |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Our annotated exception.</jc> |
| <ja>@Response</ja>( |
| code=401, |
| description=<js>"Invalid username or password provided"</js> <jc>// Description show in Swagger</jc> |
| ) |
| <jk>public class</jk> InvalidLogin <jk>extends</jk> Exception { |
| <jk>public</jk> InvalidLogin() { |
| <jk>super</jk>(<js>"Invalid username or password."</js>); <jc>// Message sent in response</jc> |
| } |
| } |
| |
| <jc>// Our REST method that throws an annotated exception.</jc> |
| <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/user/login"</js>) |
| <jk>public</jk> Ok login( |
| <ja>@FormData</ja>(<js>"username"</js>) String username, |
| <ja>@FormData</ja>(<js>"password"</js>) String password |
| ) <jk>throws</jk> InvalidLogin |
| { |
| checkCredentials(username, password); |
| <jk>return new</jk> Ok(); |
| } |
| </p> |
| <p> |
| Custom exceptions can also extend from one of the predefined HTTP exceptions such as the {@link oajr.exception.Unauthorized} exception: |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Our annotated exception.</jc> |
| <ja>@Response</ja>( |
| description=<js>"Invalid username or password provided"</js> <jc>// Overridden from parent class</jc> |
| ) |
| <jk>public class</jk> InvalidLogin <jk>extends</jk> Unauthorized { |
| <jk>public</jk> InvalidLogin() { |
| <jk>super</jk>(<js>"Invalid username or password."</js>); |
| } |
| } |
| |
| <jc>// Parent predefined exception class.</jc> |
| <ja>@Response</ja>( |
| code=401, |
| description=<js>"Unauthorized"</js> |
| ) |
| <jk>public class</jk> Unauthorized <jk>extends</jk> RestException {...} |
| </p> |
| |
| <h5 class='topic'>@Resource on return type classes</h5> |
| <p> |
| When applied type classes returned by a Java method, this annotation defines schema and Swagger information on the body of responses. |
| </p> |
| <p> |
| In the example above, we're using the <c>Ok</c> class which is defined like so: |
| </p> |
| <p class='bpcode w800'> |
| <ja>@Response</ja>( |
| code=200, |
| description=<js>"OK"</js> |
| ) |
| <jk>public class</jk> Ok { |
| |
| <ja>@ResponseBody</ja> |
| <jk>public</jk> String toString() { |
| <jk>return</jk> <js>"OK"</js>; |
| } |
| } |
| </p> |
| <p> |
| Another example showing how a redirect can be defined: |
| </p> |
| <p class='bpcode w800'> |
| <ja>@Response</ja>( |
| code=307, |
| description=<js>"Temporary Redirect"</js> |
| ) |
| <jk>public class</jk> Redirect { |
| <jk>private final</jk> URI <jf>location</jf>; |
| |
| <jk>public</jk> Redirect(URI location) { |
| <jk>this</jk>.<jf>location</jf> = location; |
| } |
| |
| <ja>@ResponseHeader</ja>( |
| name=<js>"Location"</js>, |
| format=<js>"uri"</js> |
| ) |
| <jk>public</jk> URI getLocation() { |
| <jk>return</jk> location; |
| } |
| |
| <ja>@ResponseBody</ja> |
| <jk>public</jk> String toString() { |
| <jk>return</jk> <js>"Temporary Redirect"</js>; |
| } |
| } |
| </p> |
| <p class='bpcode w800'> |
| <jc>// Usage</jc> |
| <ja>@RestMethod</ja>(method=<jsf>POST</jsf>) |
| <jk>public</jk> Redirect addPet(Pet pet) { |
| <jc>// Redirect to servlet root</jc> |
| <jk>return new</jk> Redirect(URI.<jsm>create</jsm>(<js>"servlet:/"</js>)); |
| } |
| </p> |
| |
| <h5 class='topic'>@Resource on @RestMethod-annotated methods</h5> |
| <p> |
| The <ja>@Response</ja> annotation can also be applied to the Java method itself which is effectively |
| the same as applying it to the return type (albeit for this method only). |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/user/login"</js>) |
| <ja>@Response</ja>(code=200, description=<js>"OK"</js>) |
| <jk>public</jk> Ok login( |
| <ja>@FormData</ja>(<js>"username"</js>) String username, |
| <ja>@FormData</ja>(<js>"password"</js>) String password |
| ) <jk>throws</jk> InvalidLogin |
| { |
| checkCredentials(username, password); |
| <jk>return new</jk> Ok(); |
| } |
| </p> |
| <p> |
| The <ja>@Response</ja> annotation can be simultaneously on both the Java method and return type. |
| When used in both locations, the annotation values are combined, but values defined on the |
| method return annotation take precedence over the values defined on the type. |
| </p> |
| |
| <h5 class='topic'>@Resource on @RestMethod-annotated method parameters</h5> |
| <p> |
| The <ja>@Response</ja> annotation can also be applied to the Java method parameters when the parameter type |
| is {@link oaj.Value} (a placeholder for objects). |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/user/login"</js>) |
| <jk>public void</jk> login( |
| <ja>@FormData</ja>(<js>"username"</js>) String username, |
| <ja>@FormData</ja>(<js>"password"</js>) String password, |
| <ja>@Response</ja>(code=200, description=<js>"Login succeeded"</js>) Value<String> body |
| ) <jk>throws</jk> InvalidLogin |
| { |
| checkCredentials(username, password); |
| body.set(<js>"OK"</js>); |
| } |
| </p> |
| <p> |
| <ja>@Response</ja>-annotated types can also be used as value parameters: |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestMethod</ja>(...) |
| <jk>public void</jk> login( |
| ... |
| <ja>@Response</ja> Value<Ok> res |
| ) <jk>throws</jk> InvalidLogin |
| { |
| ... |
| res.set(<jk>new</jk> Ok()); |
| } |
| </p> |
| <p> |
| In the above example, the <ja>@Response</ja> annotation is optional since it is inferred from the class |
| that it's a <ja>@Response</ja> bean. |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/user/login"</js>) |
| <jk>public void</jk> login( |
| ... |
| Value<Ok> res <jc>// @Response annotation not needed.</jc> |
| ) <jk>throws</jk> InvalidLogin |
| { |
| ... |
| res.set(<jk>new</jk> Ok()); |
| } |
| </p> |
| |
| <h5 class='topic'>@ResponseStatus on methods of @Response-annotated types</h5> |
| <p> |
| The {@link oaj.http.annotation.ResponseStatus @ResponseStatus} annotation can be used on |
| the method of a <ja>@Response</ja>-annotated class to identify HTTP response |
| statuses other than <c>200</c> (the default). |
| </p> |
| |
| <h5 class='figure'>Example:</h5> |
| <p class='bpcode w800'> |
| <ja>@Response</ja> |
| <jk>public class</jk> AddPetSuccess { |
| |
| <ja>@ResponseStatus</ja> |
| <jk>public int</jk> getStatus() { |
| <jk>return</jk> 201; |
| } |
| |
| <ja>@Override</ja> |
| <jk>public</jk> String toString() { |
| <jk>return</jk> <js>"Pet was successfully added"</js>; |
| } |
| } |
| </p> |
| |
| |
| <h5 class='topic'>@ResponseHeader on methods of @Response-annotated types</h5> |
| <p> |
| The {@link oaj.http.annotation.ResponseHeader @ResponseHeader} annotation can be used on |
| the method of a <ja>@Response</ja>-annotated class to identify a header |
| to add to the response. |
| </p> |
| |
| <h5 class='figure'>Example:</h5> |
| <p class='bpcode w800'> |
| <ja>@Response</ja> |
| <jk>public class</jk> AddPetSuccess { |
| |
| <ja>@ResponseHeader</ja>( |
| name=<js>"X-PetId"</js>, |
| type=<js>"integer"</js>, |
| format=<js>"int32"</js>, |
| description=<js>"ID of added pet."</js>, |
| example=<js>"123"</js> |
| ) |
| <jk>public int</jk> getPetId() {...} |
| } |
| </p> |
| |
| <h5 class='topic'>@ResponseBody on methods of @Response-annotated types</h5> |
| <p> |
| The {@link oaj.http.annotation.ResponseBody @ResponseBody} annotation can be used on |
| the method of a <ja>@Response</ja>-annotated class to identify a POJO |
| as the body of the HTTP response. |
| </p> |
| |
| <h5 class='figure'>Example:</h5> |
| <p class='bpcode w800'> |
| <ja>@Response</ja> |
| <jk>public class</jk> AddPetSuccess { |
| |
| <ja>@ResponseBody</ja> |
| <jk>public</jk> Pet getPet() {...} |
| } |
| </p> |
| |
| <p> |
| If a <ja>@Response</ja> class does not have a <ja>@ResponseBody</ja>-annotated method, then the response |
| object itself is serialized in the response (typically using <c>toString()</c>). |
| </p> |
| |
| <h5 class='topic'>Notes about OpenAPI part serialization</h5> |
| <p> |
| By default, POJOs representing the body of the request are serialized using the Juneau serializer |
| matching the requesting <c>Accept</c> header. |
| The {@link oaj.oapi.OpenApiSerializer} class can be used to serialize response bodies using OpenAPI rules. |
| </p> |
| <p> |
| The following examples show part-schema-based serialization of response bodies: |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestResource</ja> |
| <jk>public class</jk> ExampleResource { |
| |
| <jc>// Example 1 - String[] should be serialized using part serializer.</jc> |
| <ja>@Response</ja>( |
| serializers=OpenApiSerializer.<jk>class</jk>, |
| defaultAccept=<js>"text/openapi"</js> |
| ) |
| <ja>@RestMethod</ja> |
| <jk>public</jk> String[] example1() { |
| <jk>return new</jk> String[]{<js>"foo"</js>,<js>"bar"</js>}; |
| } |
| |
| <jc>// Example 2 - Same as above. Annotation on parameter.</jc> |
| <ja>@RestMethod</ja> |
| <jk>public void</jk> example2( |
| <ja>@Response</ja>( |
| serializers=OpenApiSerializer.<jk>class</jk>, |
| defaultAccept=<js>"text/openapi"</js> |
| ) |
| Value<String[]> body |
| ) |
| { |
| body.set(<jk>new</jk> String[]{<js>"foo"</js>,<js>"bar"</js>}); |
| } |
| } |
| </p> |
| <p> |
| The <c><ja>@Response</ja>(schema)</c> annotation can be used to define the format of the output using OpenAPI-based rules. |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestResource</ja> |
| <jk>public class</jk> ExampleResource { |
| |
| <ja>@Response</ja>( |
| serializers=OpenApiSerializer.<jk>class</jk>, |
| defaultAccept=<js>"text/openapi"</js>, |
| schema=<ja>@Schema</ja>(collectionFormat=<js>"pipes"</js>) |
| ) |
| <ja>@RestMethod</ja> |
| <jk>public</jk> String[] example1() { |
| <jk>return new</jk> String[]{<js>"foo"</js>,<js>"bar"</js>}; |
| } |
| } |
| </p> |
| |
| <h5 class='topic'>Swagger documentation</h5> |
| <p> |
| The attributes on this annotation are also used to populate the generated Swagger for the method. |
| For example, in the case of the <c>InvalidLogin</c> example above, the following Swagger is generated: |
| </p> |
| <p class='bpcode w800'> |
| <jok>'/user/login'</jok>: { |
| <jok>get</jok>: { |
| <jok>responses</jok>: { |
| <jok>401</jok>: { |
| <jok>description</jok>: <jov>'Invalid username or password provided'</jov> |
| } |
| } |
| } |
| } |
| </p> |
| |
| <h5 class='topic'>Automatic HTTP status</h5> |
| <p> |
| When the {@link oaj.http.annotation.Response#code() @Response(code)} value is specified, |
| the HTTP status is automatically set to that value on the response regardless of how it's used. |
| </p> |
| <p> |
| The following two examples are equivalent: |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/ok"</js>) |
| <jk>public void</jk> sendContinue( |
| <ja>@Response</ja>(code=100) Value<String> body |
| ) |
| { |
| body.set(<js>"OK"</js>); |
| } |
| </p> |
| <p class='bpcode w800'> |
| <ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/ok"</js>) |
| <jk>public void</jk> sendContinue(RestResponse res) { |
| res.setStatus(100); |
| res.setOutput(<js>"OK"</js>); |
| } |
| </p> |
| |
| <ul class='seealso'> |
| <li class='link'>{@doc juneau-rest-server.OpenApiSchemaPartSerializing} |
| </ul> |
| |