001/*
002 * Copyright 2002-2018 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.http.codec;
018
019import java.util.List;
020import java.util.Map;
021
022import reactor.core.publisher.Flux;
023import reactor.core.publisher.Mono;
024
025import org.springframework.core.MethodParameter;
026import org.springframework.core.ResolvableType;
027import org.springframework.http.MediaType;
028import org.springframework.http.ReactiveHttpInputMessage;
029import org.springframework.http.server.reactive.ServerHttpRequest;
030import org.springframework.http.server.reactive.ServerHttpResponse;
031import org.springframework.lang.Nullable;
032
033/**
034 * Strategy for reading from a {@link ReactiveHttpInputMessage} and decoding
035 * the stream of bytes to Objects of type {@code <T>}.
036 *
037 * @author Rossen Stoyanchev
038 * @author Arjen Poutsma
039 * @author Sebastien Deleuze
040 * @since 5.0
041 * @param <T> the type of objects in the decoded output stream
042 */
043public interface HttpMessageReader<T> {
044
045        /**
046         * Return the {@link MediaType}'s that this reader supports.
047         */
048        List<MediaType> getReadableMediaTypes();
049
050        /**
051         * Whether the given object type is supported by this reader.
052         * @param elementType the type of object to check
053         * @param mediaType the media type for the read (possibly {@code null})
054         * @return {@code true} if readable, {@code false} otherwise
055         */
056        boolean canRead(ResolvableType elementType, @Nullable MediaType mediaType);
057
058        /**
059         * Read from the input message and encode to a stream of objects.
060         * @param elementType the type of objects in the stream which must have been
061         * previously checked via {@link #canRead(ResolvableType, MediaType)}
062         * @param message the message to read from
063         * @param hints additional information about how to read and decode the input
064         * @return the decoded stream of elements
065         */
066        Flux<T> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints);
067
068        /**
069         * Read from the input message and encode to a single object.
070         * @param elementType the type of objects in the stream which must have been
071         * previously checked via {@link #canRead(ResolvableType, MediaType)}
072         * @param message the message to read from
073         * @param hints additional information about how to read and decode the input
074         * @return the decoded object
075         */
076        Mono<T> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints);
077
078        /**
079         * Server-side only alternative to
080         * {@link #read(ResolvableType, ReactiveHttpInputMessage, Map)}
081         * with additional context available.
082         * @param actualType the actual type of the target method parameter;
083         * for annotated controllers, the {@link MethodParameter} can be accessed
084         * via {@link ResolvableType#getSource()}.
085         * @param elementType the type of Objects in the output stream
086         * @param request the current request
087         * @param response the current response
088         * @param hints additional information about how to read the body
089         * @return the decoded stream of elements
090         */
091        default Flux<T> read(ResolvableType actualType, ResolvableType elementType, ServerHttpRequest request,
092                        ServerHttpResponse response, Map<String, Object> hints) {
093
094                return read(elementType, request, hints);
095        }
096
097        /**
098         * Server-side only alternative to
099         * {@link #readMono(ResolvableType, ReactiveHttpInputMessage, Map)}
100         * with additional, context available.
101         * @param actualType the actual type of the target method parameter;
102         * for annotated controllers, the {@link MethodParameter} can be accessed
103         * via {@link ResolvableType#getSource()}.
104         * @param elementType the type of Objects in the output stream
105         * @param request the current request
106         * @param response the current response
107         * @param hints additional information about how to read the body
108         * @return the decoded stream of elements
109         */
110        default Mono<T> readMono(ResolvableType actualType, ResolvableType elementType, ServerHttpRequest request,
111                        ServerHttpResponse response, Map<String, Object> hints) {
112
113                return readMono(elementType, request, hints);
114        }
115
116}