1

I have following request parameters.

a
b
c
d
e
f

Request can contain all the parameters or some of them. I am currently using regex /** to resolve this.

Is there any way to explicitly mention the request mapping instead ** and say it is optional. And any order also should match.

/a/1/b/f2

and

/b/f2/a/1

Both should match that mapping.

buræquete
  • 14,226
  • 4
  • 44
  • 89
Gibbs
  • 21,904
  • 13
  • 74
  • 138
  • You should use RequestBody rather request param, because RequestParam can generate issue if you are not fixing place of each param. or elaborate your question that why you have this specific requirement – bharatpatel Jul 17 '19 at 06:41
  • You don't have request parameters but rather path variables. I strongly suggest to look for another way of supplying the information. Actual request parameters would be ok, as well as a json serialized body. – M. Deinum Jul 17 '19 at 08:41

2 Answers2

1

You can make a RequestParam optional by adding the required flag false.

@RequestParam(value = "a", required=false)

For PathVariables i would try to use the Optional type but i have never done this before.

@PathVariable Optional<String> a for /path/{a}

arnonuem
  • 1,317
  • 6
  • 19
  • I think I used the terminology wrong. My request would be something like `/a/1/b/wew/c/343sd` not `?a=1&b=wew` – Gibbs Jul 17 '19 at 06:41
  • 3
    So you are talking about pathvariables then – arnonuem Jul 17 '19 at 06:45
  • Yes Yes. That's the word I was searching for. – Gibbs Jul 17 '19 at 06:45
  • 3
    @GoMan then don't. path variables order matter, and they're not optional. For optional parameters, use request parameters or a request body. – JB Nizet Jul 17 '19 at 06:50
  • @JBNizet will [this](https://stackoverflow.com/questions/17821731/spring-mvc-how-to-indicate-whether-a-path-variable-is-required-or-not) work? – Gibbs Jul 17 '19 at 06:52
  • The flexibility you are looking for can be achieved with Requestparams because there the order does not matter. – arnonuem Jul 17 '19 at 06:53
  • 4
    The important question is not "will it work?". The important question is "are path variables the right tool for the job?". they're not. – JB Nizet Jul 17 '19 at 06:55
  • @GoMan why you need it as path variable instead of request param? – Dipin Jul 17 '19 at 07:06
1

There is no way to achieve this via @PathVariable's. If you want the flexibility of random order & number of path variables. You can just do the following;

@GetMapping("/myEndpoint/**")
public void theEndpoint(HttpServletRequest request) {
    String requestURI = request.getRequestURI();
    Stream.of(requestURI.split("myEndpoint/")[1].split("/")).forEach(System.out::println);
}

You can put a .filter(StringUtils::isNotBlank) in case /myEndpoint/a///b/c

Will give you

a
1
b
f2
d
x

when you call /myEndpoint/a/1/b/f2/d/x

b
f2
1

when you call /myEndpoint/b/f2/1


Also, be aware that you'd need some anchor base in your endpoint, e.g. /myEndpoint. Otherwise all your other endpoints will be conflicted with this endpoint.

ps. Better to use request params for such inputs tbh, not sure your requirement here, but just FYI. It is not the best to have such a hacky structure really...

buræquete
  • 14,226
  • 4
  • 44
  • 89
  • 1
    @GoMan Yeah I know, but are you already doing something like this? Parsing request URI from `HttpServletRequest` ? That is the main part, otherwise I would recommend using a `POST` method with a request body or using some request params... – buræquete Jul 18 '19 at 06:34
  • 1
    @GoMan or if you have a limited set of params, you can define multiple endpoints with increasing path variables in the path, `/var`, `/var/var2`, `/var/var2/var3` etc. Then call same method from all controllers passing the input set of vars, and play with them, but they will be anonymous of course, same as in my answer. So you won't know whether the first `var` is of `a` or `b` etc. Doing that is impossible without request params or body... – buræquete Jul 18 '19 at 06:39