All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ratpack.handling.ByContentSpec Maven / Gradle / Ivy

/*
 * Copyright 2013 the original author or authors.
 *
 * Licensed 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.
 */

package ratpack.handling;

import ratpack.func.Block;

/**
 * A specification of how to respond to a request, based on the requested content type (i.e. the request's Accept header).
 * This is useful when a given handler can provide content of more than one type (i.e. content negotiation).
 * 

* The handler to use will be selected based on parsing the "Accept" header, respecting quality weighting and wildcard matching. * The order that types are specified is significant for wildcard matching. * The earliest registered type that matches the wildcard will be used. * *

{@code
 * import ratpack.test.embed.EmbeddedApp;
 * import ratpack.http.client.ReceivedResponse;
 *
 * import static org.junit.Assert.*;
 *
 * public class Example {
 *   public static void main(String[] args) throws Exception {
 *     EmbeddedApp.fromHandler(ctx -> {
 *       String message = "hello!";
 *       ctx.byContent(m -> m
 *         .json(() -> ctx.render("{\"msg\": \"" + message + "\"}"))
 *         .html(() -> ctx.render("

" + message + "

")) * ); * }).test(httpClient -> { * ReceivedResponse response = httpClient.requestSpec(s -> s.getHeaders().add("Accept", "application/json")).get(); * assertEquals("{\"msg\": \"hello!\"}", response.getBody().getText()); * assertEquals("application/json", response.getBody().getContentType().getType()); * * response = httpClient.requestSpec(s -> s.getHeaders().add("Accept", "text/plain; q=1.0, text/html; q=0.8, application/json; q=0.7")).get(); * assertEquals("

hello!

", response.getBody().getText()); * assertEquals("text/html", response.getBody().getContentType().getType()); * }); * } * } * }
*

* If there is no type registered, or if the client does not accept any of the given types, the "noMatch" handler will be used. * By default, the "noMatch" handler will issue a {@code 406} error via {@link Context#clientError(int)}. * If you want a different behavior, use {@link #noMatch}. *

* If the request lacks a usable Accept header (header not present or has an empty value), the "unspecified" handler will be used. * By default, the "unspecified" handler will use the handler for the first registered content type. * If you want a different behavior, use {@link #unspecified}. *

* Only the last specified handler for a type will be used. * That is, adding a subsequent handler for the same type will replace the previous. * * @see Context#byContent(ratpack.func.Action) * @see RFC 7231: Accept * @see RFC 7231: 406 Not Acceptable */ public interface ByContentSpec { /** * Specifies that the given handler should be used if the client wants content of the given MIME type. * This only supports fully-specified content types (no "*" wildcards). * * @param mimeType the MIME type to register for * @param block the code to invoke if the content type matches * @return this */ default ByContentSpec type(String mimeType, Block block) { return type(mimeType, Handlers.of(block)); } /** * Specifies that the given handler should be used if the client wants content of the given MIME type. * This only supports fully-specified content types (no "*" wildcards). * * @param mimeType the MIME type to register for * @param block the code to invoke if the content type matches * @return this * @since 1.6 */ default ByContentSpec type(CharSequence mimeType, Block block) { return type(mimeType, Handlers.of(block)); } /** * Specifies that the given handler should be used if the client wants content of the given MIME type. * This only supports fully-specified content types (no "*" wildcards). * * @param mimeType the MIME type to register for * @param handler the handler to invoke if the content type matches * @return this * @since 1.5 */ ByContentSpec type(String mimeType, Handler handler); /** * Specifies that the given handler should be used if the client wants content of the given MIME type. * This only supports fully-specified content types (no "*" wildcards). * * @param mimeType the MIME type to register for * @param handler the handler to invoke if the content type matches * @return this * @since 1.6 */ ByContentSpec type(CharSequence mimeType, Handler handler); /** * Specifies that the given handler should be used if the client wants content of the given MIME type. * This only supports fully-specified content types (no "*" wildcards). * * @param mimeType the MIME type to register for * @param handlerType the type of handler to retrieve from the registry and use * @return this * @since 1.5 */ ByContentSpec type(String mimeType, Class handlerType); /** * Specifies that the given handler should be used if the client wants content of the given MIME type. * This only supports fully-specified content types (no "*" wildcards). * * @param mimeType the MIME type to register for * @param handlerType the type of handler to retrieve from the registry and use * @return this * @since 1.6 */ ByContentSpec type(CharSequence mimeType, Class handlerType); /** * Specifies that the given handler should be used if the client wants content of type "text/plain". * * @param block the code to invoke if the content type matches * @return this */ default ByContentSpec plainText(Block block) { return plainText(Handlers.of(block)); } /** * Specifies that the given handler should be used if the client wants content of type "text/plain". * * @param handler the handler to invoke if the content type matches * @return this * @since 1.5 */ ByContentSpec plainText(Handler handler); /** * Specifies that the given handler should be used if the client wants content of type "text/plain". * * @param handlerType the type of handler to retrieve from the registry and use * @return this * @since 1.5 */ ByContentSpec plainText(Class handlerType); /** * Specifies that the given handler should be used if the client wants content of type "text/html". * * @param block the code to invoke if the content type matches * @return this */ default ByContentSpec html(Block block) { return html(Handlers.of(block)); } /** * Specifies that the given handler should be used if the client wants content of type "text/html". * * @param handler the handler to invoke if the content type matches * @return this * @since 1.5 */ ByContentSpec html(Handler handler); /** * Specifies that the given handler should be used if the client wants content of type "text/html". * * @param handlerType the type of handler to retrieve from the registry and use * @return this * @since 1.5 */ ByContentSpec html(Class handlerType); /** * Specifies that the given handler should be used if the client wants content of type "application/json". * * @param block the code to invoke if the content type matches * @return this */ default ByContentSpec json(Block block) { return json(Handlers.of(block)); } /** * Specifies that the given handler should be used if the client wants content of type "application/json". * * @param handler the handler to invoke if the content type matches * @return this * @since 1.5 */ ByContentSpec json(Handler handler); /** * Specifies that the given handler should be used if the client wants content of type "application/json". * * @param handlerType the type of handler to retrieve from the registry and use * @return this * @since 1.5 */ ByContentSpec json(Class handlerType); /** * Specifies that the given handler should be used if the client wants content of type "application/xml". * * @param block the code to invoke if the content type matches * @return this */ default ByContentSpec xml(Block block) { return xml(Handlers.of(block)); } /** * Specifies that the given handler should be used if the client wants content of type "application/xml". * * @param handler the handler to invoke if the content type matches * @return this * @since 1.5 */ ByContentSpec xml(Handler handler); /** * Specifies that the given handler should be used if the client wants content of type "application/xml". * * @param handlerType the type of handler to retrieve from the registry and use * @return this * @since 1.5 */ ByContentSpec xml(Class handlerType); /** * Specifies that the given handler should be used if the client's requested content type cannot be matched with any of the other handlers. * * @param block the code to invoke if the content type doesn't match * @return this */ default ByContentSpec noMatch(Block block) { return noMatch(Handlers.of(block)); } /** * Specifies that the given handler should be used if the client's requested content type cannot be matched with any of the other handlers. * * @param handler the handler to invoke if the content type matches * @return this * @since 1.5 */ ByContentSpec noMatch(Handler handler); /** * Specifies that the given handler should be used if the client's requested content type cannot be matched with any of the other handlers. * * @param handlerType the type of handler to retrieve from the registry and use * @return this * @since 1.5 */ ByContentSpec noMatch(Class handlerType); /** * Specifies that the handler for the specified content type should be used if the client's requested content type cannot be matched with any of the other handlers. * Effectively, this treats the request as if the user requested the specified MIME type. * If the specified mimeType doesn't have a registered block, it will result in a server error for applicable requests. * * @param mimeType the MIME type to use as a fallback if the requested type can't be matched * @return this */ ByContentSpec noMatch(String mimeType); /** * Specifies that the given handler should be used if the client did not provide a usable "Accept" header in the request. * * @param block the code to invoke if no usable "Accept" header is present in the request. * @return this * @since 1.5 */ default ByContentSpec unspecified(Block block) { return unspecified(Handlers.of(block)); } /** * Specifies that the given handler should be used if the client did not provide a usable "Accept" header in the request. * * @param handler the handler to invoke if if no usable "Accept" header is present in the request. * @return this * @since 1.5 */ ByContentSpec unspecified(Handler handler); /** * Specifies that the given handler should be used if the client did not provide a usable "Accept" header in the request. * * @param handlerType the type of handler to retrieve from the registry and use if no usable "Accept" header is present in the request. * @return this * @since 1.5 */ ByContentSpec unspecified(Class handlerType); /** * Specifies that the handler for the specified content type should be used if the client did not provide a usable "Accept" header in the request. * Effectively, this treats the request as if the user requested the specified MIME type. * If the specified mimeType doesn't have a registered block, it will result in a server error for applicable requests. * * @param mimeType the MIME type to use as a fallback if no type is requested * @return this * @since 1.5 */ ByContentSpec unspecified(String mimeType); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy