001/* 002 * Copyright 2002-2019 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.function; 018 019import java.util.Collection; 020import java.util.Map; 021import java.util.function.Consumer; 022 023import javax.servlet.http.Cookie; 024 025import org.springframework.http.HttpHeaders; 026import org.springframework.http.HttpStatus; 027import org.springframework.lang.Nullable; 028import org.springframework.util.MultiValueMap; 029 030/** 031 * Rendering-specific subtype of {@link ServerResponse} that exposes model and template data. 032 * 033 * @author Arjen Poutsma 034 * @since 5.2 035 */ 036public interface RenderingResponse extends ServerResponse { 037 038 /** 039 * Return the name of the template to be rendered. 040 */ 041 String name(); 042 043 /** 044 * Return the unmodifiable model map. 045 */ 046 Map<String, Object> model(); 047 048 049 // Builder 050 051 /** 052 * Create a builder with the template name, status code, headers and model of the given response. 053 * @param other the response to copy the values from 054 * @return the created builder 055 */ 056 static Builder from(RenderingResponse other) { 057 return new DefaultRenderingResponseBuilder(other); 058 } 059 060 /** 061 * Create a builder with the given template name. 062 * @param name the name of the template to render 063 * @return the created builder 064 */ 065 static Builder create(String name) { 066 return new DefaultRenderingResponseBuilder(name); 067 } 068 069 070 /** 071 * Defines a builder for {@code RenderingResponse}. 072 */ 073 interface Builder { 074 075 /** 076 * Add the supplied attribute to the model using a 077 * {@linkplain org.springframework.core.Conventions#getVariableName generated name}. 078 * <p><em>Note: Empty {@link Collection Collections} are not added to 079 * the model when using this method because we cannot correctly determine 080 * the true convention name. View code should check for {@code null} rather 081 * than for empty collections.</em> 082 * @param attribute the model attribute value (never {@code null}) 083 */ 084 Builder modelAttribute(Object attribute); 085 086 /** 087 * Add the supplied attribute value under the supplied name. 088 * @param name the name of the model attribute (never {@code null}) 089 * @param value the model attribute value (can be {@code null}) 090 */ 091 Builder modelAttribute(String name, @Nullable Object value); 092 093 /** 094 * Copy all attributes in the supplied array into the model, 095 * using attribute name generation for each element. 096 * @see #modelAttribute(Object) 097 */ 098 Builder modelAttributes(Object... attributes); 099 100 /** 101 * Copy all attributes in the supplied {@code Collection} into the model, 102 * using attribute name generation for each element. 103 * @see #modelAttribute(Object) 104 */ 105 Builder modelAttributes(Collection<?> attributes); 106 107 /** 108 * Copy all attributes in the supplied {@code Map} into the model. 109 * @see #modelAttribute(String, Object) 110 */ 111 Builder modelAttributes(Map<String, ?> attributes); 112 113 /** 114 * Add the given header value(s) under the given name. 115 * @param headerName the header name 116 * @param headerValues the header value(s) 117 * @return this builder 118 * @see HttpHeaders#add(String, String) 119 */ 120 Builder header(String headerName, String... headerValues); 121 122 /** 123 * Manipulate this response's headers with the given consumer. The 124 * headers provided to the consumer are "live", so that the consumer can be used to 125 * {@linkplain HttpHeaders#set(String, String) overwrite} existing header values, 126 * {@linkplain HttpHeaders#remove(Object) remove} values, or use any of the other 127 * {@link HttpHeaders} methods. 128 * @param headersConsumer a function that consumes the {@code HttpHeaders} 129 * @return this builder 130 */ 131 Builder headers(Consumer<HttpHeaders> headersConsumer); 132 133 /** 134 * Set the HTTP status. 135 * @param status the response status 136 * @return this builder 137 */ 138 Builder status(HttpStatus status); 139 140 /** 141 * Set the HTTP status. 142 * @param status the response status 143 * @return this builder 144 */ 145 Builder status(int status); 146 147 /** 148 * Add the given cookie to the response. 149 * @param cookie the cookie to add 150 * @return this builder 151 */ 152 Builder cookie(Cookie cookie); 153 154 /** 155 * Manipulate this response's cookies with the given consumer. The 156 * cookies provided to the consumer are "live", so that the consumer can be used to 157 * {@linkplain MultiValueMap#set(Object, Object) overwrite} existing cookies, 158 * {@linkplain MultiValueMap#remove(Object) remove} cookies, or use any of the other 159 * {@link MultiValueMap} methods. 160 * @param cookiesConsumer a function that consumes the cookies 161 * @return this builder 162 */ 163 Builder cookies(Consumer<MultiValueMap<String, Cookie>> cookiesConsumer); 164 165 /** 166 * Build the response. 167 * @return the built response 168 */ 169 RenderingResponse build(); 170 } 171 172}