1 16 17 package org.springframework.web.servlet; 18 19 import java.io.File ; 20 import java.io.IOException ; 21 22 import javax.servlet.RequestDispatcher ; 23 import javax.servlet.ServletException ; 24 import javax.servlet.http.HttpServletRequest ; 25 import javax.servlet.http.HttpServletResponse ; 26 27 import org.springframework.util.AntPathMatcher; 28 import org.springframework.util.PathMatcher; 29 import org.springframework.util.StringUtils; 30 import org.springframework.web.context.support.ServletContextResource; 31 32 92 public class ResourceServlet extends HttpServletBean { 93 94 98 public static final String RESOURCE_URL_DELIMITERS = ",; \t\n"; 99 100 103 public static final String RESOURCE_PARAM_NAME = "resource"; 104 105 106 private String defaultUrl; 107 108 private String allowedResources; 109 110 private String contentType; 111 112 private boolean applyLastModified = false; 113 114 private PathMatcher pathMatcher; 115 116 private long startupTime; 117 118 119 128 public void setDefaultUrl(String defaultUrl) { 129 this.defaultUrl = defaultUrl; 130 } 131 132 137 public void setAllowedResources(String allowedResources) { 138 this.allowedResources = allowedResources; 139 } 140 141 149 public void setContentType(String contentType) { 150 this.contentType = contentType; 151 } 152 153 164 public void setApplyLastModified(boolean applyLastModified) { 165 this.applyLastModified = applyLastModified; 166 } 167 168 169 172 protected void initServletBean() { 173 this.pathMatcher = getPathMatcher(); 174 this.startupTime = System.currentTimeMillis(); 175 } 176 177 183 protected PathMatcher getPathMatcher() { 184 return new AntPathMatcher(); 185 } 186 187 188 192 protected final void doGet(HttpServletRequest request, HttpServletResponse response) 193 throws ServletException , IOException { 194 195 String resourceUrl = determineResourceUrl(request); 197 198 if (resourceUrl != null) { 199 try { 200 doInclude(request, response, resourceUrl); 201 } 202 catch (ServletException ex) { 203 if (logger.isWarnEnabled()) { 204 logger.warn("Failed to include content of resource [" + resourceUrl + "]", ex); 205 } 206 if (!includeDefaultUrl(request, response)) { 208 throw ex; 209 } 210 } 211 catch (IOException ex) { 212 if (logger.isWarnEnabled()) { 213 logger.warn("Failed to include content of resource [" + resourceUrl + "]", ex); 214 } 215 if (!includeDefaultUrl(request, response)) { 217 throw ex; 218 } 219 } 220 } 221 222 else if (!includeDefaultUrl(request, response)) { 224 throw new ServletException ("No target resource URL found for request"); 225 } 226 } 227 228 236 protected String determineResourceUrl(HttpServletRequest request) { 237 return request.getParameter(RESOURCE_PARAM_NAME); 238 } 239 240 248 private boolean includeDefaultUrl(HttpServletRequest request, HttpServletResponse response) 249 throws ServletException , IOException { 250 if (this.defaultUrl == null) { 251 return false; 252 } 253 doInclude(request, response, this.defaultUrl); 254 return true; 255 } 256 257 265 private void doInclude(HttpServletRequest request, HttpServletResponse response, String resourceUrl) 266 throws ServletException , IOException { 267 268 if (this.contentType != null) { 269 response.setContentType(this.contentType); 270 } 271 String [] resourceUrls = 272 StringUtils.tokenizeToStringArray(resourceUrl, RESOURCE_URL_DELIMITERS); 273 for (int i = 0; i < resourceUrls.length; i++) { 274 if (this.allowedResources != null && !this.pathMatcher.match(this.allowedResources, resourceUrls[i])) { 276 throw new ServletException ("Resource [" + resourceUrls[i] + 277 "] does not match allowed pattern [" + this.allowedResources + "]"); 278 } 279 if (logger.isDebugEnabled()) { 280 logger.debug("Including resource [" + resourceUrls[i] + "]"); 281 } 282 RequestDispatcher rd = request.getRequestDispatcher(resourceUrls[i]); 283 rd.include(request, response); 284 } 285 } 286 287 300 protected final long getLastModified(HttpServletRequest request) { 301 if (this.applyLastModified) { 302 String resourceUrl = determineResourceUrl(request); 303 if (resourceUrl == null) { 304 resourceUrl = this.defaultUrl; 305 } 306 if (resourceUrl != null) { 307 String [] resourceUrls = StringUtils.tokenizeToStringArray(resourceUrl, RESOURCE_URL_DELIMITERS); 308 long latestTimestamp = -1; 309 for (int i = 0; i < resourceUrls.length; i++) { 310 long timestamp = getFileTimestamp(resourceUrls[i]); 311 if (timestamp > latestTimestamp) { 312 latestTimestamp = timestamp; 313 } 314 } 315 return (latestTimestamp > this.startupTime ? latestTimestamp : this.startupTime); 316 } 317 } 318 return -1; 319 } 320 321 327 protected long getFileTimestamp(String resourceUrl) { 328 try { 329 File resource = new ServletContextResource(getServletContext(), resourceUrl).getFile(); 330 long lastModifiedTime = resource.lastModified(); 331 if (logger.isDebugEnabled()) { 332 logger.debug("Last-modified timestamp of resource file [" + resource.getAbsolutePath() + 333 "] is [" + lastModifiedTime + "]"); 334 } 335 return lastModifiedTime; 336 } 337 catch (IOException ex) { 338 logger.warn("Couldn't retrieve lastModified timestamp of resource [" + resourceUrl + 339 "] - returning ResourceServlet startup time"); 340 return -1; 341 } 342 } 343 344 } 345 | Popular Tags |