Spring MVC: How to modify @Pathvariable(URI) in Interceptor before going to controller?

3.3k views Asked by At

I was get Controller's @PathVariable in Pre-Handler Interceptor.

Map<String, String> pathVariable = (Map<String, String>) request.getAttribute( HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE );

But I wish to modify @PathVariable value(below).

@RequestMapping(value = "{uuid}/attributes", method = RequestMethod.POST)
public ResponseEntity<?> addAttribute(@PathVariable("uuid") String uuid, HttpServletRequest request, HttpServletResponse response) {

 //LOGIC
}

How to modify @PathVariable("uuid") value in interceptor before going to controller?? I'm using Spring 4.1 and JDK 1.6. I can't upgrade its.

2

There are 2 answers

1
AudioBubble On

Try below given code.

public class UrlOverriderInterceptor implements ClientHttpRequestInterceptor {

private final String urlBase;

public UrlOverriderInterceptor(String urlBase) {
    this.urlBase = urlBase;
}

private static Logger LOGGER = AppLoggerFactory.getLogger(UrlOverriderInterceptor.class);

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
    URI uri = request.getURI();
    LOGGER.warn("overriding {0}", uri);

    return execution.execute(new MyHttpRequestWrapper(request), body);

}

private class MyHttpRequestWrapper extends HttpRequestWrapper {
    public MyHttpRequestWrapper(HttpRequest request) {
        super(request);
    }

    @Override
    public URI getURI() {
        try {
            return new URI(UrlUtils.composeUrl(urlBase, super.getURI().toString())); //change accordingly 
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
}

}

0
M. Deinum On

A general use for interceptors is to apply generic functionality to controllers. I.e. default data shown on all pages, security etc. You want to use it for a single piece of functionality which you generallly shouldn't do.

What are you trying to achieve isn't possible with an interceptor. As first the method to execute is detected based on the mapping data. Before executing the method the interceptor is executed. In this you basically want to change the incoming request and to execute a different method. But the method is already selected, hence it won't work.

As you eventually want to call the same method simply add another request handling method which either eventually calls addAttribute or simply redirects to the URL with the UUID.

@RequestMapping("<your-url>")
public ResponseEntity<?> addAttributeAlternate(@RequestParam("secret") String secret, HttpServletRequest request, HttpServletResponse response) {

    String uuid = // determine UUID based on request
    return this.addAttribute(uuid,request,response);
}