added check for WebSphere's compliance mode (SPR-7064)

This commit is contained in:
Juergen Hoeller 2010-04-21 18:42:59 +00:00
parent c5f83686d2
commit 3dbe38e418
2 changed files with 56 additions and 15 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.web.util;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.Properties;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
@ -47,8 +48,10 @@ public class UrlPathHelper {
*/ */
private static final String WEBSPHERE_URI_ATTRIBUTE = "com.ibm.websphere.servlet.uri_non_decoded"; private static final String WEBSPHERE_URI_ATTRIBUTE = "com.ibm.websphere.servlet.uri_non_decoded";
private static final Log logger = LogFactory.getLog(UrlPathHelper.class);
static volatile Boolean websphereComplianceFlag;
private final Log logger = LogFactory.getLog(getClass());
private boolean alwaysUseFullPath = false; private boolean alwaysUseFullPath = false;
@ -234,9 +237,10 @@ public class UrlPathHelper {
servletPath = request.getServletPath(); servletPath = request.getServletPath();
} }
if (servletPath.length() > 1 && servletPath.endsWith("/") && if (servletPath.length() > 1 && servletPath.endsWith("/") &&
request.getAttribute(WEBSPHERE_URI_ATTRIBUTE) != null) { shouldRemoveTrailingServletPathSlash(request)) {
// On WebSphere, for a "/foo/" case that would be "/foo" on all other servlet containers: // On WebSphere, in non-compliant mode, for a "/foo/" case that would be "/foo"
// removing trailing slash, proceeding with that slash as final path mapping... // on all other servlet containers: removing trailing slash, proceeding with
// that remaining slash as final lookup path...
servletPath = servletPath.substring(0, servletPath.length() - 1); servletPath = servletPath.substring(0, servletPath.length() - 1);
} }
return servletPath; return servletPath;
@ -347,4 +351,35 @@ public class UrlPathHelper {
return enc; return enc;
} }
private boolean shouldRemoveTrailingServletPathSlash(HttpServletRequest request) {
if (request.getAttribute(WEBSPHERE_URI_ATTRIBUTE) == null) {
// Regular servlet container: behaves as expected in any case,
// so the trailing slash is the result of a "/" url-pattern mapping.
// Don't remove that slash.
return false;
}
if (websphereComplianceFlag == null) {
ClassLoader classLoader = UrlPathHelper.class.getClassLoader();
String className = "com.ibm.ws.webcontainer.WebContainer";
String methodName = "getWebContainerProperties";
String propName = "com.ibm.ws.webcontainer.removetrailingservletpathslash";
boolean flag = false;
try {
Class<?> cl = classLoader.loadClass(className);
Properties prop = (Properties) cl.getMethod(methodName).invoke(null);
flag = Boolean.parseBoolean(prop.getProperty(propName));
}
catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not introspect WebSphere web container properties: " + ex);
}
}
websphereComplianceFlag = flag;
}
// Don't bother if WebSphere is configured to be fully Servlet compliant.
// However, if it is not compliant, do remove the improper trailing slash!
return !websphereComplianceFlag;
}
} }

View File

@ -16,10 +16,11 @@
package org.springframework.web.util; package org.springframework.web.util;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.*;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
/** /**
@ -146,12 +147,11 @@ public class UrlPathHelperTests {
} }
@Test @Test
public void tomcatDefaultServletFileWithCompliantSetting() throws Exception { public void wasDefaultServletFileWithCompliantSetting() throws Exception {
request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo"); request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo");
tomcatDefaultServletFile(); tomcatDefaultServletFile();
} }
@Test @Test
public void wasDefaultServletFolder() throws Exception { public void wasDefaultServletFolder() throws Exception {
request.setContextPath("/test"); request.setContextPath("/test");
@ -163,10 +163,16 @@ public class UrlPathHelperTests {
assertEquals("/foo/", helper.getLookupPathForRequest(request)); assertEquals("/foo/", helper.getLookupPathForRequest(request));
} }
// @Test @Test
public void wasDefaultServletFolderWithCompliantSetting() throws Exception { public void wasDefaultServletFolderWithCompliantSetting() throws Exception {
request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo/"); UrlPathHelper.websphereComplianceFlag = true;
tomcatDefaultServletFolder(); try {
request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo/");
tomcatDefaultServletFolder();
}
finally {
UrlPathHelper.websphereComplianceFlag = false;
}
} }
@ -185,7 +191,7 @@ public class UrlPathHelperTests {
} }
// test the root mapping for /foo/* w/o a trailing slash - <host>/<context>/foo // test the root mapping for /foo/* w/o a trailing slash - <host>/<context>/foo
// @Test @Test @Ignore
public void tomcatCasualServletRootWithMissingSlash() throws Exception { public void tomcatCasualServletRootWithMissingSlash() throws Exception {
request.setContextPath("/test"); request.setContextPath("/test");
request.setPathInfo(null); request.setPathInfo(null);
@ -226,14 +232,14 @@ public class UrlPathHelperTests {
assertEquals("/", helper.getLookupPathForRequest(request)); assertEquals("/", helper.getLookupPathForRequest(request));
} }
// @Test @Test
public void wasCasualServletRootWithCompliantSetting() throws Exception { public void wasCasualServletRootWithCompliantSetting() throws Exception {
request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo/"); request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo/");
tomcatCasualServletRoot(); tomcatCasualServletRoot();
} }
// test the root mapping for /foo/* w/o a trailing slash - <host>/<context>/foo // test the root mapping for /foo/* w/o a trailing slash - <host>/<context>/foo
// @Test @Test @Ignore
public void wasCasualServletRootWithMissingSlash() throws Exception { public void wasCasualServletRootWithMissingSlash() throws Exception {
request.setContextPath("/test"); request.setContextPath("/test");
request.setPathInfo(null); request.setPathInfo(null);
@ -244,7 +250,7 @@ public class UrlPathHelperTests {
assertEquals("/", helper.getLookupPathForRequest(request)); assertEquals("/", helper.getLookupPathForRequest(request));
} }
// @Test @Test @Ignore
public void wasCasualServletRootWithMissingSlashWithCompliantSetting() throws Exception { public void wasCasualServletRootWithMissingSlashWithCompliantSetting() throws Exception {
request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo"); request.setAttribute(WEBSPHERE_URI_ATTRIBUTE, "/test/foo");
tomcatCasualServletRootWithMissingSlash(); tomcatCasualServletRootWithMissingSlash();