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