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.function.server.support;
018
019import java.util.Collections;
020import java.util.List;
021
022import reactor.core.publisher.Mono;
023
024import org.springframework.beans.factory.InitializingBean;
025import org.springframework.core.Ordered;
026import org.springframework.http.codec.HttpMessageWriter;
027import org.springframework.http.codec.ServerCodecConfigurer;
028import org.springframework.util.Assert;
029import org.springframework.util.CollectionUtils;
030import org.springframework.web.reactive.HandlerResult;
031import org.springframework.web.reactive.HandlerResultHandler;
032import org.springframework.web.reactive.function.server.ServerResponse;
033import org.springframework.web.reactive.result.view.ViewResolver;
034import org.springframework.web.server.ServerWebExchange;
035
036/**
037 * {@code HandlerResultHandler} implementation that supports {@link ServerResponse ServerResponses}.
038 *
039 * @author Arjen Poutsma
040 * @since 5.0
041 */
042public class ServerResponseResultHandler implements HandlerResultHandler, InitializingBean, Ordered {
043
044        private List<HttpMessageWriter<?>> messageWriters = Collections.emptyList();
045
046        private List<ViewResolver> viewResolvers = Collections.emptyList();
047
048        private int order = 0;
049
050
051        /**
052         * Configure HTTP message writers to serialize the request body with.
053         * <p>By default this is set to {@link ServerCodecConfigurer}'s default writers.
054         */
055        public void setMessageWriters(List<HttpMessageWriter<?>> configurer) {
056                this.messageWriters = configurer;
057        }
058
059        public void setViewResolvers(List<ViewResolver> viewResolvers) {
060                this.viewResolvers = viewResolvers;
061        }
062
063        /**
064         * Set the order for this result handler relative to others.
065         * <p>By default set to 0. It is generally safe to place it early in the
066         * order as it looks for a concrete return type.
067         */
068        public void setOrder(int order) {
069                this.order = order;
070        }
071
072        @Override
073        public int getOrder() {
074                return this.order;
075        }
076
077
078        @Override
079        public void afterPropertiesSet() throws Exception {
080                if (CollectionUtils.isEmpty(this.messageWriters)) {
081                        throw new IllegalArgumentException("Property 'messageWriters' is required");
082                }
083        }
084
085        @Override
086        public boolean supports(HandlerResult result) {
087                return (result.getReturnValue() instanceof ServerResponse);
088        }
089
090        @Override
091        public Mono<Void> handleResult(ServerWebExchange exchange, HandlerResult result) {
092                ServerResponse response = (ServerResponse) result.getReturnValue();
093                Assert.state(response != null, "No ServerResponse");
094                return response.writeTo(exchange, new ServerResponse.Context() {
095                        @Override
096                        public List<HttpMessageWriter<?>> messageWriters() {
097                                return messageWriters;
098                        }
099                        @Override
100                        public List<ViewResolver> viewResolvers() {
101                                return viewResolvers;
102                        }
103                });
104        }
105
106}