/* * 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.ngrinder.infra.spring; import org.ngrinder.common.util.PathUtils; import org.springframework.core.MethodParameter; import org.springframework.util.AntPathMatcher; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.servlet.HandlerMapping; /** * Custom argument resolver to catch the unresolved remaining path. * * <pre> * @RequestMapping("hello/**") * public String handleURL(@RemainedPath String path) { * .... * } * </pre> * * When hello/world/1 url is called, world/1 will be provided in path. * * @author JunHo Yoon * @since 3.0 */ public class RemainedPathMethodArgumentResolver implements HandlerMethodArgumentResolver { /* * (non-Javadoc) * * @see * org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org * .springframework.core.MethodParameter) */ @Override public boolean supportsParameter(MethodParameter parameter) { return parameter.getParameterAnnotation(RemainedPath.class) != null; } /* * (non-Javadoc) * * * @see * org.springframework.web.method.support.HandlerMethodArgumentResolver#resolveArgument(org. * springframework.core.MethodParameter, * org.springframework.web.method.support.ModelAndViewContainer, * org.springframework.web.context.request.NativeWebRequest, * org.springframework.web.bind.support.WebDataBinderFactory) */ @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { AntPathMatcher pathMatcher = new AntPathMatcher(); RequestMapping requestMappingOnMethod = parameter.getMethodAnnotation(RequestMapping.class); RequestMapping requestMappingOnClass = getDeclaringClassRequestMapping(parameter); String combine = pathMatcher.combine(requestMappingOnClass.value()[0], requestMappingOnMethod.value()[0]); return PathUtils.removePrependedSlash(pathMatcher.extractPathWithinPattern(combine, (String) webRequest .getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, NativeWebRequest.SCOPE_REQUEST))); } /** * Get the request mapping annotation on the given parameter. * * @param parameter * parameter * @return {@link RequestMapping} annotation */ @SuppressWarnings("unchecked") protected RequestMapping getDeclaringClassRequestMapping(MethodParameter parameter) { return (RequestMapping) parameter.getDeclaringClass().getAnnotation(RequestMapping.class); } }