4

I have a simple rest controller which captures errors. I want to get the actual URL that the browser sent to server, but the servlet is giving me a different URL.

If I navigate to 127.0.0.1/abc a 404 error is triggered, and it's routed to /error handler as defined. However, the output gives me the result 127.0.0.1/error instead of 127.0.0.1/abc. How can I obtain the original URL?

@RestController
public class IndexController implements ErrorController {

    @RequestMapping("/")
    public String index() {
        return "OK";
    }

    @RequestMapping("/error")
    public String error(HttpServletRequest request) {
        System.out.println("ERR: " + request.getRequestURL() + " : " + request.getRequestURI());
        return "ERR";
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }
}
user2914191
  • 877
  • 1
  • 8
  • 21
  • 1
    You might instead wish to create a class annotated with `@ControllerAdvice`, and use the `@ExceptionHandler` annotation to catch the exception thrown by Spring Boot for the 404 and handle it that way. The following answer provides an example of this: https://stackoverflow.com/a/45510975/2535264 – Tom Catullo Apr 13 '18 at 21:50

1 Answers1

5

You could define your own @ExceptionHandler that will save the original request URI as an attribute on your request before it's handled by /error mapping:

@ExceptionHandler(Exception.class)
public void handleException(HttpServletRequest req, HttpServletResponse resp) throws Exception {
  req.setAttribute("originalUri", req.getRequestURI());
  req.getRequestDispatcher("/error").forward(req, resp);
}

and then read the new originalUri attribute in whatever /error mapping implementation you are using:

@RequestMapping("/error")
public String error(HttpServletRequest request) {
  System.out.println("ERR: " + request.getAttribute("originalUri"));
  return "ERR";
}

You can also try extending other error handling classes available in Spring MVC to add this behavior e.g. ResponseEntityExceptionHandler. Please note that the forward() in my example might be considered superficial as it's ok to return the ResponseEntity from @ExceptionHandler.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111