When the request is being forwarded, e.g. from a reverse proxy, the HttpServletRequest.getRequestURL() method will not return the forwarded url but the local url.
When the x-forwarded-* Headers are set, this can be easily handled:
public static String getCurrentUrl(HttpServletRequest request) {
    String forwardedHost = request.getHeader("x-forwarded-host");
    if(forwardedHost == null) {
        return request.getRequestURL().toString();
    }
    String scheme = request.getHeader("x-forwarded-proto");
    String prefix = request.getHeader("x-forwarded-prefix");
    return scheme + "://" + forwardedHost + prefix + request.getRequestURI();
}
This lacks the Query part, but that can be appended as supposed in the other answers. I came here, because I specifically needed that forwarding stuff and can hopefully help someone out with that.