Qual é a melhor maneira de obter a URL atual no Spring MVC?


95

Eu gostaria de criar URLs com base no URL usado pelo cliente para a solicitação ativa. Existe algo mais inteligente do que pegar o HttpServletRequestobjeto atual e seus getParameter...()métodos para reconstruir a URL completa incluindo (e apenas) seus parâmetros GET.

Esclarecimento: Se possível, desejo desistir de usar um HttpServletRequestobjeto.

Respostas:


111

Bem, existem dois métodos para acessar esses dados mais facilmente, mas a interface não oferece a possibilidade de obter a URL inteira com uma chamada. Você deve construí-lo manualmente:

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

Não sei como fazer isso com as instalações do Spring MVC.

Se você deseja acessar a solicitação atual sem passá-la em todos os lugares, você terá que adicionar um ouvinte no web.xml:

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

Em seguida, use isso para vincular a solicitação ao Thread atual:

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

Ok, esta é uma abordagem semelhante ao que fiz até agora. Mas estou procurando uma maneira de fazer isso sem realmente usar o HttpServletRequestobjeto. Isso ocorre porque estou usando várias classes / métodos auxiliares e não quero passar o objeto de solicitação todas as vezes.
— Koraktor,

Ok, eu sei o que você quer dizer e adicionei as informações de que você precisa para acessar a solicitação atual sem repassá-la.
— Daff,

Obrigado pelo lembrete sobre o ouvinte. Ainda sou novo no Spring (e no desenvolvimento web em Java em geral). Agora estou usando seu código em combinação com o do Spring Security UrlUtils. Funciona como um encanto.
— Koraktor,

No meu caso, ele fornece o caminho de visualização relacionado em vez do URL de navegação. Alguma ideia sobre isso?
— Md. Shougat Hossain

76

Em vez de usar RequestContextHolderdiretamente, você também pode usar ServletUriComponentsBuildere seus métodos estáticos:

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

Eles usam RequestContextHoldernos bastidores, mas fornecem flexibilidade adicional para construir novos URLs usando os recursos do UriComponentsBuilder.

Exemplo:

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

@ m4rtin Eu respondi minha própria pergunta e não queria levar o crédito por quem inicialmente me ajudou a resolver meu problema.
— Koraktor

2
Também bom para o Spring 5. Consegui obter a URL dentro de um ConstraintValidatorcom ServletUriComponentsBuilder.fromCurrentRequestUri().toUriString();.
— GuiRitter

16

A classe URI do Java pode ajudá-lo nisso:

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

está fornecendo apenas o nome do host
— vivex

8

no arquivo jsp:

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

3

Você também pode adicionar um UriComponentsBuilderà assinatura do método do seu método de controlador. O Spring injetará uma instância do construtor criado a partir da solicitação atual.

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

Usando o construtor, você pode começar a criar URIs diretamente com base na solicitação atual, por exemplo, modificar segmentos de caminho.

Veja também UriComponentsBuilderMethodArgumentResolver


Observe que o injetado UriComponentsBuildernão inclui o caminho e os parâmetros de consulta da solicitação. Se você precisar acessá-los, use ServletUriComponentsBuilder.fromCurrentRequest()ou injete uma instância de HttpServletRequeste useServletUriComponentsBuilder.fromRequest(request)
— Martin Devillers

-1

Se você precisar da URL até o nome do host e não o caminho, use a biblioteca comum do Apache StringUtil, e da URL extraia a substring até o terceiro indexOf /.

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

Exemplo: se fullURL for https://example.com/path/after/url/, a saída será https://example.com

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.