daisuzz.log

UriComponentsBuilderで設定したクエリ文字列の値がnullの場合にクエリ全体を非表示にする

Spring Frameworkでは、UriComponentsBuilderServletUriComponetnsBulder, MvcUriComponentsBuilder, もしくはUriBuilderインターフェースを実装したクラスを使うことでURIを簡単に作ることができます。

たとえば、以下のコードのようにUriComponetsBuilderを使うと、http://localhost:8080?query=valueというURIを作成できます。

    @GetMapping
    public ResponseEntity<String> sample() {

        URI url = UriComponentsBuilder.fromUriString("http://localhost:8080")
                .queryParam("query", "value")
                .build()
                .toUri();

        return ResponseEntity.created(url).build();
    }

Spring5.2以前は、queryParam()replaceQueryParam()を使って設定したクエリパラメータの値がnullの場合、クエリパラメータ名がURIに残されたまま生成されるため、明示的に値が空かどうかチェックしてクエリを設定する必要があります。

たとえば以下のようにクエリパラメータを設定すると、http://localhost:8080?replaceQuery&queryParamというURIが生成されます。

    @GetMapping
    public ResponseEntity<String> sample() {

        String queryValue = null;

        URI url = UriComponentsBuilder.fromUriString("http://localhost:8080")
                .replaceQueryParam("replaceQuery", queryValue)
                .queryParam("queryParam", queryValue)
                .build()
                .toUri();

        return ResponseEntity.created(url).build();
    }

Spring 5.3以降はqueryParamIfPresent()というメソッドが新しくUriBuilderインターフェースに追加されているため、これを使うことで、クエリ文字列の値が空のときにクエリ全体を非表示にすることができます。

例えば、以下のコードを実行すると、http://localhost:8080?query=age&queryParamというURIが生成され、queryParamIfPresent()で設定したクエリ全体が非表示になっていることがわかります。

    @GetMapping
    public ResponseEntity<String> sample() {

        String value = null;

        URI url = UriComponentsBuilder.fromUriString("http://localhost:8080")
                .query("query=age")
                .queryParam("queryParam", value)
                .queryParamIfPresent("queryParamIfPresent", Optional.ofNullable(value))
                .build()
                .toUri();

        return ResponseEntity.created(url).build();
    }

参考

UriBuilder (Spring Framework 5.3.3 API)