001/*
002 * Copyright 2002-2017 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.web.servlet.mvc.method.annotation;
018
019import java.io.IOException;
020import java.lang.reflect.Type;
021
022import org.springframework.core.MethodParameter;
023import org.springframework.http.HttpInputMessage;
024import org.springframework.http.converter.HttpMessageConverter;
025import org.springframework.lang.Nullable;
026
027/**
028 * Allows customizing the request before its body is read and converted into an
029 * Object and also allows for processing of the resulting Object before it is
030 * passed into a controller method as an {@code @RequestBody} or an
031 * {@code HttpEntity} method argument.
032 *
033 * <p>Implementations of this contract may be registered directly with the
034 * {@code RequestMappingHandlerAdapter} or more likely annotated with
035 * {@code @ControllerAdvice} in which case they are auto-detected.
036 *
037 * @author Rossen Stoyanchev
038 * @since 4.2
039 */
040public interface RequestBodyAdvice {
041
042        /**
043         * Invoked first to determine if this interceptor applies.
044         * @param methodParameter the method parameter
045         * @param targetType the target type, not necessarily the same as the method
046         * parameter type, e.g. for {@code HttpEntity<String>}.
047         * @param converterType the selected converter type
048         * @return whether this interceptor should be invoked or not
049         */
050        boolean supports(MethodParameter methodParameter, Type targetType,
051                        Class<? extends HttpMessageConverter<?>> converterType);
052
053        /**
054         * Invoked second before the request body is read and converted.
055         * @param inputMessage the request
056         * @param parameter the target method parameter
057         * @param targetType the target type, not necessarily the same as the method
058         * parameter type, e.g. for {@code HttpEntity<String>}.
059         * @param converterType the converter used to deserialize the body
060         * @return the input request or a new instance, never {@code null}
061         */
062        HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter,
063                        Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException;
064
065        /**
066         * Invoked third (and last) after the request body is converted to an Object.
067         * @param body set to the converter Object before the first advice is called
068         * @param inputMessage the request
069         * @param parameter the target method parameter
070         * @param targetType the target type, not necessarily the same as the method
071         * parameter type, e.g. for {@code HttpEntity<String>}.
072         * @param converterType the converter used to deserialize the body
073         * @return the same body or a new instance
074         */
075        Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter,
076                        Type targetType, Class<? extends HttpMessageConverter<?>> converterType);
077
078        /**
079         * Invoked second (and last) if the body is empty.
080         * @param body usually set to {@code null} before the first advice is called
081         * @param inputMessage the request
082         * @param parameter the method parameter
083         * @param targetType the target type, not necessarily the same as the method
084         * parameter type, e.g. for {@code HttpEntity<String>}.
085         * @param converterType the selected converter type
086         * @return the value to use or {@code null} which may then raise an
087         * {@code HttpMessageNotReadableException} if the argument is required.
088         */
089        @Nullable
090        Object handleEmptyBody(@Nullable Object body, HttpInputMessage inputMessage, MethodParameter parameter,
091                        Type targetType, Class<? extends HttpMessageConverter<?>> converterType);
092
093
094}