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}