1. ホーム

[解決済み】Androidでのクエリ文字列のパースについて

2022-04-03 09:36:17

質問

Java EEは ServletRequest.getParameterValues() .

非EEプラットフォームでは URL.getQuery() は単に文字列を返します。

の場合、URLのクエリー文字列を適切にパースする通常の方法は何でしょうか? ではなく をJava EEで使用することはできますか?


回答では、パーサーを自作してみるのが流行っているようです。 これは非常に面白く、エキサイティングなマイクロコーディングのプロジェクトですが とは言い切れませんが .

以下のコード・スニペットは、一般的に欠陥があったり、壊れていたりします。それらを壊すことは、読者にとって面白い練習になります。 そして、それらを使用しているウェブサイトを攻撃しているハッカーに .

クエリ文字列の解析はよく定義された問題ですが、仕様を読み、ニュアンスを理解することは容易ではありません。プラットフォームライブラリのコーダーに難しい作業や修正を任せる方がはるかに良いですよ。

解決方法は?

Android M以降、事態はより複雑になっています。の答えは android.net.URI.getQueryParameter() には、JellyBeanの前にあるスペースが壊れるというバグがあります。 アパッチ URLEncodedUtils.parse() は動作しましたが Lで非推奨 であり、また Mで削除 .

ということで、今のベストアンサーは UrlQuerySanitizer . これはAPIレベル1から存在し、今もなお存在する。また、特殊文字や繰り返し値をどう扱うかなど、厄介な問題についても考えさせられます。

最もシンプルなコードは

UrlQuerySanitizer.ValueSanitizer sanitizer = UrlQuerySanitizer.getAllButNullLegal();
// remember to decide if you want the first or last parameter with the same name
// If you want the first call setPreferFirstRepeatedParameter(true);
sanitizer.parseUrl(url);
String value = sanitizer.getValue("paramName");

もし、デフォルトのパース動作に満足しているのであれば、こうすることができます。

new UrlQuerySanitizer(url).getValue("paramName")

しかし、デフォルトのパース動作がどのようなものかを理解しておく必要があります。