Proper resolution of Tomcat war URL

Issue: SPR-15485
(cherry picked from commit d43dfc7)
This commit is contained in:
Juergen Hoeller 2017-05-03 21:58:59 +02:00
parent beac891ff0
commit d2985613d1
3 changed files with 27 additions and 20 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.core.io;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
@ -89,11 +90,11 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
try {
URL url = getURL();
if (ResourceUtils.isFileURL(url)) {
// Proceed with file system resolution...
// Proceed with file system resolution
return getFile().exists();
}
else {
// Try a URL connection content-length header...
// Try a URL connection content-length header
URLConnection con = url.openConnection();
customizeConnection(con);
HttpURLConnection httpCon =
@ -133,7 +134,7 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
try {
URL url = getURL();
if (ResourceUtils.isFileURL(url)) {
// Proceed with file system resolution...
// Proceed with file system resolution
File file = getFile();
return (file.canRead() && !file.isDirectory());
}
@ -150,11 +151,11 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
public long contentLength() throws IOException {
URL url = getURL();
if (ResourceUtils.isFileURL(url)) {
// Proceed with file system resolution...
// Proceed with file system resolution
return getFile().length();
}
else {
// Try a URL connection content-length header...
// Try a URL connection content-length header
URLConnection con = url.openConnection();
customizeConnection(con);
return con.getContentLength();
@ -165,15 +166,18 @@ public abstract class AbstractFileResolvingResource extends AbstractResource {
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();
customizeConnection(con);
return con.getLastModified();
// Proceed with file system resolution
try {
return super.lastModified();
}
catch (FileNotFoundException ex) {
// Defensively fall back to URL connection check instead
}
}
// Try a URL connection last-modified header
URLConnection con = url.openConnection();
customizeConnection(con);
return con.getLastModified();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -119,7 +119,6 @@ public abstract class AbstractResource implements Resource {
* content length. Subclasses will almost always be able to provide
* a more optimal version of this, e.g. checking a File length.
* @see #getInputStream()
* @throws IllegalStateException if {@link #getInputStream()} returns null.
*/
@Override
public long contentLength() throws IOException {
@ -162,8 +161,9 @@ public abstract class AbstractResource implements Resource {
* Determine the File to use for timestamp checking.
* <p>The default implementation delegates to {@link #getFile()}.
* @return the File to use for timestamp checking (never {@code null})
* @throws IOException if the resource cannot be resolved as absolute
* file path, i.e. if the resource is not available in a file system
* @throws FileNotFoundException if the resource cannot be resolved as
* an absolute file path, i.e. is not available in a file system
* @throws IOException in case of general resolution/reading failures
*/
protected File getFileForLastModifiedCheck() throws IOException {
return getFile();

View File

@ -583,10 +583,13 @@ public class PathMatchingResourcePatternResolver implements ResourcePatternResol
// We'll also handle paths with and without leading "file:" prefix.
String urlFile = rootDirURL.getFile();
try {
int separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
int separatorIndex = urlFile.indexOf(ResourceUtils.WAR_URL_SEPARATOR);
if (separatorIndex == -1) {
separatorIndex = urlFile.indexOf(ResourceUtils.JAR_URL_SEPARATOR);
}
if (separatorIndex != -1) {
jarFileUrl = urlFile.substring(0, separatorIndex);
rootEntryPath = urlFile.substring(separatorIndex + ResourceUtils.JAR_URL_SEPARATOR.length());
rootEntryPath = urlFile.substring(separatorIndex + 2); // both separators are 2 chars
jarFile = getJarFile(jarFileUrl);
}
else {