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.web.reactive.result.method.annotation;
018
019import java.util.List;
020
021import reactor.core.publisher.Mono;
022
023import org.springframework.core.MethodParameter;
024import org.springframework.core.ReactiveAdapterRegistry;
025import org.springframework.core.annotation.AnnotatedElementUtils;
026import org.springframework.http.codec.HttpMessageWriter;
027import org.springframework.web.bind.annotation.ResponseBody;
028import org.springframework.web.reactive.HandlerResult;
029import org.springframework.web.reactive.HandlerResultHandler;
030import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
031import org.springframework.web.server.ServerWebExchange;
032
033/**
034 * {@code HandlerResultHandler} that handles return values from methods annotated
035 * with {@code @ResponseBody} writing to the body of the request or response with
036 * an {@link HttpMessageWriter}.
037 *
038 * <p>By default the order for this result handler is set to 100. As it detects
039 * the presence of {@code @ResponseBody} it should be ordered after result
040 * handlers that look for a specific return type. Note however that this handler
041 * does recognize and explicitly ignores the {@code ResponseEntity} return type.
042 *
043 * @author Rossen Stoyanchev
044 * @author Stephane Maldini
045 * @author Sebastien Deleuze
046 * @author Arjen Poutsma
047 * @since 5.0
048 */
049public class ResponseBodyResultHandler extends AbstractMessageWriterResultHandler implements HandlerResultHandler {
050
051        /**
052         * Basic constructor with a default {@link ReactiveAdapterRegistry}.
053         * @param writers the writers for serializing to the response body
054         * @param resolver to determine the requested content type
055         */
056        public ResponseBodyResultHandler(List<HttpMessageWriter<?>> writers, RequestedContentTypeResolver resolver) {
057                this(writers, resolver, ReactiveAdapterRegistry.getSharedInstance());
058        }
059
060        /**
061         * Constructor with an {@link ReactiveAdapterRegistry} instance.
062         * @param writers the writers for serializing to the response body
063         * @param resolver to determine the requested content type
064         * @param registry for adaptation to reactive types
065         */
066        public ResponseBodyResultHandler(List<HttpMessageWriter<?>> writers,
067                        RequestedContentTypeResolver resolver, ReactiveAdapterRegistry registry) {
068
069                super(writers, resolver, registry);
070                setOrder(100);
071        }
072
073
074        @Override
075        public boolean supports(HandlerResult result) {
076                MethodParameter returnType = result.getReturnTypeSource();
077                Class<?> containingClass = returnType.getContainingClass();
078                return (AnnotatedElementUtils.hasAnnotation(containingClass, ResponseBody.class) ||
079                                returnType.hasMethodAnnotation(ResponseBody.class));
080        }
081
082        @Override
083        public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
084                Object body = result.getReturnValue();
085                MethodParameter bodyTypeParameter = result.getReturnTypeSource();
086                return writeBody(body, bodyTypeParameter, exchange);
087        }
088
089}