Java'da URL sorgu parametrelerini kodlama


109

Java'da bir url'ye gitmek için sorgu parametreleri nasıl kodlanır? Biliyorum, bu çok açık ve önceden sorulmuş bir soru gibi görünüyor.

Emin olmadığım iki incelik var:

  1. URL'de boşluklar "+" veya "% 20" olarak mı kodlanmalı? Chrome'da "http://google.com/foo=?bar me" yazarsam chrome,% 20 ile kodlanacak şekilde değiştirir
  2. ":" İki nokta üst üste işaretlerini% 3B olarak kodlamak gerekli / doğru mu? Chrome yapmaz.

Notlar:

  • java.net.URLEncoder.encodeişe yaramıyor gibi görünüyor, kodlama verileri form gönderilecek gibi görünüyor. Örneğin, boşluğu +yerine olarak %20kodlar ve gerekli olmayan iki nokta üst üste kodlar.
  • java.net.URI sorgu parametrelerini kodlamaz

Bu soru faydalı görünüyor: stackoverflow.com/questions/444112/…
Alex Black

2
Sorgu kısmının yapısı sunucuya bağlıdır, ancak çoğu application/x-www-form-urlencodedanahtar / değer çifti bekler . Daha fazlası için buraya bakın: illegalargumentexception.blogspot.com/2009/12/…
McDowell

Yanıtlar:


128

java.net.URLEncoder.encode(String s, String encoding)çok yardımcı olabilir. HTML form kodlamasını izler application/x-www-form-urlencoded.

URLEncoder.encode(query, "UTF-8");

Öte yandan, Yüzde kodlaması ( URL kodlaması olarak da bilinir ) ile boşluğu kodlar %20. İki :nokta üst üste ayrılmış bir karakterdir, bu nedenle kodlamadan sonra da iki nokta üst üste olarak kalacaktır.


3
Bunun url kodlama yaptığını düşünmediğimi, bunun yerine bir form aracılığıyla gönderilecek verileri kodladığını belirttim. yorumlar?
Alex Black

Bunun nedeni URLEncoder, application/x-www-form-urlencodedMIME formatına (geçerli bir HTML form kodlaması olan) uygun olmasıdır. Sanırım aradığın bu değil.
Buhake Sindi

6
URLEncoder.encode'u kullandım ve "+" yerine "% 20" koydum
Alex Black

2
Eğik çizgileri "% 2F" olarak kodlar, URL eğik çizgilerini olduğu gibi bırakması gerekmez mi?
golimar

6
@golimar Hayır, olmamalı. URL'nin tamamını değil, yalnızca parametre değerini vermeniz gerekir. Örnek düşünün http://example.com/?url=http://example.com/?q=c&sort=name. Kodlamalı mı &sort=nameyoksa kodlamamalı mı? Değeri URL'den ayırt etmenin bir yolu yoktur. İlk etapta değer kodlamasına ihtiyaç duymanızın tam nedeni budur.
Pijusn

15

DÜZENLEME: URIUtilartık daha yeni sürümlerde mevcut değil, daha iyi yanıt Java'da - bu konu başlığında Bay Sindi tarafından URL'yi kodlayın .


URIUtil Apache httpclient gerçekten yararlıdır, ancak bazıları alternatifleri

URIUtil.encodeQuery(url);

Örneğin, boşluğu "% 20" yerine "+" olarak kodlar

Her ikisi de doğru bağlamda mükemmel bir şekilde geçerlidir . Yine de, gerçekten tercih etseniz de, bir dizeyi değiştirebilirdiniz.


Katılıyorum. HttpClient kullanın, çok daha mutlu olacaksınız.
DaShaun

Bu umut verici görünüm, şans eseri bir bağlantı mı aldı? Googling yapıyorum ama çok buluyorum.
Alex Black

1
Bu yöntem HttpClient 4.1'de görünmüyor mu? hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…
Alex Black

@Alex, hmm can sıkıcı, bu rutini her zaman iyi sonuçlarla kullandım. Bir fikir, kaynak kodunu 3 sürümünden almaktır çünkü artık açıkça onu korumak istemedikleri için.
Johan Sjöberg

1
URIUtil.encodeWithinQuerytek bir sorgu parametresini kodlamak için kullanacağınız şeydir, bu da orijinal sorunun sorduğu gibi görünüyordu.
Jesse Glick

13

Ne yazık ki, URLEncoder.encode () geçerli bir yüzde kodlaması üretmiyor ( RFC 3986'da belirtildiği gibi) ).

URLEncoder.encode (), boşluğun "+" olarak kodlanması dışında her şeyi gayet iyi kodlar . Bulabildiğim tüm Java URI kodlayıcıları, yalnızca sorguyu, parçayı, yol parçalarını vb. Kodlamak için genel yöntemleri açığa çıkarır - ancak "ham" kodlamayı göstermez. Bu talihsiz bir durumdur çünkü parça ve sorgu alanı + olarak kodlayabilir, bu yüzden onları kullanmak istemiyoruz. Yol doğru şekilde kodlanmıştır, ancak önce "normalize edilmiştir", bu nedenle onu "jenerik" kodlama için de kullanamayız.

Bulabildiğim en iyi çözüm:

return URLEncoder.encode(raw, "UTF-8").replaceAll("\\+", "%20");

Eğer replaceAll()sizin için çok yavaş, ben alternatif kendi kodlayıcı yuvarlanmaya sanırım ...

DÜZENLEME: İlk önce bu kodu burada aldım ve "?", "&", "=" Doğru şekilde kodlamayan:

//don't use - doesn't properly encode "?", "&", "="
new URI(null, null, null, raw, null).toString().substring(1);

+bir alanın mükemmel bir şekilde geçerli kodlamasıdır.
Lawrence Dol

@LawrenceDol doğru ancak bazen +yanlış yorumlanabilir - C # blogs.msdn.microsoft.com/yangxind/2006/11/08/…
Lu55

Bu. Çeşitli alternatifleri Javascript'in encodeURIComponentyöntem çıktısıyla karşılaştırdım ve denediklerim için tek tam eşleşme buydu (boşluklu sorgular, Türkçe ve Almanca özel karakterler).
Utku Özdemir

8

Yasadışı olmasa da, sorguda iki nokta üst üste işaretini% 3B olarak kodlamak gerekli değildir.

URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
query       = *( pchar / "/" / "?" )
pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
pct-encoded   = "%" HEXDIG HEXDIG
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="

Ayrıca uzayın bir ALFA veya DIGIT olduğundan şüphelendiğim için yalnızca yüzde olarak kodlanmış boşluklar geçerli görünüyor.

bakmak URI şartname fazla ayrıntı için.


Ancak, sorgu dizesinin yorumlanması sunucuya bağlı olduğundan, bunu yapmak URI'nin anlamını değiştirebilir. Bir application/x-www-form-urlencodedsorgu dizesi üretiyorsanız , her ikisi de iyidir. Kullanıcının yazdığı / yapıştırdığı bir URL'yi düzeltiyorsanız, :yalnız bırakılmalıdır.
tc.

@tc. Genel ayırıcı olarak iki nokta üst üste kullanılıyorsa haklısınız (RFC'nin 12. sayfası); ancak, genel sınırlayıcı olarak kullanılmıyorsa, her iki kodlama da aynı şekilde çözümlenmelidir.
Edwin Buck

Ayrıca, URL'ler gerçekten URI'nin bir alt kümesi olmadığından dikkatli olmalısınız: adamgent.com/post/25161273526/urls-are-not-a-subset-of-uris
Adam Gent

5

Yerleşik Java URLEncoder yapması gerekeni yapıyor ve onu kullanmalısınız.

A "+" veya "% 20" her ikisi de bir URL içinde bir boşluk karakteri için geçerli değiştirmeler. İkisi de çalışacak.

Bir ":" gerektiğini bunun bir ayırıcı karakter olarak kodlanmış olması. yani http: // foo veya ftp: // bar . Belirli bir tarayıcının kodlanmadığında onu işleyebilmesi gerçeği onu doğru yapmaz. Onları kodlamalısın.

İyi bir uygulama olarak, karakter kodlama parametresi alan yöntemi kullandığınızdan emin olun. UTF-8 genellikle orada kullanılır, ancak bunu açıkça sağlamalısınız.

URLEncoder.encode(yourUrl, "UTF-8");

5
+sadece içindeki uzayın temsilidir application/x-www-form-urlencoded; HTTP ile sınırlı olsa bile çalışması garanti edilmez. Benzer şekilde, :geçerli bir sorgu dizesinde ve olmamalıdır dönüştürülebilir %3B; bir sunucu bunları farklı şekilde yorumlamayı seçebilir.
tc.

1
Bu yöntem ayrıca parçası örneğin kepekli url eğik çizgi ve diğer karakterleri kodlamak http://için http%3A%2F%2Fhangi doğru değil
To Kra

2
@ToKra, http://parçayı kodlamamanız gerekiyor . Yöntem, sorgu parametreleri ve kodlanmış form verileri içindir. Bununla birlikte, başka bir web sitesinin URL'sini bir sorgu parametresi olarak iletmek istiyorsanız, BU DURUMDA URL ayrıştırıcısının kafasını karıştırmamak için onu kodlamak istersiniz.
beldaz

@tc w3.org/TR/html4/interact/forms.html#h-17.13.3.3 okumam , tüm GET form verilerinin application/x-www-form-urlencodediçerik türü olarak kodlandığı yönündedir . Bu, HTTP için çalışması gerektiği anlamına gelmez mi?
beldaz

0

url'de sadece boşluk probleminiz varsa. Aşağıdaki kodu kullandım ve iyi çalışıyor

String url;
URL myUrl = new URL(url.replace(" ","%20"));

örnek: url

www.xyz.com?para=hello efendim

muUrl'nin çıktısı

www.xyz.com?para=hello%20sir


0
String param="2019-07-18 19:29:37";
param="%27"+param.trim().replace(" ", "%20")+"%27";

Datetime (Timestamp) URLEncoder.encode(param,"UTF-8")çalışmazsa gözlemledim .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.