מדריך לקידוד / פענוח URL של Java

1. הקדמה

במילים פשוטות, קידוד כתובות אתרים מתרגם תווים מיוחדים מכתובת האתר לייצוג העומד במפרט וניתן להבין ולפרש בצורה נכונה.

במאמר זה נתמקד כיצד לקודד / לפענח את כתובת האתר או נתוני הטופס כך שהוא עומד במפרט ומשדר ברשת בצורה נכונה.

2. לנתח את כתובת האתר

ניתן להכליל תחביר בסיסי של URI כ:

סכמה: [// [משתמש: [מוגן באמצעות הדוא"ל]] מארח [: פורט]] [/] נתיב [? שאילתה] [שבר #]

הצעד הראשון לקידוד URI הוא בחינת חלקיו ואז קידוד החלקים הרלוונטיים בלבד.

הבה נבחן דוגמה ל- URI:

מחרוזת testUrl = "//www.baeldung.com?key1=value+1&key2=value%40%21%242&key3=value%253";

אחת הדרכים לניתוח ה- URI היא טעינת ייצוג המחרוזת ל- a java.net.URI מעמד:

@ מבט פומבי בטל שניתןURL_whenAnalyze_thenCorrect () זורק חריג {URI uri = URI חדש (testUrl); assertThat (uri.getScheme (), הוא ("http")); assertThat (uri.getHost (), הוא ("www.baeldung.com")); assertThat (uri.getRawQuery (), .is ("key1 = value + 1 & key2 = value% 40% 21% 242 & key3 = value% 253")); }

ה URI class מנתח את כתובת ה- URL של ייצוג המחרוזות וחושף את חלקיה באמצעות ממשק API פשוט - למשל, getXXX.

3. קידד את כתובת האתר

בעת קידוד URI, אחת המלכודות הנפוצות היא קידוד ה- URI השלם. בדרך כלל עלינו לקודד רק את חלק השאילתה של ה- URI.

בואו נקודד את הנתונים באמצעות ה- קידוד (נתונים, קידוד סכימה) שיטת ה- מקודד URLEncoder מעמד:

פרטי מחרוזת encodeValue (ערך מחרוזת) {return URLEncoder.encode (value, StandardCharsets.UTF_8.toString ()); } @Test הציבור בטל givenRequestParam_whenUTF8Scheme_thenEncode () זורק חריג {Map requestParams = חדש HashMap (); requestParams.put ("key1", "value 1"); requestParams.put ("key2", "[email protected]! $ 2"); requestParams.put ("key3", "value% 3"); מחרוזת encodedURL = requestParams.keySet (). Stream () .map (key -> key + "=" + encodeValue (requestParams.get (key))) .collect (joining ("&", "//www.baeldung. com? "," ")); assertThat (testUrl, is (encodedURL)); 

ה לְהַצְפִּין השיטה מקבלת שני פרמטרים:

  1. נתונים - מחרוזת לתרגום
  2. קידוד Scheme - שם קידוד התווים

זֶה לְהַצְפִּין שיטה ממירה את המחרוזת ל- יישום / x-www-form-urlencoded פוּרמָט.

ערכת הקידוד תמיר תווים מיוחדים לשתי ספרות ייצוג הקסדצימלי של 8 סיביות שיוצגו בצורה של "% xy". כאשר עסקינן בפרמטרים של נתיב או הוספת פרמטרים שהם דינמיים, נקודד את הנתונים ואז נשלח לשרת.

הערה: ה קונסורציום הרשת העולמית ההמלצה קובעת כי UTF-8 צריך להשתמש. אי-עשייה לכך עשויה להכניס אי-התאמה. (התייחסות: //docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html)

4. פענח את כתובת האתר

בואו כעת נפענח את כתובת האתר הקודמת בשיטת הפענוח של ה- URLDecoder:

פענוח מחרוזת פרטי (ערך מחרוזת) {return URLDecoder.decode (value, StandardCharsets.UTF_8.toString ()); } @Test הציבור בטל givenRequestParam_whenUTF8Scheme_thenDecodeRequestParams () {URI uri = URI חדש (testUrl); ערכת מיתרים = uri.getScheme (); מארח מחרוזת = uri.getHost (); שאילתת מחרוזת = uri.getRawQuery (); מחרוזת decodedQuery = Arrays.stream (query.split ("&")) .map (param -> param.split ("=") [0] + "=" + פענוח (param.split ("=") [1 ])) .collect (Collectors.joining ("&")); assertEquals ("//www.baeldung.com?key1=value 1 & [email protected]! $ 2 & key3 = value% 3", scheme + ": //" + host + "?" + decodedQuery); }

שני החלקים החשובים כאן הם:

  • לנתח URL לפני פענוח
  • השתמש באותה ערכת קידוד לקידוד ופענוח

אם היינו מפענחים מאשר מנתחים, ייתכן שחלקים של כתובות אתרים לא ינותחו כהלכה. אם השתמשנו בתכנית קידוד אחרת לפענוח הנתונים, זה יביא לנתוני אשפה.

5. קידוד פלח נתיב

URLEncoder לא ניתן להשתמש בקידוד קטע נתיב של כתובת אתר. רכיב נתיב מתייחס למבנה ההיררכי המייצג נתיב ספריה, או שהוא משמש לאיתור משאבים המופרדים על ידי “/”.

תווים שמורים בפלח הנתיב שונים מאשר בערכי פרמטר השאילתה. לדוגמא, סימן "+" הוא תו תקף בקטע הנתיב ולכן אין לקודדו.

כדי לקודד את קטע הנתיב, אנו משתמשים ב- UriUtils בכיתה לפי מסגרת האביב במקום. UriUtils הכיתה מספקת encodePath ו encodePathSegment שיטות לקידוד נתיב וקטע נתיב בהתאמה.

בואו נסתכל על דוגמה:

פרטי מחרוזת encodePath (נתיב מחרוזת) {נסה {path = UriUtils.encodePath (נתיב, "UTF-8"); } לתפוס (UnsupportedEncodingException e) {LOGGER.error ("פרמטר קידוד שגיאה {}", e.getMessage (), e); } דרך חזרה; }
@Test ציבורי בטל givenPathSegment_thenEncodeDecode () זורק UnsupportedEncodingException {String pathSegment = "/ Path 1 / Path + 2"; מחרוזת encodedPathSegment = encodePath (pathSegment); מחרוזת decodedPathSegment = UriUtils.decode (encodedPathSegment, "UTF-8"); assertEquals ("/ נתיב% 201 / נתיב + 2", encodedPathSegment); assertEquals ("/ Path 1 / Path + 2", decodedPathSegment); }

בקטע הקוד שלעיל אנו יכולים לראות כי כאשר השתמשנו ב- encodePathSegment שיטה, הוא החזיר את הערך המקודד ו- + אינו מקודד מכיוון שהוא תו ערך ברכיב הנתיב.

בואו נוסיף משתנה נתיב לכתובת אתר הבדיקה שלנו:

מחרוזת testUrl = "/ path + 1? Key1 = value + 1 & key2 = value% 40% 21% 242 & key3 = value% 253";

וכדי להרכיב ולקבוע כתובת URL מקודדת כראוי הבה נשנה את הבדיקה מסעיף 2:

נתיב מחרוזת = "נתיב + 1"; מחרוזת encodedURL = requestParams.keySet (). Stream () .map (k -> k + "=" + encodeValue (requestParams.get (k))) .collect (joining ("&", "/" + encodePath (path) ) + "?", "")); assertThat (testUrl, CoreMatchers.is (encodedURL)); 

6. מסקנה

במדריך זה ראינו כיצד לקודד ולפענח את הנתונים כך שניתן יהיה להעביר ולפרש אותם נכון. בעוד המאמר התמקד בקידוד / פענוח של ערכי פרמטרים של שאילתת URI, הגישה חלה גם על פרמטרים של טופס HTML.

אתה יכול למצוא את קוד המקור ב- GitHub.