Quelle est la meilleure façon d'obtenir l'URL actuelle dans Spring MVC?


95

Je voudrais créer des URL basées sur l'URL utilisée par le client pour la demande active. Y a-t-il quelque chose de plus intelligent que de prendre l' HttpServletRequestobjet actuel et ses getParameter...()méthodes pour reconstruire l'URL complète, y compris (et seulement) ses paramètres GET.

Clarification: si possible, je souhaite renoncer à utiliser un HttpServletRequestobjet.

Réponses:


111

Eh bien, il existe deux méthodes pour accéder plus facilement à ces données, mais l'interface n'offre pas la possibilité d'obtenir l'URL entière en un seul appel. Vous devez le construire manuellement:

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

Je ne sais pas comment faire cela avec les installations Spring MVC.

Si vous souhaitez accéder à la requête actuelle sans la passer partout, vous devrez ajouter un écouteur dans le fichier web.xml:

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

Et puis utilisez ceci pour obtenir la demande liée au thread actuel:

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

Ok, c'est une approche similaire à ce que j'ai fait jusqu'à présent. Mais je cherche un moyen de faire cela sans utiliser réellement l' HttpServletRequestobjet. C'est parce que j'utilise plusieurs classes / méthodes d'assistance et que je ne veux pas passer l'objet de requête à chaque fois.
Koraktor

Ok, je sais ce que vous voulez dire et j'ai ajouté les informations dont vous avez besoin pour accéder à la demande actuelle sans la passer.
Daff le

Merci pour le rappel concernant l'auditeur. Je suis encore nouveau dans Spring (et dans le développement Web Java en général). J'utilise maintenant votre code en combinaison avec Spring Security UrlUtils. Fonctionne comme un charme.
Koraktor le

Dans mon cas, il donne le chemin de vue associé au lieu de l'URL de navigation. Une idée à ce sujet?
Md. Shougat Hossain

76

Au lieu d'utiliser RequestContextHolderdirectement, vous pouvez également utiliser ServletUriComponentsBuilderet ses méthodes statiques:

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

Ils utilisent RequestContextHoldersous le capot, mais offrent une flexibilité supplémentaire pour créer de nouvelles URL en utilisant les capacités de UriComponentsBuilder.

Exemple:

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

@ m4rtin J'ai répondu à ma propre question et je ne voulais pas m'attribuer le mérite de celui qui m'avait initialement aidé à résoudre mon problème.
Koraktor

2
Aussi bien pour Spring 5. J'ai réussi à obtenir l'URL dans un ConstraintValidatoravec ServletUriComponentsBuilder.fromCurrentRequestUri().toUriString();.
GuiRitter

16

La classe URI de Java peut vous aider à en sortir:

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

son nom d'hôte seulement
vivex

8

dans le fichier jsp:

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

3

Vous pouvez également ajouter un UriComponentsBuilderà la signature de méthode de votre méthode de contrôleur. Spring injectera une instance du générateur créée à partir de la requête actuelle.

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

En utilisant le générateur, vous pouvez directement commencer à créer des URI basés sur la demande actuelle, par exemple modifier les segments de chemin.

Voir aussi UriComponentsBuilderMethodArgumentResolver


Notez que l'injecté UriComponentsBuildern'inclut pas le chemin et les paramètres de requête de la requête. Si vous avez besoin d'accéder à ceux-ci, utilisez ServletUriComponentsBuilder.fromCurrentRequest()ou injectez une instance de HttpServletRequestet utilisezServletUriComponentsBuilder.fromRequest(request)
Martin Devillers

-1

Si vous avez besoin de l'URL jusqu'au nom d'hôte et non du chemin, utilisez la bibliothèque commune d'Apache StringUtil, et à partir de l'URL, extrayez la sous-chaîne jusqu'au troisième indexOf /.

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

Exemple: si fullURL est https://example.com/path/after/url/alors Output sera https://example.com

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.