Was ist der beste Weg, um die aktuelle URL in Spring MVC zu erhalten?


95

Ich möchte URLs basierend auf der URL erstellen, die vom Client für die aktive Anforderung verwendet wird. Gibt es etwas Klügeres als das aktuelle HttpServletRequestObjekt und seine getParameter...()Methoden zum Wiederherstellen der vollständigen URL einschließlich (und nur) der GET-Parameter?

Klarstellung: Wenn möglich, möchte ich von der Verwendung eines HttpServletRequestObjekts zurücktreten .

Antworten:


111

Nun, es gibt zwei Methoden, um einfacher auf diese Daten zuzugreifen, aber die Schnittstelle bietet nicht die Möglichkeit, die gesamte URL mit einem Aufruf abzurufen. Sie müssen es manuell erstellen:

public static String makeUrl(HttpServletRequest request)
{
    return request.getRequestURL().toString() + "?" + request.getQueryString();
}

Ich weiß nicht, wie ich dies mit Spring MVC-Einrichtungen tun kann.

Wenn Sie auf die aktuelle Anforderung zugreifen möchten, ohne sie überall zu übergeben, müssen Sie einen Listener in der Datei web.xml hinzufügen:

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

Verwenden Sie diese Option, um die Anforderung an den aktuellen Thread zu binden:

((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest()

Ok, das ist ein ähnlicher Ansatz wie bisher. Aber ich suche nach einer Möglichkeit, dies zu tun, ohne das HttpServletRequestObjekt tatsächlich zu verwenden . Dies liegt daran, dass ich mehrere Hilfsklassen / -methoden verwende und das Anforderungsobjekt nicht jedes Mal übergeben möchte.
Koraktor

Ok, ich weiß, was Sie meinen, und habe die Informationen hinzugefügt, die Sie benötigen, um auf die aktuelle Anfrage zuzugreifen, ohne sie weiterzugeben.
Daff

Danke für die Erinnerung an den Hörer. Ich bin noch neu in Spring (und der Java-Webentwicklung im Allgemeinen). Ich verwende jetzt Ihren Code in Kombination mit Spring Security UrlUtils. Klappt wunderbar.
Koraktor

In meinem Fall gibt es den zugehörigen Ansichtspfad an, anstatt die URL zu durchsuchen. Irgendeine Idee dazu?
Md. Shougat Hossain

76

Anstatt RequestContextHolderdirekt zu verwenden, können Sie auch ServletUriComponentsBuilderund seine statischen Methoden verwenden:

  • ServletUriComponentsBuilder.fromCurrentContextPath()
  • ServletUriComponentsBuilder.fromCurrentServletMapping()
  • ServletUriComponentsBuilder.fromCurrentRequestUri()
  • ServletUriComponentsBuilder.fromCurrentRequest()

Sie werden RequestContextHolderunter der Haube verwendet, bieten jedoch zusätzliche Flexibilität beim Erstellen neuer URLs mit den Funktionen von UriComponentsBuilder.

Beispiel:

ServletUriComponentsBuilder builder = ServletUriComponentsBuilder.fromCurrentRequestUri();
builder.scheme("https");
builder.replaceQueryParam("someBoolean", false);
URI newUri = builder.build().toUri();

@ m4rtin Ich beantwortete meine eigene Frage und wollte nicht den Kredit für denjenigen aufnehmen, der mir ursprünglich bei der Lösung meines Problems geholfen hat.
Koraktor

2
Auch gut für Spring 5. Ich habe es geschafft, die URL in ein ConstraintValidatormit zu bekommen ServletUriComponentsBuilder.fromCurrentRequestUri().toUriString();.
GuiRitter

16

Die URI-Klasse von Java kann Ihnen dabei helfen:

public static String getCurrentUrl(HttpServletRequest request){
    URL url = new URL(request.getRequestURL().toString());
    String host  = url.getHost();
    String userInfo = url.getUserInfo();
    String scheme = url.getProtocol();
    String port = url.getPort();
    String path = request.getAttribute("javax.servlet.forward.request_uri");
    String query = request.getAttribute("javax.servlet.forward.query_string");

    URI uri = new URI(scheme,userInfo,host,port,path,query,null)
    return uri.toString();
}

Es gibt nur den Hostnamen
Vivex

8

in jsp Datei:

request.getAttribute("javax.servlet.forward.request_uri")

3

Sie können UriComponentsBuilderder Methodensignatur Ihrer Controller-Methode auch eine hinzufügen . Spring fügt eine Instanz des Builders ein, die aus der aktuellen Anforderung erstellt wurde.

@GetMapping
public ResponseEntity<MyResponse> doSomething(UriComponentsBuilder uriComponentsBuilder) {
    URI someNewUriBasedOnCurrentRequest = uriComponentsBuilder
            .replacePath(null)
            .replaceQuery(null)
            .pathSegment("some", "new", "path")
            .build().toUri();
  //...
}

Mit dem Builder können Sie direkt mit der Erstellung von URIs beginnen, die auf der aktuellen Anforderung basieren, z. B. Pfadsegmente ändern.

Siehe auch UriComponentsBuilderMethodArgumentResolver


Beachten Sie, dass die Injektion UriComponentsBuilderdie Pfad- und Abfrageparameter der Anforderung nicht enthält. Wenn Sie auf diese zugreifen müssen, verwenden ServletUriComponentsBuilder.fromCurrentRequest()oder injizieren Sie eine Instanz von HttpServletRequestund verwenden SieServletUriComponentsBuilder.fromRequest(request)
Martin Devillers

-1

Wenn Sie die URL bis zum Hostnamen und nicht den Pfad benötigen, verwenden Sie die Common Lib StringUtilvon Apache und extrahieren Sie aus der URL den Teilstring bis zum dritten indexOf /.

public static String getURL(HttpServletRequest request){
   String fullURL = request.getRequestURL().toString();
   return fullURL.substring(0,StringUtils.ordinalIndexOf(fullURL, "/", 3)); 
}

Beispiel: Wenn fullurl ist https://example.com/path/after/url/dann Output wird https://example.com

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.