falak guglani
falak guglani

Reputation: 21

Using Spring's @RequestMapping with multiple endpoints

@RequestMapping(value = { "/abc/xyz/redirect",
            "/abc/xyz/redirect/{refPath}",
            "/abc/xyz/redirect/*" })
public String handleRequest (ServletRequest request, ServletResponse response,
@PathVariable String refPath,
@RequestParam(value = "subscriptionId", required = false) String customId)

I implemented this logic to add the refPath, but afterwards I started receiving 500 with "refPath" is not available even though the endpoint hit was /abc/xyz/redirect?customId=123

Can someone please help me understand why it is not being mapped to /abc/xyz/redirect?

I tried to work after making @PathVariable to false. It worked but still did not get why it was not matched with the current config?

Upvotes: 2

Views: 219

Answers (2)

Nirbhay Mishra
Nirbhay Mishra

Reputation: 1648

The @PathVariable annotation in Spring MVC indicates that a method parameter should be bound to a URI template variable. When you have multiple URI patterns mapped to the same method, Spring needs to resolve which variables to bind based on the incoming request.

In your case, you have three URI patterns mapped to the handleRequest method:

"/abc/xyz/redirect" 
"/abc/xyz/redirect/{refPath}" 
"/abc/xyz/redirect/*" 

When a request comes in, Spring needs to determine which pattern to match. If the request URL is "/abc/xyz/redirect?customId=123", it matches the first pattern without {refPath} variable, hence refPath remains null because it is not part of the URI.

So Either

  1. Change the Order of Mappings
  2. Make refPath Optional

Upvotes: 1

tuhin47
tuhin47

Reputation: 6058

In your @RequestMapping annotation, you have defined three different paths:

  • /abc/xyz/redirect
  • /abc/xyz/redirect/{refPath}
  • /abc/xyz/redirect/*

When you hit the endpoint /abc/xyz/redirect?customId=123, it does not match any of the defined paths exactly. The first path (/abc/xyz/redirect) does not have any path variables or wildcards, so it expects the request URL to exactly match /abc/xyz/redirect without any additional query parameters.

To make it work with query parameters like customId=123, you can modify your method signature to remove the @PathVariable annotation for refPath and handle it as a query parameter instead. Here's an updated version of your method:

@RequestMapping(value = { "/abc/xyz/redirect",
            "/abc/xyz/redirect/{refPath}",
            "/abc/xyz/redirect/*" })
public String handleRequest (ServletRequest request, ServletResponse response,
@RequestParam(value = "refPath", required = false) String refPath,
@RequestParam(value = "subscriptionId", required = false) String customId) {
    // Your method logic here
}

By changing @PathVariable to @RequestParam for refPath, you can now access refPath as a query parameter in the URL /abc/xyz/redirect?refPath=value&customId=123.

This change allows the method to be more flexible in handling different types of requests, including those with query parameters.

Upvotes: 1

Related Questions