/** * Return the list of argument resolvers to use for {@code @InitBinder} * methods including built-in and custom resolvers. */ private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(); // Annotation-based argument resolution resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); resolvers.add(new RequestParamMapMethodArgumentResolver()); resolvers.add(new PathVariableMethodArgumentResolver()); resolvers.add(new PathVariableMapMethodArgumentResolver()); resolvers.add(new MatrixVariableMethodArgumentResolver()); resolvers.add(new MatrixVariableMapMethodArgumentResolver()); resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); resolvers.add(new SessionAttributeMethodArgumentResolver()); resolvers.add(new RequestAttributeMethodArgumentResolver()); // Type-based argument resolution resolvers.add(new ServletRequestMethodArgumentResolver()); resolvers.add(new ServletResponseMethodArgumentResolver()); // Custom arguments if (getCustomArgumentResolvers() != null) { resolvers.addAll(getCustomArgumentResolvers()); } // Catch-all resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); return resolvers; }
@Override public void contributeMethodArgument(MethodParameter parameter, @Nullable Object value, UriComponentsBuilder builder, Map<String, Object> uriVariables, ConversionService conversionService) { Class<?> paramType = parameter.getNestedParameterType(); if (Map.class.isAssignableFrom(paramType) || MultipartFile.class == paramType || Part.class == paramType) { return; } RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class); String name = (requestParam == null || StringUtils.isEmpty(requestParam.name()) ? parameter.getParameterName() : requestParam.name()); Assert.state(name != null, "Unresolvable parameter name"); if (value == null) { if (requestParam != null && (!requestParam.required() || !requestParam.defaultValue().equals(ValueConstants.DEFAULT_NONE))) { return; } builder.queryParam(name); } else if (value instanceof Collection) { for (Object element : (Collection<?>) value) { element = formatUriValue(conversionService, TypeDescriptor.nested(parameter, 1), element); builder.queryParam(name, element); } } else { builder.queryParam(name, formatUriValue(conversionService, new TypeDescriptor(parameter), value)); } }
@Test public void supportsParameter() { resolver = new RequestParamMethodArgumentResolver(null, true); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertFalse(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param)); assertTrue(resolver.supportsParameter(param));
@Test @SuppressWarnings("rawtypes") public void missingOptionalParamArray() throws Exception { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); initializer.setConversionService(new DefaultConversionService()); WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, Integer[].class); Object result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.empty(), result); result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.class, result.getClass()); assertFalse(((Optional) result).isPresent()); }
public boolean supportsParameter(MethodParameter parameter) { boolean supportsParameter = super.supportsParameter(parameter); if (!supportsParameter) { if (this.useOwnDefaultResolution) return isSupportsProperty(parameter.getNestedParameterType()); } return supportsParameter; }
@Test @SuppressWarnings("rawtypes") public void missingOptionalParamValue() throws Exception { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); initializer.setConversionService(new DefaultConversionService()); WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, Integer.class); Object result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.empty(), result); result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.class, result.getClass()); assertFalse(((Optional) result).isPresent()); }
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); resolvers.add(new RequestParamMapMethodArgumentResolver()); resolvers.add(new PathVariableMethodArgumentResolver()); resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); resolvers.add(new ServletModelAttributeMethodProcessor(true));
@Override public void contributeMethodArgument(MethodParameter parameter, @Nullable Object value, UriComponentsBuilder builder, Map<String, Object> uriVariables, ConversionService conversionService) { Class<?> paramType = parameter.getNestedParameterType(); if (Map.class.isAssignableFrom(paramType) || MultipartFile.class == paramType || Part.class == paramType) { return; } RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class); String name = (requestParam == null || StringUtils.isEmpty(requestParam.name()) ? parameter.getParameterName() : requestParam.name()); Assert.state(name != null, "Unresolvable parameter name"); if (value == null) { if (requestParam != null && (!requestParam.required() || !requestParam.defaultValue().equals(ValueConstants.DEFAULT_NONE))) { return; } builder.queryParam(name); } else if (value instanceof Collection) { for (Object element : (Collection<?>) value) { element = formatUriValue(conversionService, TypeDescriptor.nested(parameter, 1), element); builder.queryParam(name, element); } } else { builder.queryParam(name, formatUriValue(conversionService, new TypeDescriptor(parameter), value)); } }
@Test @SuppressWarnings("rawtypes") public void resolveOptionalParamList() throws Exception { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); initializer.setConversionService(new DefaultConversionService()); WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, List.class); Object result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.empty(), result); request.addParameter("name", "123", "456"); result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.class, result.getClass()); assertEquals(Arrays.asList("123", "456"), ((Optional) result).get()); }
/** * Return the list of argument resolvers to use for {@code @InitBinder} * methods including built-in and custom resolvers. */ private List<HandlerMethodArgumentResolver> getDefaultInitBinderArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(); // Annotation-based argument resolution resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); resolvers.add(new RequestParamMapMethodArgumentResolver()); resolvers.add(new PathVariableMethodArgumentResolver()); resolvers.add(new PathVariableMapMethodArgumentResolver()); resolvers.add(new MatrixVariableMethodArgumentResolver()); resolvers.add(new MatrixVariableMapMethodArgumentResolver()); resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); resolvers.add(new SessionAttributeMethodArgumentResolver()); resolvers.add(new RequestAttributeMethodArgumentResolver()); // Type-based argument resolution resolvers.add(new ServletRequestMethodArgumentResolver()); resolvers.add(new ServletResponseMethodArgumentResolver()); // Custom arguments if (getCustomArgumentResolvers() != null) { resolvers.addAll(getCustomArgumentResolvers()); } // Catch-all resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); return resolvers; }
@Override public void contributeMethodArgument(MethodParameter parameter, @Nullable Object value, UriComponentsBuilder builder, Map<String, Object> uriVariables, ConversionService conversionService) { Class<?> paramType = parameter.getNestedParameterType(); if (Map.class.isAssignableFrom(paramType) || MultipartFile.class == paramType || Part.class == paramType) { return; } RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class); String name = (requestParam == null || StringUtils.isEmpty(requestParam.name()) ? parameter.getParameterName() : requestParam.name()); Assert.state(name != null, "Unresolvable parameter name"); if (value == null) { if (requestParam != null && (!requestParam.required() || !requestParam.defaultValue().equals(ValueConstants.DEFAULT_NONE))) { return; } builder.queryParam(name); } else if (value instanceof Collection) { for (Object element : (Collection<?>) value) { element = formatUriValue(conversionService, TypeDescriptor.nested(parameter, 1), element); builder.queryParam(name, element); } } else { builder.queryParam(name, formatUriValue(conversionService, new TypeDescriptor(parameter), value)); } }
@Test @SuppressWarnings("rawtypes") public void missingOptionalParamList() throws Exception { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); initializer.setConversionService(new DefaultConversionService()); WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, List.class); Object result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.empty(), result); result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.class, result.getClass()); assertFalse(((Optional) result).isPresent()); }
@Test public void supportsParameter() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(); resolvers.add(new RequestParamMethodArgumentResolver(false)); resolvers.add(new RequestHeaderMethodArgumentResolver(null)); resolvers.add(new RequestParamMethodArgumentResolver(true)); Method method = ClassUtils.getMethod(this.getClass(), "handleRequest", String.class, String.class, String.class); CompositeUriComponentsContributor contributor = new CompositeUriComponentsContributor(resolvers); assertTrue(contributor.supportsParameter(new MethodParameter(method, 0))); assertTrue(contributor.supportsParameter(new MethodParameter(method, 1))); assertFalse(contributor.supportsParameter(new MethodParameter(method, 2))); }
@Override public void contributeMethodArgument(MethodParameter parameter, @Nullable Object value, UriComponentsBuilder builder, Map<String, Object> uriVariables, ConversionService conversionService) { Class<?> paramType = parameter.getNestedParameterType(); if (Map.class.isAssignableFrom(paramType) || MultipartFile.class == paramType || Part.class == paramType) { return; } RequestParam requestParam = parameter.getParameterAnnotation(RequestParam.class); String name = (requestParam == null || StringUtils.isEmpty(requestParam.name()) ? parameter.getParameterName() : requestParam.name()); Assert.state(name != null, "Unresolvable parameter name"); if (value == null) { if (requestParam != null && (!requestParam.required() || !requestParam.defaultValue().equals(ValueConstants.DEFAULT_NONE))) { return; } builder.queryParam(name); } else if (value instanceof Collection) { for (Object element : (Collection<?>) value) { element = formatUriValue(conversionService, TypeDescriptor.nested(parameter, 1), element); builder.queryParam(name, element); } } else { builder.queryParam(name, formatUriValue(conversionService, new TypeDescriptor(parameter), value)); } }
@Test @SuppressWarnings("rawtypes") public void resolveOptionalParamArray() throws Exception { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); initializer.setConversionService(new DefaultConversionService()); WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, Integer[].class); Object result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.empty(), result); request.addParameter("name", "123", "456"); result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.class, result.getClass()); assertArrayEquals(new Integer[] {123, 456}, (Integer[]) ((Optional) result).get()); }
resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); resolvers.add(new RequestParamMapMethodArgumentResolver()); resolvers.add(new PathVariableMethodArgumentResolver()); resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); resolvers.add(new ServletModelAttributeMethodProcessor(true));
@Test(expected = MissingServletRequestParameterException.class) public void missingRequestParam() throws Exception { MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(String[].class); resolver.resolveArgument(param, null, webRequest, null); fail("Expected exception"); }
@Test public void createBinderTypeConversion() throws Exception { this.webRequest.getNativeRequest(MockHttpServletRequest.class).setParameter("requestParam", "22"); this.argumentResolvers.addResolver(new RequestParamMethodArgumentResolver(null, false)); WebDataBinderFactory factory = createFactory("initBinderTypeConversion", WebDataBinder.class, int.class); WebDataBinder dataBinder = factory.createBinder(this.webRequest, null, "foo"); assertNotNull(dataBinder.getDisallowedFields()); assertEquals("requestParam-22", dataBinder.getDisallowedFields()[0]); }
@Test @SuppressWarnings("rawtypes") public void resolveOptionalParamValue() throws Exception { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); initializer.setConversionService(new DefaultConversionService()); WebDataBinderFactory binderFactory = new DefaultDataBinderFactory(initializer); MethodParameter param = this.testMethod.annotPresent(RequestParam.class).arg(Optional.class, Integer.class); Object result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.empty(), result); request.addParameter("name", "123"); result = resolver.resolveArgument(param, null, webRequest, binderFactory); assertEquals(Optional.class, result.getClass()); assertEquals(123, ((Optional) result).get()); }
@Test public void invokeAndHandle_DynamicReturnValue() throws Exception { this.argumentResolvers.addResolver(new RequestParamMethodArgumentResolver(null, false)); this.returnValueHandlers.addHandler(new ViewMethodReturnValueHandler()); this.returnValueHandlers.addHandler(new ViewNameMethodReturnValueHandler()); // Invoke without a request parameter (String return value) ServletInvocableHandlerMethod handlerMethod = getHandlerMethod(new Handler(), "dynamicReturnValue", String.class); handlerMethod.invokeAndHandle(this.webRequest, this.mavContainer); assertNotNull(this.mavContainer.getView()); assertEquals(RedirectView.class, this.mavContainer.getView().getClass()); // Invoke with a request parameter (RedirectView return value) this.request.setParameter("param", "value"); handlerMethod.invokeAndHandle(this.webRequest, this.mavContainer); assertEquals("view", this.mavContainer.getViewName()); }