Add support for matrix variables
A new @MatrixVariable annotation allows injecting matrix variables into @RequestMapping methods. The matrix variables may appear in any path segment and should be wrapped in a URI template for request mapping purposes to ensure request matching is not affected by the order or the presence/absence of such variables. The @MatrixVariable annotation has an optional "pathVar" attribute that can be used to refer to the URI template where a matrix variable is located. Previously, ";" (semicolon) delimited content was removed from the path used for request mapping purposes. To preserve backwards compatibility that continues to be the case (except for the MVC namespace and Java config) and may be changed by setting the "removeSemicolonContent" property of RequestMappingHandlerMapping to "false". Applications using the MVC namespace and Java config do not need to do anything further to extract and use matrix variables. Issue: SPR-5499, SPR-7818
This commit is contained in:
@@ -45,7 +45,7 @@ public class MappedInterceptorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void includePatternOnly() {
|
||||
public void includePattern() {
|
||||
MappedInterceptor mappedInterceptor = new MappedInterceptor(new String[] { "/foo/*" }, this.interceptor);
|
||||
|
||||
assertTrue(mappedInterceptor.matches("/foo/bar", pathMatcher));
|
||||
@@ -53,7 +53,13 @@ public class MappedInterceptorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void excludePatternOnly() {
|
||||
public void includePatternWithMatrixVariables() {
|
||||
MappedInterceptor mappedInterceptor = new MappedInterceptor(new String[] { "/foo*/*" }, this.interceptor);
|
||||
assertTrue(mappedInterceptor.matches("/foo;q=1/bar;s=2", pathMatcher));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void excludePattern() {
|
||||
MappedInterceptor mappedInterceptor = new MappedInterceptor(null, new String[] { "/admin/**" }, this.interceptor);
|
||||
|
||||
assertTrue(mappedInterceptor.matches("/foo", pathMatcher));
|
||||
|
||||
@@ -55,6 +55,15 @@ public class UrlFilenameViewControllerTests extends TestCase {
|
||||
assertTrue(mv.getModel().isEmpty());
|
||||
}
|
||||
|
||||
public void testWithFilenameAndMatrixVariables() throws Exception {
|
||||
UrlFilenameViewController ctrl = new UrlFilenameViewController();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index;a=A;b=B");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
ModelAndView mv = ctrl.handleRequest(request, response);
|
||||
assertEquals("index", mv.getViewName());
|
||||
assertTrue(mv.getModel().isEmpty());
|
||||
}
|
||||
|
||||
public void testWithPrefixAndSuffix() throws Exception {
|
||||
UrlFilenameViewController ctrl = new UrlFilenameViewController();
|
||||
ctrl.setPrefix("mypre_");
|
||||
|
||||
@@ -30,12 +30,15 @@ import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
@@ -65,7 +68,7 @@ import org.springframework.web.util.UrlPathHelper;
|
||||
*/
|
||||
public class RequestMappingInfoHandlerMappingTests {
|
||||
|
||||
private TestRequestMappingInfoHandlerMapping mapping;
|
||||
private TestRequestMappingInfoHandlerMapping handlerMapping;
|
||||
|
||||
private Handler handler;
|
||||
|
||||
@@ -85,15 +88,16 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
this.barMethod = new HandlerMethod(handler, "bar");
|
||||
this.emptyMethod = new HandlerMethod(handler, "empty");
|
||||
|
||||
this.mapping = new TestRequestMappingInfoHandlerMapping();
|
||||
this.mapping.registerHandler(this.handler);
|
||||
this.handlerMapping = new TestRequestMappingInfoHandlerMapping();
|
||||
this.handlerMapping.registerHandler(this.handler);
|
||||
this.handlerMapping.setRemoveSemicolonContent(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMappingPathPatterns() throws Exception {
|
||||
RequestMappingInfo info = new RequestMappingInfo(
|
||||
new PatternsRequestCondition("/foo/*", "/foo", "/bar/*", "/bar"), null, null, null, null, null, null);
|
||||
Set<String> paths = this.mapping.getMappingPathPatterns(info);
|
||||
Set<String> paths = this.handlerMapping.getMappingPathPatterns(info);
|
||||
HashSet<String> expected = new HashSet<String>(Arrays.asList("/foo/*", "/foo", "/bar/*", "/bar"));
|
||||
|
||||
assertEquals(expected, paths);
|
||||
@@ -102,25 +106,25 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
@Test
|
||||
public void directMatch() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
HandlerMethod hm = (HandlerMethod) this.mapping.getHandler(request).getHandler();
|
||||
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(request).getHandler();
|
||||
assertEquals(this.fooMethod.getMethod(), hm.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void globMatch() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/bar");
|
||||
HandlerMethod hm = (HandlerMethod) this.mapping.getHandler(request).getHandler();
|
||||
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(request).getHandler();
|
||||
assertEquals(this.barMethod.getMethod(), hm.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyPathMatch() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
|
||||
HandlerMethod hm = (HandlerMethod) this.mapping.getHandler(request).getHandler();
|
||||
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(request).getHandler();
|
||||
assertEquals(this.emptyMethod.getMethod(), hm.getMethod());
|
||||
|
||||
request = new MockHttpServletRequest("GET", "/");
|
||||
hm = (HandlerMethod) this.mapping.getHandler(request).getHandler();
|
||||
hm = (HandlerMethod) this.handlerMapping.getHandler(request).getHandler();
|
||||
assertEquals(this.emptyMethod.getMethod(), hm.getMethod());
|
||||
}
|
||||
|
||||
@@ -128,7 +132,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
public void bestMatch() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
request.setParameter("p", "anything");
|
||||
HandlerMethod hm = (HandlerMethod) this.mapping.getHandler(request).getHandler();
|
||||
HandlerMethod hm = (HandlerMethod) this.handlerMapping.getHandler(request).getHandler();
|
||||
assertEquals(this.fooParamMethod.getMethod(), hm.getMethod());
|
||||
}
|
||||
|
||||
@@ -136,7 +140,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
public void requestMethodNotAllowed() throws Exception {
|
||||
try {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/bar");
|
||||
this.mapping.getHandler(request);
|
||||
this.handlerMapping.getHandler(request);
|
||||
fail("HttpRequestMethodNotSupportedException expected");
|
||||
}
|
||||
catch (HttpRequestMethodNotSupportedException ex) {
|
||||
@@ -155,7 +159,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
try {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("PUT", url);
|
||||
request.setContentType("application/json");
|
||||
this.mapping.getHandler(request);
|
||||
this.handlerMapping.getHandler(request);
|
||||
fail("HttpMediaTypeNotSupportedException expected");
|
||||
}
|
||||
catch (HttpMediaTypeNotSupportedException ex) {
|
||||
@@ -175,7 +179,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
try {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", url);
|
||||
request.addHeader("Accept", "application/json");
|
||||
this.mapping.getHandler(request);
|
||||
this.handlerMapping.getHandler(request);
|
||||
fail("HttpMediaTypeNotAcceptableException expected");
|
||||
}
|
||||
catch (HttpMediaTypeNotAcceptableException ex) {
|
||||
@@ -190,7 +194,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
RequestMappingInfo key = new RequestMappingInfo(patterns, null, null, null, null, null, null);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/1/2");
|
||||
String lookupPath = new UrlPathHelper().getLookupPathForRequest(request);
|
||||
this.mapping.handleMatch(key, lookupPath, request);
|
||||
this.handlerMapping.handleMatch(key, lookupPath, request);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> uriVariables =
|
||||
@@ -214,8 +218,8 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
pathHelper.setUrlDecode(false);
|
||||
String lookupPath = pathHelper.getLookupPathForRequest(request);
|
||||
|
||||
this.mapping.setUrlPathHelper(pathHelper);
|
||||
this.mapping.handleMatch(key, lookupPath, request);
|
||||
this.handlerMapping.setUrlPathHelper(pathHelper);
|
||||
this.handlerMapping.handleMatch(key, lookupPath, request);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> uriVariables =
|
||||
@@ -232,7 +236,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
RequestMappingInfo key = new RequestMappingInfo(patterns, null, null, null, null, null, null);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/1/2");
|
||||
|
||||
this.mapping.handleMatch(key, "/1/2", request);
|
||||
this.handlerMapping.handleMatch(key, "/1/2", request);
|
||||
|
||||
assertEquals("/{path1}/2", request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE));
|
||||
}
|
||||
@@ -243,7 +247,7 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
RequestMappingInfo key = new RequestMappingInfo(patterns, null, null, null, null, null, null);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/1/2");
|
||||
|
||||
this.mapping.handleMatch(key, "/1/2", request);
|
||||
this.handlerMapping.handleMatch(key, "/1/2", request);
|
||||
|
||||
assertEquals("/1/2", request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE));
|
||||
}
|
||||
@@ -252,14 +256,14 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
public void producibleMediaTypesAttribute() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/content");
|
||||
request.addHeader("Accept", "application/xml");
|
||||
this.mapping.getHandler(request);
|
||||
this.handlerMapping.getHandler(request);
|
||||
|
||||
assertEquals(Collections.singleton(MediaType.APPLICATION_XML),
|
||||
request.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE));
|
||||
|
||||
request = new MockHttpServletRequest("GET", "/content");
|
||||
request.addHeader("Accept", "application/json");
|
||||
this.mapping.getHandler(request);
|
||||
this.handlerMapping.getHandler(request);
|
||||
|
||||
assertNull("Negated expression should not be listed as a producible type",
|
||||
request.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE));
|
||||
@@ -285,7 +289,74 @@ public class RequestMappingInfoHandlerMappingTests {
|
||||
assertNull(chain);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void matrixVariables() {
|
||||
|
||||
MockHttpServletRequest request;
|
||||
MultiValueMap<String, String> matrixVariables;
|
||||
Map<String, String> uriVariables;
|
||||
|
||||
String lookupPath = "/cars;colors=red,blue,green;year=2012";
|
||||
|
||||
// Pattern "/{cars}" : matrix variables stripped from "cars" variable
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
testHandleMatch(request, "/{cars}", lookupPath);
|
||||
|
||||
matrixVariables = getMatrixVariables(request, "cars");
|
||||
assertNotNull(matrixVariables);
|
||||
assertEquals(Arrays.asList("red", "blue", "green"), matrixVariables.get("colors"));
|
||||
assertEquals("2012", matrixVariables.getFirst("year"));
|
||||
|
||||
uriVariables = getUriTemplateVariables(request);
|
||||
assertEquals("cars", uriVariables.get("cars"));
|
||||
|
||||
// Pattern "/{cars:[^;]+}{params}" : "cars" and "params" variables unchanged
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
testHandleMatch(request, "/{cars:[^;]+}{params}", lookupPath);
|
||||
|
||||
matrixVariables = getMatrixVariables(request, "params");
|
||||
assertNotNull(matrixVariables);
|
||||
assertEquals(Arrays.asList("red", "blue", "green"), matrixVariables.get("colors"));
|
||||
assertEquals("2012", matrixVariables.getFirst("year"));
|
||||
|
||||
uriVariables = getUriTemplateVariables(request);
|
||||
assertEquals("cars", uriVariables.get("cars"));
|
||||
assertEquals(";colors=red,blue,green;year=2012", uriVariables.get("params"));
|
||||
|
||||
// matrix variables not present : "params" variable is empty
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
testHandleMatch(request, "/{cars:[^;]+}{params}", "/cars");
|
||||
|
||||
matrixVariables = getMatrixVariables(request, "params");
|
||||
assertNull(matrixVariables);
|
||||
|
||||
uriVariables = getUriTemplateVariables(request);
|
||||
assertEquals("cars", uriVariables.get("cars"));
|
||||
assertEquals("", uriVariables.get("params"));
|
||||
}
|
||||
|
||||
private void testHandleMatch(MockHttpServletRequest request, String pattern, String lookupPath) {
|
||||
PatternsRequestCondition patterns = new PatternsRequestCondition(pattern);
|
||||
RequestMappingInfo info = new RequestMappingInfo(patterns, null, null, null, null, null, null);
|
||||
this.handlerMapping.handleMatch(info, lookupPath, request);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private MultiValueMap<String, String> getMatrixVariables(HttpServletRequest request, String uriVarName) {
|
||||
String attrName = HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE;
|
||||
return ((Map<String, MultiValueMap<String, String>>) request.getAttribute(attrName)).get(uriVarName);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, String> getUriTemplateVariables(HttpServletRequest request) {
|
||||
String attrName = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
|
||||
return (Map<String, String>) request.getAttribute(attrName);
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
private static class Handler {
|
||||
|
||||
|
||||
@@ -31,24 +31,24 @@ import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionRes
|
||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* Base class for tests using on the DispatcherServlet and HandlerMethod infrastructure classes:
|
||||
* Base class for tests using on the DispatcherServlet and HandlerMethod infrastructure classes:
|
||||
* <ul>
|
||||
* <li>RequestMappingHandlerMapping
|
||||
* <li>RequestMappingHandlerAdapter
|
||||
* <li>RequestMappingHandlerMapping
|
||||
* <li>RequestMappingHandlerAdapter
|
||||
* <li>ExceptionHandlerExceptionResolver
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class AbstractServletHandlerMethodTests {
|
||||
|
||||
private DispatcherServlet servlet;
|
||||
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
this.servlet = null;
|
||||
}
|
||||
|
||||
|
||||
protected DispatcherServlet getServlet() {
|
||||
assertNotNull("DispatcherServlet not initialized", servlet);
|
||||
return servlet;
|
||||
@@ -68,30 +68,32 @@ public class AbstractServletHandlerMethodTests {
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
protected WebApplicationContext initServlet(
|
||||
final ApplicationContextInitializer<GenericWebApplicationContext> initializer,
|
||||
final ApplicationContextInitializer<GenericWebApplicationContext> initializer,
|
||||
final Class<?>... controllerClasses) throws ServletException {
|
||||
|
||||
|
||||
final GenericWebApplicationContext wac = new GenericWebApplicationContext();
|
||||
|
||||
|
||||
servlet = new DispatcherServlet() {
|
||||
@Override
|
||||
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
|
||||
for (Class<?> clazz : controllerClasses) {
|
||||
wac.registerBeanDefinition(clazz.getSimpleName(), new RootBeanDefinition(clazz));
|
||||
}
|
||||
|
||||
|
||||
Class<?> mappingType = RequestMappingHandlerMapping.class;
|
||||
wac.registerBeanDefinition("handlerMapping", new RootBeanDefinition(mappingType));
|
||||
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(mappingType);
|
||||
beanDef.getPropertyValues().add("removeSemicolonContent", "false");
|
||||
wac.registerBeanDefinition("handlerMapping", beanDef);
|
||||
|
||||
Class<?> adapterType = RequestMappingHandlerAdapter.class;
|
||||
wac.registerBeanDefinition("handlerAdapter", new RootBeanDefinition(adapterType));
|
||||
|
||||
|
||||
Class<?> resolverType = ExceptionHandlerExceptionResolver.class;
|
||||
wac.registerBeanDefinition("requestMappingResolver", new RootBeanDefinition(resolverType));
|
||||
|
||||
|
||||
resolverType = ResponseStatusExceptionResolver.class;
|
||||
wac.registerBeanDefinition("responseStatusResolver", new RootBeanDefinition(resolverType));
|
||||
|
||||
|
||||
resolverType = DefaultHandlerExceptionResolver.class;
|
||||
wac.registerBeanDefinition("defaultResolver", new RootBeanDefinition(resolverType));
|
||||
|
||||
@@ -103,9 +105,9 @@ public class AbstractServletHandlerMethodTests {
|
||||
return wac;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
servlet.init(new MockServletConfig());
|
||||
|
||||
|
||||
return wac;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.web.servlet.mvc.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.annotation.MatrixVariable;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
/**
|
||||
* Test fixture with {@link MatrixVariableMethodArgumentResolver}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class MatrixVariablesMapMethodArgumentResolverTests {
|
||||
|
||||
private MatrixVariableMapMethodArgumentResolver resolver;
|
||||
|
||||
private MethodParameter paramString;
|
||||
private MethodParameter paramMap;
|
||||
private MethodParameter paramMultivalueMap;
|
||||
private MethodParameter paramMapForPathVar;
|
||||
private MethodParameter paramMapWithName;
|
||||
|
||||
private ModelAndViewContainer mavContainer;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.resolver = new MatrixVariableMapMethodArgumentResolver();
|
||||
|
||||
Method method = getClass().getMethod("handle", String.class,
|
||||
Map.class, MultiValueMap.class, MultiValueMap.class, Map.class);
|
||||
|
||||
this.paramString = new MethodParameter(method, 0);
|
||||
this.paramMap = new MethodParameter(method, 1);
|
||||
this.paramMultivalueMap = new MethodParameter(method, 2);
|
||||
this.paramMapForPathVar = new MethodParameter(method, 3);
|
||||
this.paramMapWithName = new MethodParameter(method, 4);
|
||||
|
||||
this.mavContainer = new ModelAndViewContainer();
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
|
||||
|
||||
Map<String, MultiValueMap<String, String>> params = new LinkedHashMap<String, MultiValueMap<String, String>>();
|
||||
this.request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, params);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsParameter() {
|
||||
assertFalse(resolver.supportsParameter(paramString));
|
||||
assertTrue(resolver.supportsParameter(paramMap));
|
||||
assertTrue(resolver.supportsParameter(paramMultivalueMap));
|
||||
assertTrue(resolver.supportsParameter(paramMapForPathVar));
|
||||
assertFalse(resolver.supportsParameter(paramMapWithName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgument() throws Exception {
|
||||
|
||||
MultiValueMap<String, String> params = getMatrixVariables("cars");
|
||||
params.add("colors", "red");
|
||||
params.add("colors", "green");
|
||||
params.add("colors", "blue");
|
||||
params.add("year", "2012");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> map = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMap, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Arrays.asList("red", "green", "blue"), map.get("colors"));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
MultiValueMap<String, String> multivalueMap = (MultiValueMap<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMultivalueMap, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Arrays.asList("red", "green", "blue"), multivalueMap.get("colors"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentPathVariable() throws Exception {
|
||||
|
||||
MultiValueMap<String, String> params1 = getMatrixVariables("cars");
|
||||
params1.add("colors", "red");
|
||||
params1.add("colors", "purple");
|
||||
|
||||
MultiValueMap<String, String> params2 = getMatrixVariables("planes");
|
||||
params2.add("colors", "yellow");
|
||||
params2.add("colors", "orange");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> mapForPathVar = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMapForPathVar, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Arrays.asList("red", "purple"), mapForPathVar.get("colors"));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> mapAll = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMap, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Arrays.asList("red", "purple", "yellow", "orange"), mapAll.get("colors"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentNoParams() throws Exception {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> map = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMap, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Collections.emptyMap(), map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentNoMatch() throws Exception {
|
||||
|
||||
MultiValueMap<String, String> params2 = getMatrixVariables("planes");
|
||||
params2.add("colors", "yellow");
|
||||
params2.add("colors", "orange");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> map = (Map<String, String>) this.resolver.resolveArgument(
|
||||
this.paramMapForPathVar, this.mavContainer, this.webRequest, null);
|
||||
|
||||
assertEquals(Collections.emptyMap(), map);
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private MultiValueMap<String, String> getMatrixVariables(String pathVarName) {
|
||||
|
||||
Map<String, MultiValueMap<String, String>> matrixVariables =
|
||||
(Map<String, MultiValueMap<String, String>>) this.request.getAttribute(
|
||||
HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE);
|
||||
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
|
||||
matrixVariables.put(pathVarName, params);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
public void handle(
|
||||
String stringArg,
|
||||
@MatrixVariable Map<String, String> map,
|
||||
@MatrixVariable MultiValueMap<String, String> multivalueMap,
|
||||
@MatrixVariable(pathVar="cars") MultiValueMap<String, String> mapForPathVar,
|
||||
@MatrixVariable("name") Map<String, String> mapWithName) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.web.servlet.mvc.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.ServletRequestBindingException;
|
||||
import org.springframework.web.bind.annotation.MatrixVariable;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
|
||||
/**
|
||||
* Test fixture with {@link MatrixVariableMethodArgumentResolver}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class MatrixVariablesMethodArgumentResolverTests {
|
||||
|
||||
private MatrixVariableMethodArgumentResolver resolver;
|
||||
|
||||
private MethodParameter paramString;
|
||||
private MethodParameter paramColors;
|
||||
private MethodParameter paramYear;
|
||||
|
||||
private ModelAndViewContainer mavContainer;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
this.resolver = new MatrixVariableMethodArgumentResolver();
|
||||
|
||||
Method method = getClass().getMethod("handle", String.class, List.class, int.class);
|
||||
this.paramString = new MethodParameter(method, 0);
|
||||
this.paramColors = new MethodParameter(method, 1);
|
||||
this.paramYear = new MethodParameter(method, 2);
|
||||
|
||||
this.paramColors.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer());
|
||||
|
||||
this.mavContainer = new ModelAndViewContainer();
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
|
||||
|
||||
Map<String, MultiValueMap<String, String>> params = new LinkedHashMap<String, MultiValueMap<String, String>>();
|
||||
this.request.setAttribute(HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE, params);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsParameter() {
|
||||
assertFalse(resolver.supportsParameter(paramString));
|
||||
assertTrue(resolver.supportsParameter(paramColors));
|
||||
assertTrue(resolver.supportsParameter(paramYear));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgument() throws Exception {
|
||||
|
||||
MultiValueMap<String, String> params = getMatrixVariables("cars");
|
||||
params.add("colors", "red");
|
||||
params.add("colors", "green");
|
||||
params.add("colors", "blue");
|
||||
|
||||
assertEquals(Arrays.asList("red", "green", "blue"),
|
||||
this.resolver.resolveArgument(this.paramColors, this.mavContainer, this.webRequest, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentPathVariable() throws Exception {
|
||||
|
||||
getMatrixVariables("cars").add("year", "2006");
|
||||
getMatrixVariables("bikes").add("year", "2005");
|
||||
|
||||
assertEquals("2006", this.resolver.resolveArgument(this.paramYear, this.mavContainer, this.webRequest, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentDefaultValue() throws Exception {
|
||||
assertEquals("2013", resolver.resolveArgument(this.paramYear, this.mavContainer, this.webRequest, null));
|
||||
}
|
||||
|
||||
@Test(expected=ServletRequestBindingException.class)
|
||||
public void resolveArgumentMultipleMatches() throws Exception {
|
||||
|
||||
getMatrixVariables("var1").add("colors", "red");
|
||||
getMatrixVariables("var2").add("colors", "green");
|
||||
|
||||
this.resolver.resolveArgument(this.paramColors, this.mavContainer, this.webRequest, null);
|
||||
}
|
||||
|
||||
@Test(expected=ServletRequestBindingException.class)
|
||||
public void resolveArgumentRequired() throws Exception {
|
||||
resolver.resolveArgument(this.paramColors, this.mavContainer, this.webRequest, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgumentNoMatch() throws Exception {
|
||||
|
||||
MultiValueMap<String, String> params = getMatrixVariables("cars");
|
||||
params.add("anotherYear", "2012");
|
||||
|
||||
assertEquals("2013", this.resolver.resolveArgument(this.paramYear, this.mavContainer, this.webRequest, null));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private MultiValueMap<String, String> getMatrixVariables(String pathVarName) {
|
||||
|
||||
Map<String, MultiValueMap<String, String>> matrixVariables =
|
||||
(Map<String, MultiValueMap<String, String>>) this.request.getAttribute(
|
||||
HandlerMapping.MATRIX_VARIABLES_ATTRIBUTE);
|
||||
|
||||
MultiValueMap<String, String> params = new LinkedMultiValueMap<String, String>();
|
||||
matrixVariables.put(pathVarName, params);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
|
||||
public void handle(
|
||||
String stringArg,
|
||||
@MatrixVariable List<String> colors,
|
||||
@MatrixVariable(value="year", pathVar="cars", required=false, defaultValue="2013") int preferredYear) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -22,9 +22,11 @@ import static org.junit.Assert.assertTrue;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -38,8 +40,10 @@ import org.springframework.context.ApplicationContextInitializer;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.MatrixVariable;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
@@ -52,22 +56,22 @@ import org.springframework.web.servlet.mvc.annotation.UriTemplateServletAnnotati
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
/**
|
||||
* The origin of this test class is {@link UriTemplateServletAnnotationControllerTests}.
|
||||
*
|
||||
* The origin of this test class is {@link UriTemplateServletAnnotationControllerTests}.
|
||||
*
|
||||
* Tests in this class run against the {@link HandlerMethod} infrastructure:
|
||||
* <ul>
|
||||
* <li>RequestMappingHandlerMapping
|
||||
* <li>RequestMappingHandlerAdapter
|
||||
* <li>RequestMappingHandlerMapping
|
||||
* <li>RequestMappingHandlerAdapter
|
||||
* <li>ExceptionHandlerExceptionResolver
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* <p>Rather than against the existing infrastructure:
|
||||
* <ul>
|
||||
* <li>DefaultAnnotationHandlerMapping
|
||||
* <li>AnnotationMethodHandlerAdapter
|
||||
* <li>AnnotationMethodHandlerExceptionResolver
|
||||
* </ul>
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
@@ -80,17 +84,18 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
assertEquals("test-42", response.getContentAsString());
|
||||
assertEquals("test-42-7", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multiple() throws Exception {
|
||||
initServletWithControllers(MultipleUriTemplateController.class);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42/bookings/21-other");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42;q=24/bookings/21-other;q=12");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
assertEquals("test-42-21-other", response.getContentAsString());
|
||||
assertEquals(200, response.getStatus());
|
||||
assertEquals("test-42-q24-21-other-q12", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -99,8 +104,8 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
pathVars.put("hotel", "42");
|
||||
pathVars.put("booking", 21);
|
||||
pathVars.put("other", "other");
|
||||
|
||||
WebApplicationContext wac =
|
||||
|
||||
WebApplicationContext wac =
|
||||
initServlet(new ApplicationContextInitializer<GenericWebApplicationContext>() {
|
||||
public void initialize(GenericWebApplicationContext context) {
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(ModelValidatingViewResolver.class);
|
||||
@@ -109,9 +114,9 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
}
|
||||
}, ViewRenderingController.class);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42/bookings/21-other");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42;q=1,2/bookings/21-other;q=3;r=R");
|
||||
getServlet().service(request, new MockHttpServletResponse());
|
||||
|
||||
|
||||
ModelValidatingViewResolver resolver = wac.getBean(ModelValidatingViewResolver.class);
|
||||
assertEquals(3, resolver.validatedAttrCount);
|
||||
}
|
||||
@@ -166,10 +171,10 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
public void extension() throws Exception {
|
||||
initServletWithControllers(SimpleUriTemplateController.class);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42.xml");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42;jsessionid=c0o7fszeb1;q=24.xml");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
assertEquals("test-42", response.getContentAsString());
|
||||
assertEquals("test-42-24", response.getContentAsString());
|
||||
|
||||
}
|
||||
|
||||
@@ -287,10 +292,11 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
public void customRegex() throws Exception {
|
||||
initServletWithControllers(CustomRegexController.class);
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42;q=1;q=2");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
assertEquals("test-42", response.getContentAsString());
|
||||
assertEquals(200, response.getStatus());
|
||||
assertEquals("test-42-;q=1;q=2-[1, 2]", response.getContentAsString());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -343,7 +349,7 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
@Test
|
||||
public void doIt() throws Exception {
|
||||
initServletWithControllers(Spr6978Controller.class);
|
||||
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo/100");
|
||||
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||
getServlet().service(request, response);
|
||||
@@ -375,9 +381,11 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
public static class SimpleUriTemplateController {
|
||||
|
||||
@RequestMapping("/{root}")
|
||||
public void handle(@PathVariable("root") int root, Writer writer) throws IOException {
|
||||
public void handle(@PathVariable("root") int root, @MatrixVariable(required=false, defaultValue="7") int q,
|
||||
Writer writer) throws IOException {
|
||||
|
||||
assertEquals("Invalid path variable value", 42, root);
|
||||
writer.write("test-" + root);
|
||||
writer.write("test-" + root + "-" + q);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -389,10 +397,12 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
public void handle(@PathVariable("hotel") String hotel,
|
||||
@PathVariable int booking,
|
||||
@PathVariable String other,
|
||||
@MatrixVariable(value="q", pathVar="hotel") int qHotel,
|
||||
@MatrixVariable(value="q", pathVar="other") int qOther,
|
||||
Writer writer) throws IOException {
|
||||
assertEquals("Invalid path variable value", "42", hotel);
|
||||
assertEquals("Invalid path variable value", 21, booking);
|
||||
writer.write("test-" + hotel + "-" + booking + "-" + other);
|
||||
writer.write("test-" + hotel + "-q" + qHotel + "-" + booking + "-" + other + "-q" + qOther);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -401,9 +411,13 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
public static class ViewRenderingController {
|
||||
|
||||
@RequestMapping("/hotels/{hotel}/bookings/{booking}-{other}")
|
||||
public void handle(@PathVariable("hotel") String hotel, @PathVariable int booking, @PathVariable String other) {
|
||||
public void handle(@PathVariable("hotel") String hotel, @PathVariable int booking,
|
||||
@PathVariable String other, @MatrixVariable MultiValueMap<String, String> params) {
|
||||
|
||||
assertEquals("Invalid path variable value", "42", hotel);
|
||||
assertEquals("Invalid path variable value", 21, booking);
|
||||
assertEquals(Arrays.asList("1", "2", "3"), params.get("q"));
|
||||
assertEquals("R", params.getFirst("r"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -499,12 +513,13 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
@Controller
|
||||
public static class CustomRegexController {
|
||||
|
||||
@RequestMapping("/{root:\\d+}")
|
||||
public void handle(@PathVariable("root") int root, Writer writer) throws IOException {
|
||||
assertEquals("Invalid path variable value", 42, root);
|
||||
writer.write("test-" + root);
|
||||
}
|
||||
@RequestMapping("/{root:\\d+}{params}")
|
||||
public void handle(@PathVariable("root") int root, @PathVariable("params") String paramString,
|
||||
@MatrixVariable List<Integer> q, Writer writer) throws IOException {
|
||||
|
||||
assertEquals("Invalid path variable value", 42, root);
|
||||
writer.write("test-" + root + "-" + paramString + "-" + q);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
@@ -515,7 +530,6 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
throws IOException {
|
||||
writer.write("latitude-" + latitude + "-longitude-" + longitude);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -650,9 +664,9 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
public static class ModelValidatingViewResolver implements ViewResolver {
|
||||
|
||||
private final Map<String, Object> attrsToValidate;
|
||||
|
||||
|
||||
int validatedAttrCount;
|
||||
|
||||
|
||||
public ModelValidatingViewResolver(Map<String, Object> attrsToValidate) {
|
||||
this.attrsToValidate = attrsToValidate;
|
||||
}
|
||||
@@ -674,8 +688,8 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// @Ignore("ControllerClassNameHandlerMapping")
|
||||
|
||||
// @Ignore("ControllerClassNameHandlerMapping")
|
||||
// public void controllerClassName() throws Exception {
|
||||
|
||||
// @Ignore("useDefaultSuffixPattern property not supported")
|
||||
@@ -683,5 +697,5 @@ public class UriTemplateServletAnnotationControllerHandlerMethodTests extends Ab
|
||||
|
||||
// @Ignore("useDefaultSuffixPattern property not supported")
|
||||
// public void noDefaultSuffixPattern() throws Exception {
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -84,6 +84,12 @@ public final class DefaultRequestToViewNameTranslatorTests {
|
||||
assertViewName(VIEW_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetViewNameWithSemicolonContent() {
|
||||
request.setRequestURI(CONTEXT_PATH + VIEW_NAME + ";a=A;b=B");
|
||||
assertViewName(VIEW_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetViewNameWithPrefix() {
|
||||
final String prefix = "fiona_";
|
||||
|
||||
Reference in New Issue
Block a user