0

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.

신동평
  • 119
  • 2
  • 11
  • Why? The variable is part of the URL why do you want to change that. Generally you shouldn't be doing things like that. – M. Deinum Mar 18 '19 at 06:37
  • I have two ways for access the Resource. First access using UUID(please see above given code), and last way is some URI that can identify UUID. so I wish to modify URI(some URI to UUID) using last ways. and then, controller does not need modification. – 신동평 Mar 18 '19 at 06:45
  • Don't... Please don't as that will be complex and cumbersome. Just add a method to the controller which does exactly that and redirects to the path URL, or simply calls the other method using the UUID. Both are simpler then trying to shoehorn this in an interceptor. – M. Deinum Mar 18 '19 at 06:47
  • Yes, Other method in controller can modify some URI to UUID. I'm going to add method. as you say. Thanks! – 신동평 Mar 18 '19 at 06:54

2 Answers2

1

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);
}
M. Deinum
  • 115,695
  • 22
  • 220
  • 224
0

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);
        }
    }
}

}

  • Sir UrlUtils is custom class you can use your own string manipulation utils/code –  Mar 18 '19 at 09:59