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.net.URI; 020import java.time.Instant; 021import java.time.ZonedDateTime; 022import java.util.Set; 023import java.util.function.Consumer; 024 025import javax.servlet.http.Cookie; 026 027import org.springframework.core.ParameterizedTypeReference; 028import org.springframework.http.CacheControl; 029import org.springframework.http.HttpHeaders; 030import org.springframework.http.HttpMethod; 031import org.springframework.http.HttpStatus; 032import org.springframework.http.MediaType; 033import org.springframework.util.MultiValueMap; 034 035/** 036 * Entity-specific subtype of {@link ServerResponse} that exposes entity data. 037 * 038 * @author Arjen Poutsma 039 * @since 5.2 040 * @param <T> the entity type 041 */ 042public interface EntityResponse<T> extends ServerResponse { 043 044 /** 045 * Return the entity that makes up this response. 046 */ 047 T entity(); 048 049 050 // Static builder methods 051 052 /** 053 * Create a builder with the given object. 054 * @param t the object that represents the body of the response 055 * @param <T> the type of element contained in the publisher 056 * @return the created builder 057 */ 058 static <T> Builder<T> fromObject(T t) { 059 return DefaultEntityResponseBuilder.fromObject(t); 060 } 061 062 /** 063 * Create a builder with the given object and type reference. 064 * @param t the object that represents the body of the response 065 * @param entityType the type of the entity, used to capture the generic type 066 * @param <T> the type of element contained in the publisher 067 * @return the created builder 068 */ 069 static <T> Builder<T> fromObject(T t, ParameterizedTypeReference<T> entityType) { 070 return DefaultEntityResponseBuilder.fromObject(t, entityType); 071 } 072 073 074 /** 075 * Defines a builder for {@code EntityResponse}. 076 * @param <T> the entity type 077 */ 078 interface Builder<T> { 079 080 /** 081 * Add the given header value(s) under the given name. 082 * @param headerName the header name 083 * @param headerValues the header value(s) 084 * @return this builder 085 * @see HttpHeaders#add(String, String) 086 */ 087 Builder<T> header(String headerName, String... headerValues); 088 089 /** 090 * Manipulate this response's headers with the given consumer. The 091 * headers provided to the consumer are "live", so that the consumer can be used to 092 * {@linkplain HttpHeaders#set(String, String) overwrite} existing header values, 093 * {@linkplain HttpHeaders#remove(Object) remove} values, or use any of the other 094 * {@link HttpHeaders} methods. 095 * @param headersConsumer a function that consumes the {@code HttpHeaders} 096 * @return this builder 097 */ 098 Builder<T> headers(Consumer<HttpHeaders> headersConsumer); 099 100 /** 101 * Set the HTTP status. 102 * @param status the response status 103 * @return this builder 104 */ 105 Builder<T> status(HttpStatus status); 106 107 /** 108 * Set the HTTP status. 109 * @param status the response status 110 * @return this builder 111 */ 112 Builder<T> status(int status); 113 114 /** 115 * Add the given cookie to the response. 116 * @param cookie the cookie to add 117 * @return this builder 118 */ 119 Builder<T> cookie(Cookie cookie); 120 121 /** 122 * Manipulate this response's cookies with the given consumer. The 123 * cookies provided to the consumer are "live", so that the consumer can be used to 124 * {@linkplain MultiValueMap#set(Object, Object) overwrite} existing cookies, 125 * {@linkplain MultiValueMap#remove(Object) remove} cookies, or use any of the other 126 * {@link MultiValueMap} methods. 127 * @param cookiesConsumer a function that consumes the cookies 128 * @return this builder 129 */ 130 Builder<T> cookies(Consumer<MultiValueMap<String, Cookie>> cookiesConsumer); 131 132 /** 133 * Set the set of allowed {@link HttpMethod HTTP methods}, as specified 134 * by the {@code Allow} header. 135 * @param allowedMethods the allowed methods 136 * @return this builder 137 * @see HttpHeaders#setAllow(Set) 138 */ 139 Builder<T> allow(HttpMethod... allowedMethods); 140 141 /** 142 * Set the set of allowed {@link HttpMethod HTTP methods}, as specified 143 * by the {@code Allow} header. 144 * @param allowedMethods the allowed methods 145 * @return this builder 146 * @see HttpHeaders#setAllow(Set) 147 */ 148 Builder<T> allow(Set<HttpMethod> allowedMethods); 149 150 /** 151 * Set the entity tag of the body, as specified by the {@code ETag} header. 152 * @param etag the new entity tag 153 * @return this builder 154 * @see HttpHeaders#setETag(String) 155 */ 156 Builder<T> eTag(String etag); 157 158 /** 159 * Set the time the resource was last changed, as specified by the 160 * {@code Last-Modified} header. 161 * <p>The date should be specified as the number of milliseconds since 162 * January 1, 1970 GMT. 163 * @param lastModified the last modified date 164 * @return this builder 165 * @see HttpHeaders#setLastModified(long) 166 */ 167 Builder<T> lastModified(ZonedDateTime lastModified); 168 169 /** 170 * Set the time the resource was last changed, as specified by the 171 * {@code Last-Modified} header. 172 * <p>The date should be specified as the number of milliseconds since 173 * January 1, 1970 GMT. 174 * @param lastModified the last modified date 175 * @return this builder 176 * @since 5.1.4 177 * @see HttpHeaders#setLastModified(long) 178 */ 179 Builder<T> lastModified(Instant lastModified); 180 /** 181 * Set the location of a resource, as specified by the {@code Location} header. 182 * @param location the location 183 * @return this builder 184 * @see HttpHeaders#setLocation(URI) 185 */ 186 Builder<T> location(URI location); 187 188 /** 189 * Set the caching directives for the resource, as specified by the HTTP 1.1 190 * {@code Cache-Control} header. 191 * <p>A {@code CacheControl} instance can be built like 192 * {@code CacheControl.maxAge(3600).cachePublic().noTransform()}. 193 * @param cacheControl a builder for cache-related HTTP response headers 194 * @return this builder 195 * @see <a href="https://tools.ietf.org/html/rfc7234#section-5.2">RFC-7234 Section 5.2</a> 196 */ 197 Builder<T> cacheControl(CacheControl cacheControl); 198 199 /** 200 * Configure one or more request header names (e.g. "Accept-Language") to 201 * add to the "Vary" response header to inform clients that the response is 202 * subject to content negotiation and variances based on the value of the 203 * given request headers. The configured request header names are added only 204 * if not already present in the response "Vary" header. 205 * @param requestHeaders request header names 206 * @return this builder 207 */ 208 Builder<T> varyBy(String... requestHeaders); 209 210 /** 211 * Set the length of the body in bytes, as specified by the 212 * {@code Content-Length} header. 213 * @param contentLength the content length 214 * @return this builder 215 * @see HttpHeaders#setContentLength(long) 216 */ 217 Builder<T> contentLength(long contentLength); 218 219 /** 220 * Set the {@linkplain MediaType media type} of the body, as specified by the 221 * {@code Content-Type} header. 222 * @param contentType the content type 223 * @return this builder 224 * @see HttpHeaders#setContentType(MediaType) 225 */ 226 Builder<T> contentType(MediaType contentType); 227 228 /** 229 * Build the response. 230 * @return the built response 231 */ 232 EntityResponse<T> build(); 233 } 234 235}