1 /*
2  * Copyright 2002-2011 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.web.context.request;
18 
19 import java.security.Principal;
20 import java.util.Iterator;
21 import java.util.Locale;
22 import java.util.Map;
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25 import javax.servlet.http.HttpSession;
26 
27 import org.springframework.util.CollectionUtils;
28 import org.springframework.util.ObjectUtils;
29 import org.springframework.util.StringUtils;
30 import org.springframework.web.util.WebUtils;
31 
32 /**
33  * {@link WebRequest} adapter for an {@link javax.servlet.http.HttpServletRequest}.
34  *
35  * @author Juergen Hoeller
36  * @since 2.0
37  */
38 public class ServletWebRequest extends ServletRequestAttributes implements NativeWebRequest {
39 
40 	private static final String HEADER_ETAG = "ETag";
41 
42 	private static final String HEADER_IF_MODIFIED_SINCE = "If-Modified-Since";
43 
44 	private static final String HEADER_IF_NONE_MATCH = "If-None-Match";
45 
46 	private static final String HEADER_LAST_MODIFIED = "Last-Modified";
47 
48 	private static final String METHOD_GET = "GET";
49 
50 
51 	private HttpServletResponse response;
52 
53 	private boolean notModified = false;
54 
55 
56 	/**
57 	 * Create a new ServletWebRequest instance for the given request.
58 	 * @param request current HTTP request
59 	 */
ServletWebRequest(HttpServletRequest request)60 	public ServletWebRequest(HttpServletRequest request) {
61 		super(request);
62 	}
63 
64 	/**
65 	 * Create a new ServletWebRequest instance for the given request/response pair.
66 	 * @param request current HTTP request
67 	 * @param response current HTTP response (for automatic last-modified handling)
68 	 */
ServletWebRequest(HttpServletRequest request, HttpServletResponse response)69 	public ServletWebRequest(HttpServletRequest request, HttpServletResponse response) {
70 		this(request);
71 		this.response = response;
72 	}
73 
74 
75 	/**
76 	 * Exposes the native {@link HttpServletRequest} that we're wrapping (if any).
77 	 */
getResponse()78 	public final HttpServletResponse getResponse() {
79 		return this.response;
80 	}
81 
getNativeRequest()82 	public Object getNativeRequest() {
83 		return getRequest();
84 	}
85 
getNativeResponse()86 	public Object getNativeResponse() {
87 		return getResponse();
88 	}
89 
90 	@SuppressWarnings("unchecked")
getNativeRequest(Class<T> requiredType)91 	public <T> T getNativeRequest(Class<T> requiredType) {
92 		return WebUtils.getNativeRequest(getRequest(), requiredType);
93 	}
94 
95 	@SuppressWarnings("unchecked")
getNativeResponse(Class<T> requiredType)96 	public <T> T getNativeResponse(Class<T> requiredType) {
97 		return WebUtils.getNativeResponse(getResponse(), requiredType);
98 	}
99 
100 
getHeader(String headerName)101 	public String getHeader(String headerName) {
102 		return getRequest().getHeader(headerName);
103 	}
104 
105 	@SuppressWarnings("unchecked")
getHeaderValues(String headerName)106 	public String[] getHeaderValues(String headerName) {
107 		String[] headerValues = StringUtils.toStringArray(getRequest().getHeaders(headerName));
108 		return (!ObjectUtils.isEmpty(headerValues) ? headerValues : null);
109 	}
110 
111 	@SuppressWarnings("unchecked")
getHeaderNames()112 	public Iterator<String> getHeaderNames() {
113 		return CollectionUtils.toIterator(getRequest().getHeaderNames());
114 	}
115 
getParameter(String paramName)116 	public String getParameter(String paramName) {
117 		return getRequest().getParameter(paramName);
118 	}
119 
getParameterValues(String paramName)120 	public String[] getParameterValues(String paramName) {
121 		return getRequest().getParameterValues(paramName);
122 	}
123 
124 	@SuppressWarnings("unchecked")
getParameterNames()125 	public Iterator<String> getParameterNames() {
126 		return CollectionUtils.toIterator(getRequest().getParameterNames());
127 	}
128 
129 	@SuppressWarnings("unchecked")
getParameterMap()130 	public Map<String, String[]> getParameterMap() {
131 		return getRequest().getParameterMap();
132 	}
133 
getLocale()134 	public Locale getLocale() {
135 		return getRequest().getLocale();
136 	}
137 
getContextPath()138 	public String getContextPath() {
139 		return getRequest().getContextPath();
140 	}
141 
getRemoteUser()142 	public String getRemoteUser() {
143 		return getRequest().getRemoteUser();
144 	}
145 
getUserPrincipal()146 	public Principal getUserPrincipal() {
147 		return getRequest().getUserPrincipal();
148 	}
149 
isUserInRole(String role)150 	public boolean isUserInRole(String role) {
151 		return getRequest().isUserInRole(role);
152 	}
153 
isSecure()154 	public boolean isSecure() {
155 		return getRequest().isSecure();
156 	}
157 
checkNotModified(long lastModifiedTimestamp)158 	public boolean checkNotModified(long lastModifiedTimestamp) {
159 		if (lastModifiedTimestamp >= 0 && !this.notModified &&
160 				(this.response == null || !this.response.containsHeader(HEADER_LAST_MODIFIED))) {
161 			long ifModifiedSince = getRequest().getDateHeader(HEADER_IF_MODIFIED_SINCE);
162 			this.notModified = (ifModifiedSince >= (lastModifiedTimestamp / 1000 * 1000));
163 			if (this.response != null) {
164 				if (this.notModified && METHOD_GET.equals(getRequest().getMethod())) {
165 					this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
166 				}
167 				else {
168 					this.response.setDateHeader(HEADER_LAST_MODIFIED, lastModifiedTimestamp);
169 				}
170 			}
171 		}
172 		return this.notModified;
173 	}
174 
checkNotModified(String eTag)175 	public boolean checkNotModified(String eTag) {
176 		if (StringUtils.hasLength(eTag) && !this.notModified &&
177 				(this.response == null || !this.response.containsHeader(HEADER_ETAG))) {
178 			String ifNoneMatch = getRequest().getHeader(HEADER_IF_NONE_MATCH);
179 			this.notModified = eTag.equals(ifNoneMatch);
180 			if (this.response != null) {
181 				if (this.notModified && METHOD_GET.equals(getRequest().getMethod())) {
182 					this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
183 				}
184 				else {
185 					this.response.setHeader(HEADER_ETAG, eTag);
186 				}
187 			}
188 		}
189 		return this.notModified;
190 
191 	}
192 
isNotModified()193 	public boolean isNotModified() {
194 		return this.notModified;
195 	}
196 
getDescription(boolean includeClientInfo)197 	public String getDescription(boolean includeClientInfo) {
198 		HttpServletRequest request = getRequest();
199 		StringBuilder sb = new StringBuilder();
200 		sb.append("uri=").append(request.getRequestURI());
201 		if (includeClientInfo) {
202 			String client = request.getRemoteAddr();
203 			if (StringUtils.hasLength(client)) {
204 				sb.append(";client=").append(client);
205 			}
206 			HttpSession session = request.getSession(false);
207 			if (session != null) {
208 				sb.append(";session=").append(session.getId());
209 			}
210 			String user = request.getRemoteUser();
211 			if (StringUtils.hasLength(user)) {
212 				sb.append(";user=").append(user);
213 			}
214 		}
215 		return sb.toString();
216 	}
217 
218 
219 	@Override
toString()220 	public String toString() {
221 		return "ServletWebRequest: " + getDescription(true);
222 	}
223 
224 }
225