URL มีอยู่ทุกหนทุกแห่ง แต่ดูเหมือนว่านักพัฒนาไม่เข้าใจพวกเขาจริง ๆ เพราะฉันมักจะเห็นคนถามว่าจะสร้าง URL ได้อย่างถูกต้องบนสแต็กล้น หากคุณต้องการทราบว่า URL Syntax ทำงานอย่างไรคุณสามารถอ่านบทความนี้โดย Lunatech ซึ่งดีมาก
บทความนี้จะไม่แนะนำไวยากรณ์ทั้งหมดของ URL ในเชิงลึก (หากคุณต้องการเข้าใจ URL อย่างเต็มที่คุณสามารถอ่าน RFC 3986, RFC 1738 และบทความที่กล่าวถึงข้างต้นรวมถึงเอกสารข้างต้น W3) ที่นี่ฉันต้องการพูดคุยเกี่ยวกับห้องสมุดทั่วไปในการใช้งาน URL และวิธีการใช้งานอย่างถูกต้องผ่าน URL-builder นี่คือห้องสมุด Java ที่เราเผยแพร่เพื่อสร้าง URL อย่างถูกต้อง
คำถามที่ 1: urlencoder ของ Java
ไม่เพียง แต่คลาสนี้ชื่อไม่ดี แต่ประโยคแรกในเอกสารนั้นไม่ถูกต้องมาก
คลาสยูทิลิตี้สำหรับการเข้ารหัสแบบฟอร์ม HTML
คุณอาจสงสัยว่าทำไมมันจึงเรียกว่า urlencoder แต่คุณพูดไม่ออกอย่างสมบูรณ์เมื่อคุณเห็นบรรทัดนี้
หากคุณได้อ่านโพสต์บล็อก Lunatech ตอนนี้คุณควรเข้าใจว่าคุณไม่สามารถแปลงสตริง URL เป็นวัตถุ URL ที่ปลอดภัยและเข้ารหัสได้อย่างน่าอัศจรรย์ผ่านคลาสนี้ แน่นอนถ้าคุณยังไม่ได้ทำการบ้านมากพอนี่เป็นตัวอย่างเล็ก ๆ ที่ช่วยให้คุณเข้าใจ
สมมติว่าคุณมีจุดสิ้นสุดบริการ http http://foo.com/search ซึ่งยอมรับพารามิเตอร์แบบสอบถาม P และค่าของ P คือสตริงที่จะค้นหา หากคุณค้นหาสตริง "You & I" URL ของการค้นหาที่คุณสร้างขึ้นเป็นครั้งแรกอาจเป็นเช่นนี้: http://foo.com/search?q=you & I. แน่นอนว่าสิ่งนี้จะไม่ทำงานเพราะ & เป็นตัวคั่น หากคุณได้รับสตริง URL ที่ยุ่งเหยิงนี้คุณจะทำอะไรไม่ถูกเพราะก่อนอื่นคุณไม่สามารถแยกวิเคราะห์ได้อย่างถูกต้อง
โอเคใช้ urlencoder กันเถอะ urlencoder.encode ("You & I", "UTF-8") เป็นผลลัพธ์ที่คุณ+%26+i หลังจากถอดรหัส %26 นี้มันคือ & และเครื่องหมาย + แสดงถึงช่องว่างในสตริงการสืบค้นดังนั้น URL นี้สามารถทำงานได้ตามปกติ
ตอนนี้สมมติว่าคุณต้องการใช้สตริงแบบสอบถามของคุณเพื่อแยกเส้นทาง URL แทนการใส่ลงในพารามิเตอร์ URL เห็นได้ชัดว่า http://foo.com/search/you & ฉันผิด น่าเสียดายที่ผลลัพธ์ของ urlencoder.encode () ก็ผิดเช่นกัน http://foo.com/search/you+%26+i จะได้รับ/ค้นหา/คุณ+&+i เนื่องจากเครื่องหมาย+จะไม่สามารถแก้ไขช่องว่างในเส้นทาง URL ได้
urlencoder อาจตอบสนองสถานการณ์บางอย่างของคุณ น่าเสียดายที่ชื่อทั่วไปของมันทำให้นักพัฒนาสามารถใช้ในทางที่ผิดได้ง่าย ดังนั้นวิธีที่ดีที่สุดคือไม่ใช้มันเพื่อให้นักพัฒนารายอื่นทำผิดพลาดเมื่อใช้ฟังก์ชั่นอื่น ๆ บนพื้นฐานของคุณ (เว้นแต่คุณจะทำ "การเข้ารหัสแบบฟอร์ม HTML")
คำถามที่ 2: groovy httpbuilder และ uri ของ Java
HTTP Builder เป็นไลบรารีไคลเอนต์ HTTP ของ Groovy
การสร้างคำขอ GET ปกตินั้นง่ายมาก:
ใหม่ httpbuilder ("http: // localhost: 18080") .request (method.get) {uri.path = "/foo"}รหัสนี้จะส่ง /Foo HTTP /1.1 ไปยังเซิร์ฟเวอร์ (คุณสามารถเรียกใช้ NC -L -P 18080 จากนั้นเรียกใช้รหัสนี้เพื่อตรวจสอบ)
ลองใช้ URL ที่มีช่องว่าง
ใหม่ httpbuilder ("http: // localhost: 18080") .request (method.get) {uri.path = "/foo bar"}สิ่งนี้จะส่ง /foo%20bar http /1.1 ซึ่งดูค่อนข้างดี
ตอนนี้สมมติว่ามีส่วนหนึ่งในเส้นทางของเราที่เรียกว่า foo/bar สิ่งนี้ไม่สามารถทำได้ง่ายๆโดยการส่ง Foo/Bar เพราะสิ่งนี้จะถูกพิจารณาว่าเป็นสองส่วนในเส้นทาง Foo และ Bar ลอง Foo%2fbar (แทนที่ / ด้วยการเข้ารหัสที่สอดคล้องกัน)
ใหม่ httpbuilder ('http: // localhost: 18080') .request (method.get) {uri.path = '/foo%2fbar'}สิ่งนี้จะส่ง /foo%252fbar http /1.1 นี่ไม่ดีมาก %ใน %2F ถูกเข้ารหัสซ้ำ ๆ ดังนั้นเส้นทางที่ได้รับหลังจากการถอดรหัสคือ foo %2fbar แทน foo/bar ของจริงที่จะตำหนิที่นี่คือ java.net.uri เพราะคลาส Uribuilder ใน HttpBuilder ใช้มัน
ประเภทของคุณสมบัติ URI ที่เปิดเผยในการปิดการกำหนดค่าในรหัสด้านบนคือ uribuilder หากคุณอัปเดตคุณสมบัติเส้นทางของ URI ผ่าน Uri.Path = …ในที่สุดมันก็จะเรียกตัวสร้างของ URI วิธีนี้อธิบายคุณสมบัติเส้นทางที่เข้ามาดังนี้:
หากมีการจัดเตรียมพารามิเตอร์พา ธ มันจะถูกผนวกเข้ากับ URL อักขระในเส้นทางจะถูกเข้ารหัสตราบเท่าที่พวกเขาไม่ได้รับการสงวนไว้, คั่น, หลบหนี, หลบหนีและหมวดหมู่อื่น ๆ (หมายเหตุของนักแปล: หมวดหมู่เหล่านี้มีรายละเอียดใน RFC 2396) และไม่ใช่/หรือ @ หมายเลข
วิธีการนี้ไม่ได้มีความหมายมากนักเพราะหากข้อความก่อนการเข้ารหัสมีอักขระพิเศษมันไม่สามารถสร้างเซ็กเมนต์เส้นทางที่เข้ารหัสได้อย่างถูกต้อง กล่าวอีกนัยหนึ่ง "ฉันจะเข้ารหัสสตริงนี้และหลังจากการเข้ารหัสมันถูกต้อง" ซึ่งแน่นอนว่าการเข้าใจผิดและ URI ก็เป็นเหยื่อของการเข้าใจผิดนี้ หากสตริงถูกเข้ารหัสอย่างถูกต้องจะไม่มีปัญหา ถ้าไม่ทำเช่นนั้นจะทำเพราะสตริงไม่สามารถแยกวิเคราะห์ได้ ในความเป็นจริงสิ่งที่เอกสารบอกว่าไม่หลบหนี / หมายความว่ามันสันนิษฐานว่าสตริงเส้นทางได้รับการเข้ารหัสอย่างถูกต้อง (นั่นคือมันถูกใช้อย่างถูกต้องเพื่อแยกเส้นทาง) และมันไม่ได้เข้ารหัสอย่างถูกต้อง (ส่วนอื่น ๆ ยกเว้น / ยังต้องเข้ารหัส)
มันจะดีถ้า httpbuilder ไม่ได้ใช้ฟังก์ชั่นที่มีข้อบกพร่องของคลาส URI แน่นอนว่ามันจะดียิ่งขึ้นถ้า URI เองก็ใช้ได้
วิธีที่ถูกต้องในการทำ
เราเขียน URL-builder นี้ซึ่งสามารถช่วยให้นักพัฒนาแบ่ง URL ประเภทต่างๆได้อย่างง่ายดาย มันเป็นไปตามข้อกำหนดการเข้ารหัสในวัสดุอ้างอิงที่จุดเริ่มต้นของบทความและยังให้ API สตรีมมิ่ง ตัวอย่างการใช้งานต่อไปนี้สามารถครอบคลุมสถานการณ์การใช้งานเกือบทั้งหมด:
urlbuilder.forhost ("http", "foo.com") .pathsegment ("กับช่องว่าง") .pathsegments ("เส้นทาง", "ด้วย", "varargs") .pathsegment ("& =?/"). Queryparam ("แฟนซี + ชื่อ" .Fragment ("#? =") .TourlString ()ผลลัพธ์คือ: http://foo.com/with%20spaces/path/with/varargs/&=%3F%2F;
ตัวอย่างนี้แสดงให้เห็นถึงกฎการเข้ารหัสที่แตกต่างกันสำหรับแต่ละส่วนของ URL ตัวอย่างเช่นอนุญาตให้ไม่มีการเข้ารหัส & = ในเส้นทางในขณะที่?/ จำเป็นต้องเข้ารหัส แต่ต้องเข้ารหัส = ต้องเข้ารหัสในพารามิเตอร์การสืบค้น แต่? หมายเลขไม่ต้องการเพราะนี่เป็นส่วนหนึ่งของสตริงการสืบค้น (หมายเหตุของนักแปล: สตริงการสืบค้นเริ่มต้นด้วยหมายเลข? ดังนั้นจึงสามารถรวมหมายเลข? หลังจากนั้น)
ขอบคุณสำหรับการอ่านฉันหวังว่ามันจะช่วยคุณได้ ขอบคุณสำหรับการสนับสนุนเว็บไซต์นี้!