EN
Spring Boot 2 - request mapping with wildcard parameter (/path/**)
6 points
In this short article, we would like to show how to get wildcard request parameters (under stars parameter from /some/path/**
) from URL in Spring Boot 2.
Quick solution:
xxxxxxxxxx
1
package example.controllers;
2
3
import org.springframework.beans.factory.annotation.Autowired;
4
import org.springframework.http.ResponseEntity;
5
import org.springframework.stereotype.Controller;
6
import org.springframework.util.PathMatcher;
7
import org.springframework.web.bind.annotation.PathVariable;
8
import org.springframework.web.bind.annotation.RequestMapping;
9
import org.springframework.web.bind.annotation.RequestMethod;
10
import org.springframework.web.servlet.HandlerMapping;
11
12
import javax.servlet.http.HttpServletRequest;
13
14
15
public class ExampleController {
16
17
18
private PathMatcher pathMatcher;
19
20
private String getWildcardParam(HttpServletRequest request) {
21
String patternAttribute = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
22
String mappingAttribute = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
23
return this.pathMatcher.extractPathWithinPattern(patternAttribute, mappingAttribute);
24
}
25
26
(
27
method = RequestMethod.GET,
28
value = "/items/{itemId}/**"
29
)
30
public ResponseEntity<String> getItem(HttpServletRequest request, String itemId) {
31
String wildcardParam = this.getWildcardParam(request); // <--- extracts all data located under **
32
33
// Some logic here ...
34
}
35
}
This section contains an example source code, how to create and use simple @WildcardParam
annotation.
Simple steps:
- create wildcard annotation to simplify controller mappings usage,
- register wildcard annotation in application configuration,
- use wildcard parameters in
@PathVariable
way.
ExampleController.java file:
xxxxxxxxxx
1
package example.controllers;
2
3
import example.annotations.WildcardParam;
4
import org.springframework.beans.factory.annotation.Autowired;
5
import org.springframework.http.HttpStatus;
6
import org.springframework.http.ResponseEntity;
7
import org.springframework.stereotype.Controller;
8
import org.springframework.web.bind.annotation.*;
9
import org.springframework.web.servlet.HandlerMapping;
10
11
import javax.servlet.ServletException;
12
import javax.servlet.http.HttpServletRequest;
13
import javax.servlet.http.Part;
14
import java.io.IOException;
15
import java.net.URISyntaxException;
16
import java.util.Collection;
17
import java.util.function.Function;
18
19
20
public class ExampleController {
21
22
(
23
method = RequestMethod.GET,
24
value = "/items/{itemId}/**"
25
)
26
public ResponseEntity<String> getItem(
27
String itemId,
28
String itemResource // <--- contains all data located under **
29
) {
30
// Some logic here ...
31
}
32
}
WildcardParam.java file:
xxxxxxxxxx
1
package example.annotations;
2
3
import org.springframework.core.MethodParameter;
4
import org.springframework.util.PathMatcher;
5
import org.springframework.web.bind.support.WebDataBinderFactory;
6
import org.springframework.web.context.request.NativeWebRequest;
7
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
8
import org.springframework.web.method.support.ModelAndViewContainer;
9
import org.springframework.web.servlet.HandlerMapping;
10
11
import javax.servlet.http.HttpServletRequest;
12
import java.lang.annotation.*;
13
14
ElementType.PARAMETER) (
15
RetentionPolicy.RUNTIME) (
16
public @interface WildcardParam {
17
18
class Resolver implements HandlerMethodArgumentResolver {
19
20
private PathMatcher pathMatcher;
21
22
public Resolver(PathMatcher pathMatcher) {
23
this.pathMatcher = pathMatcher;
24
}
25
26
27
public boolean supportsParameter(MethodParameter methodParameter) {
28
Annotation annotation = methodParameter.getParameterAnnotation(WildcardParam.class);
29
return annotation != null;
30
}
31
32
33
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modeContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
34
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
35
if (servletRequest == null) {
36
return null;
37
}
38
String patternAttribute = (String) servletRequest.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
39
String mappingAttribute = (String) servletRequest.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
40
return this.pathMatcher.extractPathWithinPattern(patternAttribute, mappingAttribute);
41
}
42
}
43
}
MVCConfig.java file:
xxxxxxxxxx
1
package example.config;
2
3
import example.annotations.WildcardParam;
4
import org.springframework.beans.factory.annotation.Autowired;
5
import org.springframework.context.annotation.Configuration;
6
import org.springframework.util.PathMatcher;
7
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
8
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
9
10
import java.util.List;
11
12
13
public class MVCConfig implements WebMvcConfigurer {
14
15
16
private PathMatcher pathMatcher; // or replace it with bean creation function
17
18
19
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
20
resolvers.add(new WildcardParam.Resolver(this.pathMatcher));
21
}
22
}