added "contentLength()" method to Resource abstraction; URL-based Resource variants introspect "last-modified" and "content-length" response headers (SPR-5465); refined "exists()" check for UrlResource (HEAD request) and ClassPathResource (URL resolution)
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@3545 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
69b608bb2b
commit
c3a8a4933a
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -18,8 +18,10 @@ package org.springframework.core.io;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
|
||||||
import org.springframework.util.ResourceUtils;
|
import org.springframework.util.ResourceUtils;
|
||||||
|
|
||||||
|
|
@ -81,6 +83,70 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean exists() {
|
||||||
|
try {
|
||||||
|
URL url = getURL();
|
||||||
|
if (ResourceUtils.isFileURL(url)) {
|
||||||
|
// Proceed with file system resolution...
|
||||||
|
return getFile().exists();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Try a URL connection content-length header...
|
||||||
|
URLConnection con = url.openConnection();
|
||||||
|
con.setUseCaches(false);
|
||||||
|
if (con instanceof HttpURLConnection) {
|
||||||
|
((HttpURLConnection) con).setRequestMethod("HEAD");
|
||||||
|
}
|
||||||
|
boolean doesExist = (con.getContentLength() >= 0);
|
||||||
|
if (!doesExist && con instanceof HttpURLConnection) {
|
||||||
|
((HttpURLConnection) con).disconnect();
|
||||||
|
}
|
||||||
|
return doesExist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int contentLength() throws IOException {
|
||||||
|
URL url = getURL();
|
||||||
|
if (ResourceUtils.isFileURL(url)) {
|
||||||
|
// Proceed with file system resolution...
|
||||||
|
return super.contentLength();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Try a URL connection content-length header...
|
||||||
|
URLConnection con = url.openConnection();
|
||||||
|
con.setUseCaches(false);
|
||||||
|
if (con instanceof HttpURLConnection) {
|
||||||
|
((HttpURLConnection) con).setRequestMethod("HEAD");
|
||||||
|
}
|
||||||
|
return con.getContentLength();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long lastModified() throws IOException {
|
||||||
|
URL url = getURL();
|
||||||
|
if (ResourceUtils.isFileURL(url) || ResourceUtils.isJarURL(url)) {
|
||||||
|
// Proceed with file system resolution...
|
||||||
|
return super.lastModified();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Try a URL connection last-modified header...
|
||||||
|
URLConnection con = url.openConnection();
|
||||||
|
con.setUseCaches(false);
|
||||||
|
if (con instanceof HttpURLConnection) {
|
||||||
|
((HttpURLConnection) con).setRequestMethod("HEAD");
|
||||||
|
}
|
||||||
|
return con.getLastModified();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime.
|
* Inner delegate class, avoiding a hard JBoss VFS API dependency at runtime.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -107,6 +107,15 @@ public abstract class AbstractResource implements Resource {
|
||||||
throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");
|
throw new FileNotFoundException(getDescription() + " cannot be resolved to absolute file path");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implementation checks the timestamp of the underlying File,
|
||||||
|
* if available.
|
||||||
|
* @see #getFile()
|
||||||
|
*/
|
||||||
|
public int contentLength() throws IOException {
|
||||||
|
return (int) getFile().length();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation checks the timestamp of the underlying File,
|
* This implementation checks the timestamp of the underlying File,
|
||||||
* if available.
|
* if available.
|
||||||
|
|
@ -142,10 +151,10 @@ public abstract class AbstractResource implements Resource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation always throws IllegalStateException,
|
* This implementation always throws IllegalStateException,
|
||||||
* assuming that the resource does not carry a filename.
|
* assuming that the resource does not have a filename.
|
||||||
*/
|
*/
|
||||||
public String getFilename() throws IllegalStateException {
|
public String getFilename() throws IllegalStateException {
|
||||||
throw new IllegalStateException(getDescription() + " does not carry a filename");
|
throw new IllegalStateException(getDescription() + " does not have a filename");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,23 @@ public class ClassPathResource extends AbstractFileResolvingResource {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implementation checks for the resolution of a resource URL.
|
||||||
|
* @see java.lang.ClassLoader#getResource(String)
|
||||||
|
* @see java.lang.Class#getResource(String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean exists() {
|
||||||
|
URL url;
|
||||||
|
if (this.clazz != null) {
|
||||||
|
url = this.clazz.getResource(this.path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url = this.classLoader.getResource(this.path);
|
||||||
|
}
|
||||||
|
return (url != null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This implementation opens an InputStream for the given class path resource.
|
* This implementation opens an InputStream for the given class path resource.
|
||||||
* @see java.lang.ClassLoader#getResourceAsStream(String)
|
* @see java.lang.ClassLoader#getResourceAsStream(String)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -91,6 +91,13 @@ public interface Resource extends InputStreamSource {
|
||||||
*/
|
*/
|
||||||
File getFile() throws IOException;
|
File getFile() throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine the content length for this resource.
|
||||||
|
* @throws IOException if the resource cannot be resolved
|
||||||
|
* (in the file system or as some other known physical resource type)
|
||||||
|
*/
|
||||||
|
int contentLength() throws IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine the last-modified timestamp for this resource.
|
* Determine the last-modified timestamp for this resource.
|
||||||
* @throws IOException if the resource cannot be resolved
|
* @throws IOException if the resource cannot be resolved
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2010 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -246,6 +246,17 @@ public abstract class ResourceUtils {
|
||||||
return new File(resourceUri.getSchemeSpecificPart());
|
return new File(resourceUri.getSchemeSpecificPart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given URL points to a resource in the file system,
|
||||||
|
* that is, has protocol "file" or "vfs".
|
||||||
|
* @param url the URL to check
|
||||||
|
* @return whether the URL has been identified as a file system URL
|
||||||
|
*/
|
||||||
|
public static boolean isFileURL(URL url) {
|
||||||
|
String protocol = url.getProtocol();
|
||||||
|
return (URL_PROTOCOL_FILE.equals(protocol) || protocol.startsWith(URL_PROTOCOL_VFS));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine whether the given URL points to a resource in a jar file,
|
* Determine whether the given URL points to a resource in a jar file,
|
||||||
* that is, has protocol "jar", "zip", "wsjar" or "code-source".
|
* that is, has protocol "jar", "zip", "wsjar" or "code-source".
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue