diff --git a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/SpringValidatorAdapterTests.java b/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/SpringValidatorAdapterTests.java index a7980fff376..86de5314557 100644 --- a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/SpringValidatorAdapterTests.java +++ b/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/SpringValidatorAdapterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2019 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. @@ -34,6 +34,7 @@ import java.util.Set; import javax.validation.Constraint; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; +import javax.validation.ConstraintViolation; import javax.validation.Payload; import javax.validation.Valid; import javax.validation.Validation; @@ -50,6 +51,7 @@ import org.springframework.beans.BeanWrapperImpl; import org.springframework.context.support.StaticMessageSource; import org.springframework.util.ObjectUtils; import org.springframework.validation.BeanPropertyBindingResult; +import org.springframework.validation.FieldError; import org.springframework.validation.beanvalidation.SpringValidatorAdapter; import static java.lang.annotation.ElementType.*; @@ -73,7 +75,7 @@ public class SpringValidatorAdapterTests { @Before public void setupSpringValidatorAdapter() { messageSource.addMessage("Size", Locale.ENGLISH, "Size of {0} is must be between {2} and {1}"); - messageSource.addMessage("Same", Locale.ENGLISH, "{2} must be same value with {1}"); + messageSource.addMessage("Same", Locale.ENGLISH, "{2} must be same value as {1}"); messageSource.addMessage("password", Locale.ENGLISH, "Password"); messageSource.addMessage("confirmPassword", Locale.ENGLISH, "Password(Confirm)"); } @@ -96,8 +98,11 @@ public class SpringValidatorAdapterTests { assertThat(errors.getFieldErrorCount("password"), is(1)); assertThat(errors.getFieldValue("password"), is("pass")); - assertThat(messageSource.getMessage(errors.getFieldError("password"), Locale.ENGLISH), - is("Size of Password is must be between 8 and 128")); + FieldError error = errors.getFieldError("password"); + assertNotNull(error); + assertThat(messageSource.getMessage(error, Locale.ENGLISH), is("Size of Password is must be between 8 and 128")); + assertTrue(error.contains(ConstraintViolation.class)); + assertThat(error.unwrap(ConstraintViolation.class).getPropertyPath().toString(), is("password")); } @Test // SPR-13406 @@ -111,8 +116,11 @@ public class SpringValidatorAdapterTests { assertThat(errors.getFieldErrorCount("password"), is(1)); assertThat(errors.getFieldValue("password"), is("password")); - assertThat(messageSource.getMessage(errors.getFieldError("password"), Locale.ENGLISH), - is("Password must be same value with Password(Confirm)")); + FieldError error = errors.getFieldError("password"); + assertNotNull(error); + assertThat(messageSource.getMessage(error, Locale.ENGLISH), is("Password must be same value as Password(Confirm)")); + assertTrue(error.contains(ConstraintViolation.class)); + assertThat(error.unwrap(ConstraintViolation.class).getPropertyPath().toString(), is("password")); } @Test // SPR-13406 @@ -127,10 +135,16 @@ public class SpringValidatorAdapterTests { assertThat(errors.getFieldErrorCount("email"), is(1)); assertThat(errors.getFieldValue("email"), is("test@example.com")); assertThat(errors.getFieldErrorCount("confirmEmail"), is(1)); - assertThat(messageSource.getMessage(errors.getFieldError("email"), Locale.ENGLISH), - is("email must be same value with confirmEmail")); - assertThat(messageSource.getMessage(errors.getFieldError("confirmEmail"), Locale.ENGLISH), - is("Email required")); + FieldError error1 = errors.getFieldError("email"); + FieldError error2 = errors.getFieldError("confirmEmail"); + assertNotNull(error1); + assertNotNull(error2); + assertThat(messageSource.getMessage(error1, Locale.ENGLISH), is("email must be same value as confirmEmail")); + assertThat(messageSource.getMessage(error2, Locale.ENGLISH), is("Email required")); + assertTrue(error1.contains(ConstraintViolation.class)); + assertThat(error1.unwrap(ConstraintViolation.class).getPropertyPath().toString(), is("email")); + assertTrue(error2.contains(ConstraintViolation.class)); + assertThat(error2.unwrap(ConstraintViolation.class).getPropertyPath().toString(), is("confirmEmail")); } @Test // SPR-15123 @@ -147,10 +161,16 @@ public class SpringValidatorAdapterTests { assertThat(errors.getFieldErrorCount("email"), is(1)); assertThat(errors.getFieldValue("email"), is("test@example.com")); assertThat(errors.getFieldErrorCount("confirmEmail"), is(1)); - assertThat(messageSource.getMessage(errors.getFieldError("email"), Locale.ENGLISH), - is("email must be same value with confirmEmail")); - assertThat(messageSource.getMessage(errors.getFieldError("confirmEmail"), Locale.ENGLISH), - is("Email required")); + FieldError error1 = errors.getFieldError("email"); + FieldError error2 = errors.getFieldError("confirmEmail"); + assertNotNull(error1); + assertNotNull(error2); + assertThat(messageSource.getMessage(error1, Locale.ENGLISH), is("email must be same value as confirmEmail")); + assertThat(messageSource.getMessage(error2, Locale.ENGLISH), is("Email required")); + assertTrue(error1.contains(ConstraintViolation.class)); + assertThat(error1.unwrap(ConstraintViolation.class).getPropertyPath().toString(), is("email")); + assertTrue(error2.contains(ConstraintViolation.class)); + assertThat(error2.unwrap(ConstraintViolation.class).getPropertyPath().toString(), is("confirmEmail")); } @Test // SPR-16177 @@ -403,13 +423,13 @@ public class SpringValidatorAdapterTests { private Integer id; - @javax.validation.constraints.NotNull + @NotNull private String name; - @javax.validation.constraints.NotNull + @NotNull private Integer age; - @javax.validation.constraints.NotNull + @NotNull private Parent parent; public Integer getId() { diff --git a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/ValidatorFactoryTests.java b/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/ValidatorFactoryTests.java index c065a8db322..08a2e3427b8 100644 --- a/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/ValidatorFactoryTests.java +++ b/spring-context-support/src/test/java/org/springframework/validation/beanvalidation2/ValidatorFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -285,6 +285,8 @@ public class ValidatorFactoryTests { validator.validate(listContainer, errors); FieldError fieldError = errors.getFieldError("list[1]"); + assertNotNull(fieldError); + assertEquals("X", fieldError.getRejectedValue()); assertEquals("X", errors.getFieldValue("list[1]")); } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/AutoProxyRegistrar.java b/spring-context/src/main/java/org/springframework/context/annotation/AutoProxyRegistrar.java index 7ef91660ffd..770070b3545 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/AutoProxyRegistrar.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/AutoProxyRegistrar.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -57,9 +57,9 @@ public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { boolean candidateFound = false; - Set annoTypes = importingClassMetadata.getAnnotationTypes(); - for (String annoType : annoTypes) { - AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType); + Set annTypes = importingClassMetadata.getAnnotationTypes(); + for (String annType : annTypes) { + AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType); if (candidate == null) { continue; } diff --git a/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java b/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java index 1a554a0ab7f..fd0ebbb9108 100644 --- a/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java +++ b/spring-context/src/main/java/org/springframework/context/support/DefaultMessageSourceResolvable.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -135,7 +135,7 @@ public class DefaultMessageSourceResolvable implements MessageSourceResolvable, * including codes, arguments, and default message. */ protected final String resolvableToString() { - StringBuilder result = new StringBuilder(); + StringBuilder result = new StringBuilder(64); result.append("codes [").append(StringUtils.arrayToDelimitedString(this.codes, ",")); result.append("]; arguments [").append(StringUtils.arrayToDelimitedString(this.arguments, ",")); result.append("]; default message [").append(this.defaultMessage).append(']'); diff --git a/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java index dd3a0c09c6a..438a1248f6e 100644 --- a/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/GenericApplicationContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -358,9 +358,9 @@ public class GenericApplicationContext extends AbstractApplicationContext implem /** * Register a bean from the given bean class, optionally customizing its - * bean definition metadata (typically declared as a lambda expression - * or method reference). - * @param beanClass the class of the bean + * bean definition metadata (typically declared as a lambda expression). + * @param beanClass the class of the bean (resolving a public constructor + * to be autowired, possibly simply the default constructor) * @param customizers one or more callbacks for customizing the factory's * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * @since 5.0 @@ -371,18 +371,19 @@ public class GenericApplicationContext extends AbstractApplicationContext implem } /** - * Register a bean from the given bean class, using the given supplier for - * obtaining a new instance (typically declared as a lambda expression or - * method reference), optionally customizing its bean definition metadata - * (again typically declared as a lambda expression or method reference). + * Register a bean from the given bean class, optionally customizing its + * bean definition metadata (typically declared as a lambda expression). * @param beanName the name of the bean (may be {@code null}) - * @param beanClass the class of the bean + * @param beanClass the class of the bean (resolving a public constructor + * to be autowired, possibly simply the default constructor) * @param customizers one or more callbacks for customizing the factory's * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * @since 5.0 * @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...) */ - public final void registerBean(@Nullable String beanName, Class beanClass, BeanDefinitionCustomizer... customizers) { + public final void registerBean( + @Nullable String beanName, Class beanClass, BeanDefinitionCustomizer... customizers) { + registerBean(beanName, beanClass, null, customizers); } @@ -390,7 +391,7 @@ public class GenericApplicationContext extends AbstractApplicationContext implem * Register a bean from the given bean class, using the given supplier for * obtaining a new instance (typically declared as a lambda expression or * method reference), optionally customizing its bean definition metadata - * (again typically declared as a lambda expression or method reference). + * (again typically declared as a lambda expression). * @param beanClass the class of the bean * @param supplier a callback for creating an instance of the bean * @param customizers one or more callbacks for customizing the factory's @@ -398,7 +399,9 @@ public class GenericApplicationContext extends AbstractApplicationContext implem * @since 5.0 * @see #registerBean(String, Class, Supplier, BeanDefinitionCustomizer...) */ - public final void registerBean(Class beanClass, Supplier supplier, BeanDefinitionCustomizer... customizers) { + public final void registerBean( + Class beanClass, Supplier supplier, BeanDefinitionCustomizer... customizers) { + registerBean(null, beanClass, supplier, customizers); } @@ -406,18 +409,19 @@ public class GenericApplicationContext extends AbstractApplicationContext implem * Register a bean from the given bean class, using the given supplier for * obtaining a new instance (typically declared as a lambda expression or * method reference), optionally customizing its bean definition metadata - * (again typically declared as a lambda expression or method reference). + * (again typically declared as a lambda expression). *

This method can be overridden to adapt the registration mechanism for * all {@code registerBean} methods (since they all delegate to this one). * @param beanName the name of the bean (may be {@code null}) * @param beanClass the class of the bean - * @param supplier a callback for creating an instance of the bean + * @param supplier a callback for creating an instance of the bean (in case + * of {@code null}, resolving a public constructor to be autowired instead) * @param customizers one or more callbacks for customizing the factory's * {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * @since 5.0 */ - public void registerBean(@Nullable String beanName, Class beanClass, @Nullable Supplier supplier, - BeanDefinitionCustomizer... customizers) { + public void registerBean(@Nullable String beanName, Class beanClass, + @Nullable Supplier supplier, BeanDefinitionCustomizer... customizers) { BeanDefinitionBuilder builder = (supplier != null ? BeanDefinitionBuilder.genericBeanDefinition(beanClass, supplier) : diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index 0df93925a8a..bfc1386883c 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -50,13 +50,17 @@ import org.springframework.validation.SmartValidator; * while also exposing the original JSR-303 Validator interface itself. * *

Can be used as a programmatic wrapper. Also serves as base class for - * {@link CustomValidatorBean} and {@link LocalValidatorFactoryBean}. + * {@link CustomValidatorBean} and {@link LocalValidatorFactoryBean}, + * and as the primary implementation of the {@link SmartValidator} interface. * *

As of Spring Framework 5.0, this adapter is fully compatible with * Bean Validation 1.1 as well as 2.0. * * @author Juergen Hoeller * @since 3.0 + * @see SmartValidator + * @see CustomValidatorBean + * @see LocalValidatorFactoryBean */ public class SpringValidatorAdapter implements SmartValidator, javax.validation.Validator { @@ -141,7 +145,7 @@ public class SpringValidatorAdapter implements SmartValidator, javax.validation. // as necessary for Hibernate Validator compatibility (non-indexed set path in field) BindingResult bindingResult = (BindingResult) errors; String nestedField = bindingResult.getNestedPath() + field; - if ("".equals(nestedField)) { + if (nestedField.isEmpty()) { String[] errorCodes = bindingResult.resolveMessageCodes(errorCode); ObjectError error = new ObjectError( errors.getObjectName(), errorCodes, errorArgs, violation.getMessage()); diff --git a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java index e53692b6482..6a8655dc95b 100644 --- a/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java +++ b/spring-context/src/test/java/org/springframework/validation/beanvalidation/ValidatorFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -284,6 +284,8 @@ public class ValidatorFactoryTests { validator.validate(listContainer, errors); FieldError fieldError = errors.getFieldError("list[1]"); + assertNotNull(fieldError); + assertEquals("X", fieldError.getRejectedValue()); assertEquals("X", errors.getFieldValue("list[1]")); } diff --git a/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java index 28b3ebc2111..eb1fdf6db70 100644 --- a/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/AnnotationMetadataTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -52,7 +52,7 @@ import static org.junit.Assert.*; public class AnnotationMetadataTests { @Test - public void standardAnnotationMetadata() throws Exception { + public void standardAnnotationMetadata() { AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class, true); doTestAnnotationInfo(metadata); doTestMethodAnnotationInfo(metadata); @@ -68,7 +68,7 @@ public class AnnotationMetadataTests { } @Test - public void standardAnnotationMetadataForSubclass() throws Exception { + public void standardAnnotationMetadataForSubclass() { AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponentSubClass.class, true); doTestSubClassAnnotationInfo(metadata); } @@ -104,7 +104,7 @@ public class AnnotationMetadataTests { } @Test - public void standardAnnotationMetadataForInterface() throws Exception { + public void standardAnnotationMetadataForInterface() { AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotationMetadata.class, true); doTestMetadataForInterfaceClass(metadata); } @@ -132,7 +132,7 @@ public class AnnotationMetadataTests { } @Test - public void standardAnnotationMetadataForAnnotation() throws Exception { + public void standardAnnotationMetadataForAnnotation() { AnnotationMetadata metadata = new StandardAnnotationMetadata(Component.class, true); doTestMetadataForAnnotationClass(metadata); } @@ -172,7 +172,7 @@ public class AnnotationMetadataTests { * 'true' as is done in the main test above. */ @Test - public void standardAnnotationMetadata_nestedAnnotationsAsMap_false() throws Exception { + public void standardAnnotationMetadata_nestedAnnotationsAsMap_false() { AnnotationMetadata metadata = new StandardAnnotationMetadata(AnnotatedComponent.class); AnnotationAttributes specialAttrs = (AnnotationAttributes) metadata.getAnnotationAttributes(SpecialAttr.class.getName()); Annotation[] nestedAnnoArray = (Annotation[]) specialAttrs.get("nestedAnnoArray"); @@ -205,19 +205,13 @@ public class AnnotationMetadataTests { assertThat("length of basePackageClasses[]", basePackageClasses.length, is(0)); } - /** - * https://jira.spring.io/browse/SPR-11649 - */ - @Test + @Test // SPR-11649 public void multipleAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() { AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedAnnotationsClass.class); assertMultipleAnnotationsWithIdenticalAttributeNames(metadata); } - /** - * https://jira.spring.io/browse/SPR-11649 - */ - @Test + @Test // SPR-11649 public void multipleAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor() throws Exception { MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(); MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(NamedAnnotationsClass.class.getName()); @@ -225,19 +219,13 @@ public class AnnotationMetadataTests { assertMultipleAnnotationsWithIdenticalAttributeNames(metadata); } - /** - * https://jira.spring.io/browse/SPR-11649 - */ - @Test + @Test // SPR-11649 public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingStandardAnnotationMetadata() { AnnotationMetadata metadata = new StandardAnnotationMetadata(NamedComposedAnnotationClass.class); assertMultipleAnnotationsWithIdenticalAttributeNames(metadata); } - /** - * https://jira.spring.io/browse/SPR-11649 - */ - @Test + @Test // SPR-11649 public void composedAnnotationWithMetaAnnotationsWithIdenticalAttributeNamesUsingAnnotationMetadataReadingVisitor() throws Exception { MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(); MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(NamedComposedAnnotationClass.class.getName()); diff --git a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java index d1b3381614a..415d56ceb9b 100644 --- a/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java +++ b/spring-web/src/main/java/org/springframework/web/util/UrlPathHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -34,7 +34,7 @@ import org.springframework.util.StringUtils; /** * Helper class for URL path matching. Provides support for URL paths in - * RequestDispatcher includes and support for consistent URL decoding. + * {@code RequestDispatcher} includes and support for consistent URL decoding. * *

Used by {@link org.springframework.web.servlet.handler.AbstractUrlHandlerMapping} * and {@link org.springframework.web.servlet.support.RequestContext} for path matching @@ -44,6 +44,8 @@ import org.springframework.util.StringUtils; * @author Rob Harrop * @author Rossen Stoyanchev * @since 14.01.2004 + * @see #getLookupPathForRequest + * @see javax.servlet.RequestDispatcher */ public class UrlPathHelper { @@ -90,7 +92,7 @@ public class UrlPathHelper { *

By default this is set to {@literal true}. *

Note: Be aware the servlet path will not match when * compared to encoded paths. Therefore use of {@code urlDecode=false} is - * not compatible with a prefix-based Servlet mappping and likewise implies + * not compatible with a prefix-based Servlet mapping and likewise implies * also setting {@code alwaysUseFullPath=true}. * @see #getServletPath * @see #getContextPath @@ -157,8 +159,8 @@ public class UrlPathHelper { *

Detects include request URL if called within a RequestDispatcher include. * @param request current HTTP request * @return the lookup path - * @see #getPathWithinApplication * @see #getPathWithinServletMapping + * @see #getPathWithinApplication */ public String getLookupPathForRequest(HttpServletRequest request) { // Always use full path within current servlet context? @@ -187,6 +189,7 @@ public class UrlPathHelper { *

E.g.: servlet mapping = "/*.test"; request URI = "/a.test" -> "". * @param request current HTTP request * @return the path within the servlet mapping, or "" + * @see #getLookupPathForRequest */ public String getPathWithinServletMapping(HttpServletRequest request) { String pathWithinApp = getPathWithinApplication(request); @@ -234,6 +237,7 @@ public class UrlPathHelper { *

Detects include request URL if called within a RequestDispatcher include. * @param request current HTTP request * @return the path within the web application + * @see #getLookupPathForRequest */ public String getPathWithinApplication(HttpServletRequest request) { String contextPath = getContextPath(request); @@ -288,7 +292,7 @@ public class UrlPathHelper { /** * Sanitize the given path with the following rules: *

    - *
  • replace all "//" by "/"
  • + *
  • replace all "//" by "/"
  • *
*/ private String getSanitizedPath(final String path) {