Spring MVCで現在のURLを取得する最良の方法は何ですか?


95

クライアントがアクティブなリクエストに使用するURLに基​​づいてURLを作成したいと思います。現在のHttpServletRequestオブジェクトを取得するよりも賢いことはありますか?それはgetParameter...()、GETパラメータを含む(そして唯一の)完全なURLを再構築するメソッドです。

明確化:可能であれば、HttpServletRequestオブジェクトの使用を辞退したいと思います。

回答:


111

このデータに簡単にアクセスする方法は2つありますが、インターフェイスでは1回の呼び出しでURL全体を取得することはできません。手動でビルドする必要があります:

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

Spring MVC機能でこれを行う方法については知りません。

どこにも渡さずに現在のリクエストにアクセスする場合は、web.xmlにリスナーを追加する必要があります。

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

次に、これを使用して、現在のスレッドにバインドされたリクエストを取得します。

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

わかりました、これは私がこれまでに行ったことと同様のアプローチです。しかし、私は実際にHttpServletRequestオブジェクトを使用せずにこれを行う方法を探しています。これは、いくつかのヘルパークラス/メソッドを使用しており、リクエストオブジェクトを毎回渡したくないためです。
Koraktor 2009

OK、私はあなたが何を意味しているのかを知っており、現在のリクエストを渡さずにアクセスするために必要な情報を追加しました
Daff、

リスナーについてのリマインダーをありがとう。私はまだSpring(および一般的なJava Web開発)に不慣れです。今、Spring Securityのコードと組み合わせてコードを使用していますUrlUtils。魅力のように機能します。
Koraktor 2009

私の場合、ブラウズURLではなく、関連するビューパスが表示されます。これについて何か考えはありますか?
Ms. Shougat Hossain

76

RequestContextHolder直接使用する代わりにServletUriComponentsBuilder、その静的メソッドを使用することもできます。

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

それらはRequestContextHolder内部で使用しますが、の機能を使用して新しいURLを作成するための追加の柔軟性を提供しますUriComponentsBuilder

例:

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

@ m4rtin私は自分の質問に回答しましたが、最初に問題の解決を手伝ってくれた質問を信用したくありませんでした。
Koraktor

2
また、春5.のために良いが、私は内部のURLを取得することができたConstraintValidatorServletUriComponentsBuilder.fromCurrentRequestUri().toUriString();
GuiRitter 2018年

16

JavaのURIクラスはこれからあなたを助けることができます:

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

その指定ホスト名のみ
Vivex 2015


3

UriComponentsBuilderコントローラメソッドのメソッドシグネチャにを追加することもできます。Springは、現在のリクエストから作成されたビルダーのインスタンスを注入します。

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

ビルダーを使用すると、現在のリクエストに基づいてURIの作成を直接開始できます(パスセグメントの変更など)。

UriComponentsBuilderMethodArgumentResolverも参照してください


挿入されたUriComponentsBuilderものには、リクエストのパスとクエリパラメータが含まれていないことに注意してください。それらにアクセスする必要がServletUriComponentsBuilder.fromCurrentRequest()ある場合はHttpServletRequest、使用するか、インスタンスを挿入して使用しますServletUriComponentsBuilder.fromRequest(request)
Martin Devillers

-1

パスではなくホスト名までのURLが必要な場合は、ApacheのCommon Libを使用StringUtilし、URLから3番目のindexOfまでの部分文字列を抽出します/

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

例:場合fullurlをがありhttps://example.com/path/after/url/、その後 出力がされます https://example.com

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.