Introduced MvcUriComponentsBuilder to create URIs pointing to controller methods.

MvcUriComponentsBuilder allows creating URIs that point to Spring MVC
controller methods annotated with @RequestMapping. It builds them by
exposing a mock method invocation API similar to Mockito, records the
method invocations and thus builds up the URI by inspecting the mapping
annotations and the parameters handed into the method invocations.

Introduced a new SPI UriComponentsContributor that should be implemented 
by HandlerMethodArgumentResolvers that actually contribute path segments 
or query parameters to a URI. While the newly introduced 
MvcUriComponentsBuilder looks up those UriComponentsContributor instances 
from the MVC configuration.

The MvcUriComponentsBuilderFactory (name to be discussed - MvcUris maybe?) 
prevents the multiple lookups by keeping the UriComponentsBuilder 
instances in an instance variable. So an instance of the factory could 
be exposed as Spring bean or through a HandlerMethodArgumentResolver to 
be injected into Controller methods.

Issue: SPR-10665, SPR-8826
This commit is contained in:
Oliver Gierke
2013-08-02 19:19:48 +02:00
committed by Rossen Stoyanchev
parent 92a48b72d7
commit 4fd27b12fc
18 changed files with 2036 additions and 1 deletions

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2002-2013 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
/**
* Unit tests for {@link AnnotationAttribute}.
*
* @author Oliver Gierke
*/
public class AnnotationAttributeUnitTests {
AnnotationAttribute valueAttribute = new AnnotationAttribute(MyAnnotation.class);
AnnotationAttribute nonValueAttribute = new AnnotationAttribute(MyAnnotation.class,
"nonValue");
@Test
public void readsAttributesFromType() {
assertThat(valueAttribute.findValueOn(Sample.class), is((Object) "foo"));
assertThat(nonValueAttribute.findValueOn(Sample.class), is((Object) "bar"));
}
@Test
public void findsAttributesFromSubType() {
assertThat(valueAttribute.findValueOn(SampleSub.class), is((Object) "foo"));
}
@Test
public void doesNotGetValueFromSubTyp() {
assertThat(valueAttribute.getValueFrom(SampleSub.class), is(nullValue()));
}
@Retention(RetentionPolicy.RUNTIME)
public static @interface MyAnnotation {
String value() default "";
String nonValue() default "";
}
@MyAnnotation(value = "foo", nonValue = "bar")
static class Sample {
}
static class SampleSub extends Sample {
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2013 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.core;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import org.junit.Test;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
/**
* Unit tests for {@link MethodParameters}.
*
* @author Oliver Gierke
*/
public class MethodParametersUnitTests {
@Test
public void prefersAnnotatedParameterOverDiscovered() throws Exception {
Method method = Sample.class.getMethod("method", String.class, String.class);
MethodParameters parameters = new MethodParameters(method,
new AnnotationAttribute(Qualifier.class));
assertThat(parameters.getParameter("param"), is(notNullValue()));
assertThat(parameters.getParameter("foo"), is(notNullValue()));
assertThat(parameters.getParameter("another"), is(nullValue()));
}
@Retention(RetentionPolicy.RUNTIME)
public static @interface Qualifier {
String value() default "";
}
static class Sample {
public void method(String param, @Qualifier("foo") String another) {
}
}
}