Qual è il modo migliore per ottenere l'URL corrente in Spring MVC?


95

Vorrei creare URL basati sull'URL utilizzato dal client per la richiesta attiva. C'è qualcosa di più intelligente che prendere l' HttpServletRequestoggetto corrente ei suoi getParameter...()metodi per ricostruire l'URL completo includendo (e solo) i suoi parametri GET.

Chiarimento: se possibile desidero dimettermi dall'uso di un HttpServletRequestoggetto.

Risposte:


111

Bene, ci sono due metodi per accedere più facilmente a questi dati, ma l'interfaccia non offre la possibilità di ottenere l'intero URL con una chiamata. Devi costruirlo manualmente:

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

Non conosco un modo per farlo con le strutture Spring MVC.

Se vuoi accedere alla richiesta corrente senza passarla ovunque dovrai aggiungere un listener nel web.xml:

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

E quindi usa questo per ottenere la richiesta associata al thread corrente:

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

Ok, questo è un approccio simile a quello che ho fatto finora. Ma sto cercando un modo per farlo senza utilizzare effettivamente l' HttpServletRequestoggetto. Questo perché sto usando diverse classi / metodi di supporto e non voglio passare l'oggetto richiesta ogni volta.
Koraktor,

Ok, so cosa intendi e ho aggiunto le informazioni necessarie per accedere alla richiesta corrente senza passarla in giro.
Daff

Grazie per il promemoria sull'ascoltatore. Sono ancora nuovo di Spring (e dello sviluppo web Java in generale). Ora sto usando il tuo codice in combinazione con Spring Security UrlUtils. Funziona come un fascino.
Koraktor,

Nel mio caso fornisce il percorso di visualizzazione correlato anziché l'URL di navigazione. Qualche idea su questo?
Md. Shougat Hossain

76

Invece di usare RequestContextHolderdirettamente, puoi anche usare ServletUriComponentsBuilderei suoi metodi statici:

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

Usano RequestContextHoldersotto il cofano, ma forniscono ulteriore flessibilità per creare nuovi URL utilizzando le funzionalità di UriComponentsBuilder.

Esempio:

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

@ m4rtin Ho risposto alla mia domanda e non volevo prendermi il merito di colui che inizialmente mi ha aiutato a risolvere il mio problema.
Koraktor

2
Buono anche per la primavera 5. Sono riuscito a ottenere l'URL all'interno di un ConstraintValidatorcon ServletUriComponentsBuilder.fromCurrentRequestUri().toUriString();.
GuiRitter

16

La classe URI di Java può aiutarti in questo:

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

fornisce solo il nome host
vivex il

8

nel file jsp:

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

3

È inoltre possibile aggiungere un UriComponentsBuilderalla firma del metodo del metodo del controller. Spring inietterà un'istanza del builder creata dalla richiesta corrente.

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

Utilizzando il builder è possibile iniziare direttamente a creare URI in base alla richiesta corrente, ad esempio modificare i segmenti di percorso.

Vedi anche UriComponentsBuilderMethodArgumentResolver


Si noti che l'injected UriComponentsBuildernon include il percorso ei parametri di query della richiesta. Se è necessario accedere a quelli, utilizzare ServletUriComponentsBuilder.fromCurrentRequest()o iniettare un'istanza HttpServletRequeste utilizzareServletUriComponentsBuilder.fromRequest(request)
Martin Devillers

-1

Se hai bisogno dell'URL fino al nome host e non del percorso usa Common Lib di Apache StringUtile dall'URL estrai la sottostringa fino al terzo indexOf /.

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

Esempio: Se fullurl è https://example.com/path/after/url/poi uscita sarà https://example.com

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.