การเข้ารหัส URL ใน Android


336

คุณเข้ารหัสURLใน Android ได้อย่างไร

ฉันคิดว่ามันเป็นเช่นนี้:

final String encodedURL = URLEncoder.encode(urlAsString, "UTF-8");
URL url = new URL(encodedURL);

ถ้าฉันทำตามข้างต้นhttp://in urlAsStringจะถูกแทนที่ด้วยhttp%3A%2F%2FในencodedURLแล้วฉันจะได้รับ java.net.MalformedURLExceptionเมื่อฉันใช้ URL

คำตอบ:


630

คุณไม่ได้เข้ารหัส URL ทั้งหมดเพียงบางส่วนเท่านั้นที่มาจาก "แหล่งที่ไม่น่าเชื่อถือ"

String query = URLEncoder.encode("apples oranges", "utf-8");
String url = "http://stackoverflow.com/search?q=" + query;

หรือคุณสามารถใช้Strings.urlEncode (String str)ของDroidPartsที่ไม่ส่งข้อยกเว้นที่เลือก

หรือใช้สิ่งที่ชอบ

String uri = Uri.parse("http://...")
                .buildUpon()
                .appendQueryParameter("key", "val")
                .build().toString();

1
เกิดอะไรขึ้นถ้า URL ทั้งหมดไม่น่าเชื่อถือ? ฉันควรเข้ารหัสทุกอย่างยกเว้นโปรโตคอลหรือไม่ ฉันคาดหวังว่าจะมีวิธีอำนวยความสะดวกในการทำเช่นนี้
hpique

5
ถ้างั้นมันก็แค่ URL ที่หัก แนวคิดคือการป้องกันไม่ให้ส่วนแบบสอบถามทำลาย URL
yanchenko

5
@hgpc - ดูหัวข้อ 3 ของ RFC3986 ( tools.ietf.org/html/rfc3986#section-3 ) มันบอกวิธีเข้ารหัสส่วนต่าง ๆ ของ URI น่าเสียดายที่แต่ละส่วนของ URI (โฮสต์เส้นทางแบบสอบถาม ฯลฯ ) มีกฎการเข้ารหัสที่แตกต่างกันเล็กน้อย
D.Shawley

2
นี่เป็นเรื่องปกติที่คุณจะจัดการกับส่วนเฉพาะของ URL และคุณรู้วิธีสร้างหรือสร้าง URL ขึ้นใหม่ สำหรับแนวทางทั่วไปที่สามารถจัดการกับสตริง url ได้โปรดดูคำตอบของฉันด้านล่าง
Craig B

8
ทำไมฉันถึงได้รับคำเตือนเรื่องเลิกใช้งานสิ่งนี้? ใช้Uri.encode(query);แทน
prasanthv

166

ฉันจะเพิ่มข้อเสนอแนะหนึ่งข้อที่นี่ คุณสามารถทำสิ่งนี้เพื่อหลีกเลี่ยงการได้รับห้องสมุดภายนอกใด ๆ

ลองดูสิ:

String urlStr = "http://abc.dev.domain.com/0007AC/ads/800x480 15sec h.264.mp4";
URL url = new URL(urlStr);
URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();

คุณจะเห็นว่าใน URL นี้ฉันต้องมีการเว้นวรรคเหล่านั้นเพื่อให้ฉันสามารถใช้มันสำหรับการร้องขอ

นี่เป็นการใช้ประโยชน์จากคุณสมบัติสองสามอย่างที่มีให้คุณในคลาส Android ก่อนอื่นคลาส URL สามารถแบ่ง URL เป็นส่วนประกอบที่เหมาะสมดังนั้นคุณไม่จำเป็นต้องทำการค้นหา / แทนที่สตริงใด ๆ ประการที่สองวิธีนี้ใช้ประโยชน์จากคุณลักษณะคลาส URI ในการหลีกเลี่ยงส่วนประกอบได้อย่างถูกต้องเมื่อคุณสร้าง URI ผ่านส่วนประกอบแทนที่จะเป็นจากสตริงเดียว

ความสวยงามของวิธีการนี้คือคุณสามารถใช้สตริง URL ที่ถูกต้องและใช้งานได้โดยไม่จำเป็นต้องมีความรู้พิเศษใด ๆ ด้วยตนเอง


19
นี่ควรเป็นคำตอบที่ถูกต้อง นี่เป็นวิธีที่เป็นทางการและชัดเจนในการทำเช่นนี้
Asanka Senavirathna

3
มันอาจเป็นความคิดที่ดีที่จะ urldecode urlStr ก่อนที่จะส่งไปยังตัวสร้าง URL URLDecoder.decode (urlStr)
Jakob Eriksson

1
ขอบคุณสำหรับการโพสต์ :) แต่ฉันกำลังประสบปัญหา หาก url มีการเข้ารหัสบางส่วนอยู่แล้วมันจะเข้ารหัสส่วนที่เข้ารหัสไว้แล้ว ฉันควรทำอย่างไรดี? ตัวอย่างเช่น: dj-videos.us/Music/XclusiveSinGleTrack/320%20Kbps/…% 20 จะได้รับรหัสถึง% 2520
บ้าดีเดือด

2
@berserk หากมีการเข้ารหัสแล้วอย่าเข้ารหัส คุณไม่ควรเข้าสู่สถานะที่มันถูกเข้ารหัสบางส่วนหรือคุณไม่แน่ใจว่ามันเป็นหรือไม่ได้ถูกเข้ารหัส
มาร์ควิสแห่ง Lorne

3
วิธีนี้ไม่ได้เข้ารหัสอักขระเช่นğถึง% C4% 9F ยอมรับหนึ่งการเข้ารหัส!
Alexander Prokofyev

74

สำหรับ Android ฉันจะใช้ String android.net.Uri.encode (String s)

เข้ารหัสอักขระในสตริงที่กำหนดเป็น '%' - อ็อกเท็ตที่ใช้ Escape โดยใช้รูปแบบ UTF-8 ออกจากตัวอักษร ("AZ", "az"), ตัวเลข ("0-9") และอักขระที่ไม่ถูกสงวน ("_- !. ~ '() *") เหมือนเดิม เข้ารหัสอักขระอื่น ๆ ทั้งหมด

Ex /

String urlEncoded = "http://stackoverflow.com/search?q=" + Uri.encode(query);

2
แต่น่าเสียดายที่Uri.encode("a=1&b=1")ผลิตa%3D1%26b%3D1แต่คาดว่าa=1&b=1
loentar

14
@loentar นั่นเป็นผลลัพธ์ที่คาดหวัง หากผู้ใช้ป้อนa=1&b=1เป็นแบบสอบถามคุณต้องการสอบถามอย่างแน่นอน
Anubian Noob

ความแตกต่างนี้กับ URLEncoder.encode (StringHere, "UTF-8")
ติดขัดไหลเวียน

@ stuckedoverflow สำหรับสิ่งหนึ่ง Uri.encode (str) ไม่ได้ยกเว้นการตรวจสอบยกเว้น URLEncoder.encode (str, "UTF-8")
deekshith

50

นอกจากนี้คุณสามารถใช้สิ่งนี้

private static final String ALLOWED_URI_CHARS = "@#&=*+-_.,:!?()/~'%";
String urlEncoded = Uri.encode(path, ALLOWED_URI_CHARS);

มันเป็นวิธีที่ง่ายที่สุด


1
นี่ไม่ใช่ทางออกที่ดีที่สุด แต่แน่นอนว่าเป็นการแก้ไขด่วนที่ดี ... thanx
Sebastian Breit

4
นี่คือการแก้ไขที่รวดเร็วที่สุดเมื่อ URL ทั้งหมดไม่น่าเชื่อถือ ขอบคุณ!
user1032613

คุณแน่ใจว่า% ควรได้รับอนุญาตหรือไม่ ไม่ควรเข้ารหัส?
MediumOne

1
วิธีเข้ารหัส URL นี้เพื่อให้สามารถแบ่งปันได้จากนั้นผู้ใช้จะสามารถเปิดลิงก์และดูหน้า: yazd20.com
Ahmad Ebrahimi

3
try {
                    query = URLEncoder.encode(query, "utf-8");
                } catch (UnsupportedEncodingException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

1

คุณสามารถใช้วิธีการด้านล่าง

public static String parseUrl(String surl) throws Exception
{
    URL u = new URL(surl);
    return new URI(u.getProtocol(), u.getAuthority(), u.getPath(), u.getQuery(), u.getRef()).toString();
}

หรือ

public String parseURL(String url, Map<String, String> params)
{
    Builder builder = Uri.parse(url).buildUpon();
    for (String key : params.keySet())
    {
        builder.appendQueryParameter(key, params.get(key));
    }
    return builder.build().toString();
}

อันที่สองดีกว่าครั้งแรก


0

ค้นหาตัวอักษรภาษาอาหรับและแทนที่ด้วยการเข้ารหัส UTF-8 บางสิ่งเช่นนี้

for (int i = 0; i < urlAsString.length(); i++) {
    if (urlAsString.charAt(i) > 255) {
        urlAsString = urlAsString.substring(0, i) + URLEncoder.encode(urlAsString.charAt(i)+"", "UTF-8") + urlAsString.substring(i+1);
    }
}
encodedURL = urlAsString;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.