001/* 002 * Copyright 2002-2020 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.context.request; 018 019import java.security.Principal; 020import java.util.Iterator; 021import java.util.Locale; 022import java.util.Map; 023 024import org.springframework.lang.Nullable; 025 026/** 027 * Generic interface for a web request. Mainly intended for generic web 028 * request interceptors, giving them access to general request metadata, 029 * not for actual handling of the request. 030 * 031 * @author Juergen Hoeller 032 * @author Brian Clozel 033 * @since 2.0 034 * @see WebRequestInterceptor 035 */ 036public interface WebRequest extends RequestAttributes { 037 038 /** 039 * Return the request header of the given name, or {@code null} if none. 040 * <p>Retrieves the first header value in case of a multi-value header. 041 * @since 3.0 042 * @see javax.servlet.http.HttpServletRequest#getHeader(String) 043 */ 044 @Nullable 045 String getHeader(String headerName); 046 047 /** 048 * Return the request header values for the given header name, 049 * or {@code null} if none. 050 * <p>A single-value header will be exposed as an array with a single element. 051 * @since 3.0 052 * @see javax.servlet.http.HttpServletRequest#getHeaders(String) 053 */ 054 @Nullable 055 String[] getHeaderValues(String headerName); 056 057 /** 058 * Return a Iterator over request header names. 059 * @since 3.0 060 * @see javax.servlet.http.HttpServletRequest#getHeaderNames() 061 */ 062 Iterator<String> getHeaderNames(); 063 064 /** 065 * Return the request parameter of the given name, or {@code null} if none. 066 * <p>Retrieves the first parameter value in case of a multi-value parameter. 067 * @see javax.servlet.http.HttpServletRequest#getParameter(String) 068 */ 069 @Nullable 070 String getParameter(String paramName); 071 072 /** 073 * Return the request parameter values for the given parameter name, 074 * or {@code null} if none. 075 * <p>A single-value parameter will be exposed as an array with a single element. 076 * @see javax.servlet.http.HttpServletRequest#getParameterValues(String) 077 */ 078 @Nullable 079 String[] getParameterValues(String paramName); 080 081 /** 082 * Return a Iterator over request parameter names. 083 * @since 3.0 084 * @see javax.servlet.http.HttpServletRequest#getParameterNames() 085 */ 086 Iterator<String> getParameterNames(); 087 088 /** 089 * Return a immutable Map of the request parameters, with parameter names as map keys 090 * and parameter values as map values. The map values will be of type String array. 091 * <p>A single-value parameter will be exposed as an array with a single element. 092 * @see javax.servlet.http.HttpServletRequest#getParameterMap() 093 */ 094 Map<String, String[]> getParameterMap(); 095 096 /** 097 * Return the primary Locale for this request. 098 * @see javax.servlet.http.HttpServletRequest#getLocale() 099 */ 100 Locale getLocale(); 101 102 /** 103 * Return the context path for this request 104 * (usually the base path that the current web application is mapped to). 105 * @see javax.servlet.http.HttpServletRequest#getContextPath() 106 */ 107 String getContextPath(); 108 109 /** 110 * Return the remote user for this request, if any. 111 * @see javax.servlet.http.HttpServletRequest#getRemoteUser() 112 */ 113 @Nullable 114 String getRemoteUser(); 115 116 /** 117 * Return the user principal for this request, if any. 118 * @see javax.servlet.http.HttpServletRequest#getUserPrincipal() 119 */ 120 @Nullable 121 Principal getUserPrincipal(); 122 123 /** 124 * Determine whether the user is in the given role for this request. 125 * @see javax.servlet.http.HttpServletRequest#isUserInRole(String) 126 */ 127 boolean isUserInRole(String role); 128 129 /** 130 * Return whether this request has been sent over a secure transport 131 * mechanism (such as SSL). 132 * @see javax.servlet.http.HttpServletRequest#isSecure() 133 */ 134 boolean isSecure(); 135 136 /** 137 * Check whether the requested resource has been modified given the 138 * supplied last-modified timestamp (as determined by the application). 139 * <p>This will also transparently set the "Last-Modified" response header 140 * and HTTP status when applicable. 141 * <p>Typical usage: 142 * <pre class="code"> 143 * public String myHandleMethod(WebRequest request, Model model) { 144 * long lastModified = // application-specific calculation 145 * if (request.checkNotModified(lastModified)) { 146 * // shortcut exit - no further processing necessary 147 * return null; 148 * } 149 * // further request processing, actually building content 150 * model.addAttribute(...); 151 * return "myViewName"; 152 * }</pre> 153 * <p>This method works with conditional GET/HEAD requests, but 154 * also with conditional POST/PUT/DELETE requests. 155 * <p><strong>Note:</strong> you can use either 156 * this {@code #checkNotModified(long)} method; or 157 * {@link #checkNotModified(String)}. If you want enforce both 158 * a strong entity tag and a Last-Modified value, 159 * as recommended by the HTTP specification, 160 * then you should use {@link #checkNotModified(String, long)}. 161 * <p>If the "If-Modified-Since" header is set but cannot be parsed 162 * to a date value, this method will ignore the header and proceed 163 * with setting the last-modified timestamp on the response. 164 * @param lastModifiedTimestamp the last-modified timestamp in 165 * milliseconds that the application determined for the underlying 166 * resource 167 * @return whether the request qualifies as not modified, 168 * allowing to abort request processing and relying on the response 169 * telling the client that the content has not been modified 170 */ 171 boolean checkNotModified(long lastModifiedTimestamp); 172 173 /** 174 * Check whether the requested resource has been modified given the 175 * supplied {@code ETag} (entity tag), as determined by the application. 176 * <p>This will also transparently set the "ETag" response header 177 * and HTTP status when applicable. 178 * <p>Typical usage: 179 * <pre class="code"> 180 * public String myHandleMethod(WebRequest request, Model model) { 181 * String eTag = // application-specific calculation 182 * if (request.checkNotModified(eTag)) { 183 * // shortcut exit - no further processing necessary 184 * return null; 185 * } 186 * // further request processing, actually building content 187 * model.addAttribute(...); 188 * return "myViewName"; 189 * }</pre> 190 * <p><strong>Note:</strong> you can use either 191 * this {@code #checkNotModified(String)} method; or 192 * {@link #checkNotModified(long)}. If you want enforce both 193 * a strong entity tag and a Last-Modified value, 194 * as recommended by the HTTP specification, 195 * then you should use {@link #checkNotModified(String, long)}. 196 * @param etag the entity tag that the application determined 197 * for the underlying resource. This parameter will be padded 198 * with quotes (") if necessary. 199 * @return true if the request does not require further processing. 200 */ 201 boolean checkNotModified(String etag); 202 203 /** 204 * Check whether the requested resource has been modified given the 205 * supplied {@code ETag} (entity tag) and last-modified timestamp, 206 * as determined by the application. 207 * <p>This will also transparently set the "ETag" and "Last-Modified" 208 * response headers, and HTTP status when applicable. 209 * <p>Typical usage: 210 * <pre class="code"> 211 * public String myHandleMethod(WebRequest request, Model model) { 212 * String eTag = // application-specific calculation 213 * long lastModified = // application-specific calculation 214 * if (request.checkNotModified(eTag, lastModified)) { 215 * // shortcut exit - no further processing necessary 216 * return null; 217 * } 218 * // further request processing, actually building content 219 * model.addAttribute(...); 220 * return "myViewName"; 221 * }</pre> 222 * <p>This method works with conditional GET/HEAD requests, but 223 * also with conditional POST/PUT/DELETE requests. 224 * <p><strong>Note:</strong> The HTTP specification recommends 225 * setting both ETag and Last-Modified values, but you can also 226 * use {@code #checkNotModified(String)} or 227 * {@link #checkNotModified(long)}. 228 * @param etag the entity tag that the application determined 229 * for the underlying resource. This parameter will be padded 230 * with quotes (") if necessary. 231 * @param lastModifiedTimestamp the last-modified timestamp in 232 * milliseconds that the application determined for the underlying 233 * resource 234 * @return true if the request does not require further processing. 235 * @since 4.2 236 */ 237 boolean checkNotModified(@Nullable String etag, long lastModifiedTimestamp); 238 239 /** 240 * Get a short description of this request, 241 * typically containing request URI and session id. 242 * @param includeClientInfo whether to include client-specific 243 * information such as session id and user name 244 * @return the requested description as String 245 */ 246 String getDescription(boolean includeClientInfo); 247 248}