Polishing
This commit is contained in:
parent
ba5ef6456f
commit
c1405ef140
|
|
@ -38,7 +38,7 @@ import org.springframework.expression.spel.support.ReflectionHelper.ArgumentsMat
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests for any helper code.
|
||||
* Tests for reflection helper code.
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
|
|
@ -46,23 +46,14 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
|
|||
|
||||
@Test
|
||||
public void testFormatHelperForClassName() {
|
||||
assertEquals("java.lang.String",FormatHelper.formatClassNameForMessage(String.class));
|
||||
assertEquals("java.lang.String[]",FormatHelper.formatClassNameForMessage(new String[1].getClass()));
|
||||
assertEquals("java.lang.String[][]",FormatHelper.formatClassNameForMessage(new String[1][1].getClass()));
|
||||
assertEquals("int[]",FormatHelper.formatClassNameForMessage(new int[1].getClass()));
|
||||
assertEquals("int[][]",FormatHelper.formatClassNameForMessage(new int[1][2].getClass()));
|
||||
assertEquals("null",FormatHelper.formatClassNameForMessage(null));
|
||||
assertEquals("java.lang.String", FormatHelper.formatClassNameForMessage(String.class));
|
||||
assertEquals("java.lang.String[]", FormatHelper.formatClassNameForMessage(String[].class));
|
||||
assertEquals("java.lang.String[][]", FormatHelper.formatClassNameForMessage(String[][].class));
|
||||
assertEquals("int[]", FormatHelper.formatClassNameForMessage(int[].class));
|
||||
assertEquals("int[][]", FormatHelper.formatClassNameForMessage(int[][].class));
|
||||
assertEquals("null", FormatHelper.formatClassNameForMessage(null));
|
||||
}
|
||||
|
||||
/*
|
||||
@Test
|
||||
public void testFormatHelperForMethod() {
|
||||
assertEquals("foo(java.lang.String)",FormatHelper.formatMethodForMessage("foo", String.class));
|
||||
assertEquals("goo(java.lang.String,int[])",FormatHelper.formatMethodForMessage("goo", String.class, new int[1].getClass()));
|
||||
assertEquals("boo()",FormatHelper.formatMethodForMessage("boo"));
|
||||
}
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testUtilities() throws ParseException {
|
||||
SpelExpression expr = (SpelExpression)parser.parseExpression("3+4+5+6+7-2");
|
||||
|
|
@ -159,47 +150,45 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
|
|||
StandardTypeConverter typeConverter = new StandardTypeConverter();
|
||||
|
||||
// Passing (Super,String) on call to foo(Sub,String) is not a match
|
||||
checkMatch(new Class<?>[] {Super.class,String.class}, new Class<?>[] {Sub.class,String.class},typeConverter,null);
|
||||
checkMatch(new Class<?>[] {Super.class,String.class}, new Class<?>[] {Sub.class,String.class}, typeConverter, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReflectionHelperCompareArguments_Varargs_ExactMatching() {
|
||||
StandardTypeConverter tc = new StandardTypeConverter();
|
||||
Class<?> stringArrayClass = new String[0].getClass();
|
||||
Class<?> integerArrayClass = new Integer[0].getClass();
|
||||
|
||||
// Passing (String[]) on call to (String[]) is exact match
|
||||
checkMatch2(new Class<?>[] {stringArrayClass}, new Class<?>[] {stringArrayClass}, tc, ArgumentsMatchKind.EXACT);
|
||||
checkMatch2(new Class<?>[] {String[].class}, new Class<?>[] {String[].class}, tc, ArgumentsMatchKind.EXACT);
|
||||
|
||||
// Passing (Integer, String[]) on call to (Integer, String[]) is exact match
|
||||
checkMatch2(new Class<?>[] {Integer.class, stringArrayClass}, new Class<?>[] {Integer.class, stringArrayClass}, tc, ArgumentsMatchKind.EXACT);
|
||||
checkMatch2(new Class<?>[] {Integer.class, String[].class}, new Class<?>[] {Integer.class, String[].class}, tc, ArgumentsMatchKind.EXACT);
|
||||
|
||||
// Passing (String, Integer, String[]) on call to (String, String, String[]) is exact match
|
||||
checkMatch2(new Class<?>[] {String.class, Integer.class, stringArrayClass}, new Class<?>[] {String.class,Integer.class, stringArrayClass}, tc, ArgumentsMatchKind.EXACT);
|
||||
checkMatch2(new Class<?>[] {String.class, Integer.class, String[].class}, new Class<?>[] {String.class,Integer.class, String[].class}, tc, ArgumentsMatchKind.EXACT);
|
||||
|
||||
// Passing (Sub, String[]) on call to (Super, String[]) is exact match
|
||||
checkMatch2(new Class<?>[] {Sub.class, stringArrayClass}, new Class<?>[] {Super.class,stringArrayClass}, tc, ArgumentsMatchKind.CLOSE);
|
||||
checkMatch2(new Class<?>[] {Sub.class, String[].class}, new Class<?>[] {Super.class,String[].class}, tc, ArgumentsMatchKind.CLOSE);
|
||||
|
||||
// Passing (Integer, String[]) on call to (String, String[]) is exact match
|
||||
checkMatch2(new Class<?>[] {Integer.class, stringArrayClass}, new Class<?>[] {String.class, stringArrayClass}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION);
|
||||
checkMatch2(new Class<?>[] {Integer.class, String[].class}, new Class<?>[] {String.class, String[].class}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION);
|
||||
|
||||
// Passing (Integer, Sub, String[]) on call to (String, Super, String[]) is exact match
|
||||
checkMatch2(new Class<?>[] {Integer.class, Sub.class, String[].class}, new Class<?>[] {String.class,Super .class, String[].class}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION);
|
||||
|
||||
// Passing (String) on call to (String[]) is exact match
|
||||
checkMatch2(new Class<?>[] {String.class}, new Class<?>[] {stringArrayClass}, tc, ArgumentsMatchKind.EXACT);
|
||||
checkMatch2(new Class<?>[] {String.class}, new Class<?>[] {String[].class}, tc, ArgumentsMatchKind.EXACT);
|
||||
|
||||
// Passing (Integer,String) on call to (Integer,String[]) is exact match
|
||||
checkMatch2(new Class<?>[] {Integer.class, String.class}, new Class<?>[] {Integer.class, stringArrayClass}, tc, ArgumentsMatchKind.EXACT);
|
||||
checkMatch2(new Class<?>[] {Integer.class, String.class}, new Class<?>[] {Integer.class, String[].class}, tc, ArgumentsMatchKind.EXACT);
|
||||
|
||||
// Passing (String) on call to (Integer[]) is conversion match (String to Integer)
|
||||
checkMatch2(new Class<?>[] {String.class}, new Class<?>[] {integerArrayClass}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION);
|
||||
checkMatch2(new Class<?>[] {String.class}, new Class<?>[] {Integer[].class}, tc, ArgumentsMatchKind.REQUIRES_CONVERSION);
|
||||
|
||||
// Passing (Sub) on call to (Super[]) is close match
|
||||
checkMatch2(new Class<?>[] {Sub.class}, new Class<?>[] {new Super[0].getClass()}, tc, ArgumentsMatchKind.CLOSE);
|
||||
checkMatch2(new Class<?>[] {Sub.class}, new Class<?>[] {Super[].class}, tc, ArgumentsMatchKind.CLOSE);
|
||||
|
||||
// Passing (Super) on call to (Sub[]) is not a match
|
||||
checkMatch2(new Class<?>[] {Super.class}, new Class<?>[] {new Sub[0].getClass()}, tc, null);
|
||||
checkMatch2(new Class<?>[] {Super.class}, new Class<?>[] {Sub[].class}, tc, null);
|
||||
|
||||
checkMatch2(new Class<?>[] {Unconvertable.class, String.class}, new Class<?>[] {Sub.class, Super[].class}, tc, null);
|
||||
|
||||
|
|
@ -234,12 +223,12 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
|
|||
// varargs with nothing needing conversion
|
||||
args = new Object[] {3, "abc", "abc"};
|
||||
ReflectionHelper.convertArguments(tc, args, twoArg, 1);
|
||||
checkArguments(args, "3","abc","abc");
|
||||
checkArguments(args, "3", "abc", "abc");
|
||||
|
||||
// varargs with conversion required
|
||||
args = new Object[] {3, false ,3.0d};
|
||||
ReflectionHelper.convertArguments(tc, args, twoArg, 1);
|
||||
checkArguments(args, "3","false","3.0");
|
||||
checkArguments(args, "3", "false", "3.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -251,33 +240,33 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
|
|||
// Simple conversion: int to string
|
||||
Object[] args = new Object[] {3};
|
||||
ReflectionHelper.convertAllArguments(tc, args, oneArg);
|
||||
checkArguments(args,"3");
|
||||
checkArguments(args, "3");
|
||||
|
||||
// varargs conversion
|
||||
args = new Object[] {3, false, 3.0f};
|
||||
ReflectionHelper.convertAllArguments(tc, args, twoArg);
|
||||
checkArguments(args,"3","false","3.0");
|
||||
checkArguments(args, "3", "false", "3.0");
|
||||
|
||||
// varargs conversion but no varargs
|
||||
args = new Object[] {3};
|
||||
ReflectionHelper.convertAllArguments(tc, args, twoArg);
|
||||
checkArguments(args,"3");
|
||||
checkArguments(args, "3");
|
||||
|
||||
// null value
|
||||
args = new Object[] {3, null, 3.0f};
|
||||
ReflectionHelper.convertAllArguments(tc, args, twoArg);
|
||||
checkArguments(args,"3",null,"3.0");
|
||||
checkArguments(args, "3", null, "3.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetupArguments() {
|
||||
Object[] newArray = ReflectionHelper.setupArgumentsForVarargsInvocation(
|
||||
new Class<?>[] {new String[0].getClass()},"a","b","c");
|
||||
new Class<?>[] {String[].class}, "a", "b", "c");
|
||||
|
||||
assertEquals(1, newArray.length);
|
||||
Object firstParam = newArray[0];
|
||||
assertEquals(String.class,firstParam.getClass().getComponentType());
|
||||
Object[] firstParamArray = (Object[])firstParam;
|
||||
Object[] firstParamArray = (Object[]) firstParam;
|
||||
assertEquals(3,firstParamArray.length);
|
||||
assertEquals("a",firstParamArray[0]);
|
||||
assertEquals("b",firstParamArray[1]);
|
||||
|
|
@ -285,75 +274,75 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testReflectivePropertyResolver() throws Exception {
|
||||
ReflectivePropertyAccessor rpr = new ReflectivePropertyAccessor();
|
||||
public void testReflectivePropertyAccessor() throws Exception {
|
||||
ReflectivePropertyAccessor rpa = new ReflectivePropertyAccessor();
|
||||
Tester t = new Tester();
|
||||
t.setProperty("hello");
|
||||
EvaluationContext ctx = new StandardEvaluationContext(t);
|
||||
assertTrue(rpr.canRead(ctx, t, "property"));
|
||||
assertEquals("hello",rpr.read(ctx, t, "property").getValue());
|
||||
assertEquals("hello",rpr.read(ctx, t, "property").getValue()); // cached accessor used
|
||||
assertTrue(rpa.canRead(ctx, t, "property"));
|
||||
assertEquals("hello",rpa.read(ctx, t, "property").getValue());
|
||||
assertEquals("hello",rpa.read(ctx, t, "property").getValue()); // cached accessor used
|
||||
|
||||
assertTrue(rpr.canRead(ctx, t, "field"));
|
||||
assertEquals(3,rpr.read(ctx, t, "field").getValue());
|
||||
assertEquals(3,rpr.read(ctx, t, "field").getValue()); // cached accessor used
|
||||
assertTrue(rpa.canRead(ctx, t, "field"));
|
||||
assertEquals(3,rpa.read(ctx, t, "field").getValue());
|
||||
assertEquals(3,rpa.read(ctx, t, "field").getValue()); // cached accessor used
|
||||
|
||||
assertTrue(rpr.canWrite(ctx, t, "property"));
|
||||
rpr.write(ctx, t, "property","goodbye");
|
||||
rpr.write(ctx, t, "property","goodbye"); // cached accessor used
|
||||
assertTrue(rpa.canWrite(ctx, t, "property"));
|
||||
rpa.write(ctx, t, "property", "goodbye");
|
||||
rpa.write(ctx, t, "property", "goodbye"); // cached accessor used
|
||||
|
||||
assertTrue(rpr.canWrite(ctx, t, "field"));
|
||||
rpr.write(ctx, t, "field",12);
|
||||
rpr.write(ctx, t, "field",12);
|
||||
assertTrue(rpa.canWrite(ctx, t, "field"));
|
||||
rpa.write(ctx, t, "field", 12);
|
||||
rpa.write(ctx, t, "field", 12);
|
||||
|
||||
// Attempted write as first activity on this field and property to drive testing
|
||||
// of populating type descriptor cache
|
||||
rpr.write(ctx,t,"field2",3);
|
||||
rpr.write(ctx, t, "property2","doodoo");
|
||||
assertEquals(3,rpr.read(ctx,t,"field2").getValue());
|
||||
rpa.write(ctx, t, "field2", 3);
|
||||
rpa.write(ctx, t, "property2", "doodoo");
|
||||
assertEquals(3,rpa.read(ctx, t, "field2").getValue());
|
||||
|
||||
// Attempted read as first activity on this field and property (no canRead before them)
|
||||
assertEquals(0,rpr.read(ctx,t,"field3").getValue());
|
||||
assertEquals("doodoo",rpr.read(ctx,t,"property3").getValue());
|
||||
assertEquals(0,rpa.read(ctx, t, "field3").getValue());
|
||||
assertEquals("doodoo",rpa.read(ctx, t, "property3").getValue());
|
||||
|
||||
// Access through is method
|
||||
// assertEquals(0,rpr.read(ctx,t,"field3").getValue());
|
||||
assertEquals(false,rpr.read(ctx,t,"property4").getValue());
|
||||
assertTrue(rpr.canRead(ctx,t,"property4"));
|
||||
assertEquals(0,rpa .read(ctx, t, "field3").getValue());
|
||||
assertEquals(false,rpa.read(ctx, t, "property4").getValue());
|
||||
assertTrue(rpa.canRead(ctx, t, "property4"));
|
||||
|
||||
// repro SPR-9123, ReflectivePropertyAccessor JavaBean property names compliance tests
|
||||
assertEquals("iD",rpr.read(ctx,t,"iD").getValue());
|
||||
assertTrue(rpr.canRead(ctx,t,"iD"));
|
||||
assertEquals("id",rpr.read(ctx,t,"id").getValue());
|
||||
assertTrue(rpr.canRead(ctx,t,"id"));
|
||||
assertEquals("ID",rpr.read(ctx,t,"ID").getValue());
|
||||
assertTrue(rpr.canRead(ctx,t,"ID"));
|
||||
assertEquals("iD",rpa.read(ctx, t, "iD").getValue());
|
||||
assertTrue(rpa.canRead(ctx, t, "iD"));
|
||||
assertEquals("id",rpa.read(ctx, t, "id").getValue());
|
||||
assertTrue(rpa.canRead(ctx, t, "id"));
|
||||
assertEquals("ID",rpa.read(ctx, t, "ID").getValue());
|
||||
assertTrue(rpa.canRead(ctx, t, "ID"));
|
||||
// note: "Id" is not a valid JavaBean name, nevertheless it is treated as "id"
|
||||
assertEquals("id",rpr.read(ctx,t,"Id").getValue());
|
||||
assertTrue(rpr.canRead(ctx,t,"Id"));
|
||||
assertEquals("id",rpa.read(ctx, t, "Id").getValue());
|
||||
assertTrue(rpa.canRead(ctx, t, "Id"));
|
||||
|
||||
// repro SPR-10994
|
||||
assertEquals("xyZ",rpr.read(ctx,t,"xyZ").getValue());
|
||||
assertTrue(rpr.canRead(ctx,t,"xyZ"));
|
||||
assertEquals("xY",rpr.read(ctx,t,"xY").getValue());
|
||||
assertTrue(rpr.canRead(ctx,t,"xY"));
|
||||
assertEquals("xyZ",rpa.read(ctx, t, "xyZ").getValue());
|
||||
assertTrue(rpa.canRead(ctx, t, "xyZ"));
|
||||
assertEquals("xY",rpa.read(ctx, t, "xY").getValue());
|
||||
assertTrue(rpa.canRead(ctx, t, "xY"));
|
||||
|
||||
// SPR-10122, ReflectivePropertyAccessor JavaBean property names compliance tests - setters
|
||||
rpr.write(ctx, t, "pEBS","Test String");
|
||||
assertEquals("Test String",rpr.read(ctx,t,"pEBS").getValue());
|
||||
rpa.write(ctx, t, "pEBS", "Test String");
|
||||
assertEquals("Test String",rpa.read(ctx, t, "pEBS").getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOptimalReflectivePropertyResolver() throws Exception {
|
||||
ReflectivePropertyAccessor rpr = new ReflectivePropertyAccessor();
|
||||
public void testOptimalReflectivePropertyAccessor() throws Exception {
|
||||
ReflectivePropertyAccessor rpa = new ReflectivePropertyAccessor();
|
||||
Tester t = new Tester();
|
||||
t.setProperty("hello");
|
||||
EvaluationContext ctx = new StandardEvaluationContext(t);
|
||||
// assertTrue(rpr.canRead(ctx, t, "property"));
|
||||
// assertEquals("hello",rpr.read(ctx, t, "property").getValue());
|
||||
// assertEquals("hello",rpr.read(ctx, t, "property").getValue()); // cached accessor used
|
||||
assertTrue(rpa.canRead(ctx, t, "property"));
|
||||
assertEquals("hello", rpa.read(ctx, t, "property").getValue());
|
||||
assertEquals("hello", rpa.read(ctx, t, "property").getValue()); // cached accessor used
|
||||
|
||||
PropertyAccessor optA = rpr.createOptimalAccessor(ctx, t, "property");
|
||||
PropertyAccessor optA = rpa.createOptimalAccessor(ctx, t, "property");
|
||||
assertTrue(optA.canRead(ctx, t, "property"));
|
||||
assertFalse(optA.canRead(ctx, t, "property2"));
|
||||
try {
|
||||
|
|
@ -381,14 +370,14 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
|
|||
// success
|
||||
}
|
||||
try {
|
||||
optA.write(ctx,t,"property",null);
|
||||
optA.write(ctx, t, "property", null);
|
||||
fail();
|
||||
}
|
||||
catch (UnsupportedOperationException uoe) {
|
||||
// success
|
||||
}
|
||||
|
||||
optA = rpr.createOptimalAccessor(ctx, t, "field");
|
||||
optA = rpa.createOptimalAccessor(ctx, t, "field");
|
||||
assertTrue(optA.canRead(ctx, t, "field"));
|
||||
assertFalse(optA.canRead(ctx, t, "field2"));
|
||||
try {
|
||||
|
|
@ -406,7 +395,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
|
|||
// success
|
||||
}
|
||||
assertEquals(3,optA.read(ctx, t, "field").getValue());
|
||||
assertEquals(3,optA.read(ctx, t, "field").getValue()); // cached accessor used
|
||||
assertEquals(3,optA.read(ctx, t, "field").getValue()); // cached accessor used
|
||||
|
||||
try {
|
||||
optA.getSpecificTargetClasses();
|
||||
|
|
@ -416,7 +405,7 @@ public class ReflectionHelperTests extends AbstractExpressionTests {
|
|||
// success
|
||||
}
|
||||
try {
|
||||
optA.write(ctx,t,"field",null);
|
||||
optA.write(ctx, t, "field", null);
|
||||
fail();
|
||||
}
|
||||
catch (UnsupportedOperationException uoe) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import javax.xml.transform.Source;
|
|||
import javax.xml.transform.dom.DOMSource;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
import org.springframework.test.util.JsonExpectationsHelper;
|
||||
import org.w3c.dom.Node;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
|
@ -32,6 +31,7 @@ import org.springframework.http.MediaType;
|
|||
import org.springframework.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||
import org.springframework.mock.http.client.MockClientHttpRequest;
|
||||
import org.springframework.test.util.JsonExpectationsHelper;
|
||||
import org.springframework.test.util.XmlExpectationsHelper;
|
||||
import org.springframework.test.web.client.RequestMatcher;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
|
@ -218,8 +218,8 @@ public class ContentRequestMatchers {
|
|||
* regardless of formatting.
|
||||
* <p>Can compare in two modes, depending on {@code strict} parameter value:
|
||||
* <ul>
|
||||
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
|
||||
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
|
||||
* <li>{@code true}: strict checking. Not extensible, and strict array ordering.</li>
|
||||
* <li>{@code false}: lenient checking. Extensible, and non-strict array ordering.</li>
|
||||
* </ul>
|
||||
* <p>Use of this matcher requires the <a
|
||||
* href="http://jsonassert.skyscreamer.org/">JSONassert<a/> library.
|
||||
|
|
@ -232,8 +232,9 @@ public class ContentRequestMatchers {
|
|||
try {
|
||||
MockClientHttpRequest mockRequest = (MockClientHttpRequest) request;
|
||||
jsonHelper.assertJsonEqual(expectedJsonContent, mockRequest.getBodyAsString(), strict);
|
||||
} catch (Exception e) {
|
||||
throw new AssertionError("Failed to parse expected or actual JSON request content", e);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new AssertionError("Failed to parse expected or actual JSON request content", ex);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -259,4 +260,3 @@ public class ContentRequestMatchers {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -537,6 +537,24 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
|||
return resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the given resource path.
|
||||
* <p>The default implementation replaces:
|
||||
* <ul>
|
||||
* <li>Backslash with forward slash.
|
||||
* <li>Duplicate occurrences of slash with a single slash.
|
||||
* <li>Any combination of leading slash and control characters (00-1F and 7F)
|
||||
* with a single "/" or "". For example {@code " / // foo/bar"}
|
||||
* becomes {@code "/foo/bar"}.
|
||||
* </ul>
|
||||
* @since 3.2.12
|
||||
*/
|
||||
protected String processPath(String path) {
|
||||
path = StringUtils.replace(path, "\\", "/");
|
||||
path = cleanDuplicateSlashes(path);
|
||||
return cleanLeadingSlash(path);
|
||||
}
|
||||
|
||||
private String cleanDuplicateSlashes(String path) {
|
||||
StringBuilder sb = null;
|
||||
char prev = 0;
|
||||
|
|
@ -619,6 +637,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
|||
* path starts predictably with a single '/' or does not have one.
|
||||
* @param path the path to validate
|
||||
* @return {@code true} if the path is invalid, {@code false} otherwise
|
||||
* @since 3.0.6
|
||||
*/
|
||||
protected boolean isInvalidPath(String path) {
|
||||
if (path.contains("WEB-INF") || path.contains("META-INF")) {
|
||||
|
|
@ -642,24 +661,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the given resource path.
|
||||
* <p>The default implementation replaces:
|
||||
* <ul>
|
||||
* <li>Backslash with forward slash.
|
||||
* <li>Duplicate occurrences of slash with a single slash.
|
||||
* <li>Any combination of leading slash and control characters (00-1F and 7F)
|
||||
* with a single "/" or "". For example {@code " / // foo/bar"}
|
||||
* becomes {@code "/foo/bar"}.
|
||||
* </ul>
|
||||
* @since 3.2.12
|
||||
*/
|
||||
protected String processPath(String path) {
|
||||
path = StringUtils.replace(path, "\\", "/");
|
||||
path = cleanDuplicateSlashes(path);
|
||||
return cleanLeadingSlash(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the media type for the given request and the resource matched
|
||||
* to it. This implementation tries to determine the MediaType based on the
|
||||
|
|
|
|||
Loading…
Reference in New Issue