จะรับ URL โดเมนและชื่อแอปพลิเคชันได้อย่างไร


98

นี่คือสถานการณ์

เว็บแอปพลิเคชัน Java ของฉันมีเส้นทางต่อไปนี้

https://www.mywebsite.com:9443/MyWebApp

สมมติว่ามีไฟล์ JSP

https://www.mywebsite.com:9443/MyWebApp/protected/index.jsp

และฉันต้องดึงข้อมูล

https://www.mywebsite.com:9443/MyWebApp 

ภายในไฟล์ JSP นี้

แน่นอนว่ามีวิธีค่อนข้างขี้เกียจและไร้สาระในการรับ URL แล้วติดตามเส้นทางกลับอีกครั้ง

แต่มีวิธีแบบเป็นโปรแกรมในการทำเช่นนี้หรือไม่? โดยเฉพาะอย่างยิ่งฉันคิดว่าฉันจะได้รับพอร์ตโดเมน + แต่ฉันจะดึงชื่อแอปพลิเคชัน "MyWebApp" ได้อย่างไร

คำตอบ:


91

ชื่อเว็บแอปพลิเคชัน (ที่จริงคือพา ธ บริบท) สามารถใช้งานได้โดยการโทรHttpServletrequest#getContextPath()(และไม่ใช่getServletPath()ตามที่แนะนำก่อนหน้านี้) คุณสามารถดึงข้อมูลใน JSP ${pageContext.request.contextPath}โดย

<p>The context path is: ${pageContext.request.contextPath}.</p>

หากคุณตั้งใจจะใช้สิ่งนี้กับพา ธ สัมพัทธ์ทั้งหมดในหน้า JSP ของคุณ (ซึ่งจะทำให้คำถามนี้มีความหมายมากขึ้น) คุณสามารถใช้ประโยชน์จาก<base>แท็กHTML :

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<c:set var="req" value="${pageContext.request}" />
<c:set var="url">${req.requestURL}</c:set>
<c:set var="uri" value="${req.requestURI}" />

<!doctype html>
<html lang="en">
    <head>
        <title>SO question 2204870</title>
        <base href="${fn:substring(url, 0, fn:length(url) - fn:length(uri))}${req.contextPath}/">
        <script src="js/global.js"></script>
        <link rel="stylesheet" href="css/global.css">
    </head>
    <body>
        <ul>
            <li><a href="home.jsp">Home</a></li>
            <li><a href="faq.jsp">FAQ</a></li>
            <li><a href="contact.jsp">Contact</a></li>
        </ul>
    </body>
</html>

จากนั้นลิงก์ทั้งหมดในเพจจะสัมพันธ์กับลิงก์โดยอัตโนมัติ<base>เพื่อที่คุณจะได้ไม่ต้องคัดลอกพา ธ บริบทไปทุกที่ โปรดทราบว่าเมื่อลิงก์สัมพัทธ์เริ่มต้นด้วย a ลิงก์/เหล่านี้จะไม่สัมพันธ์กับ<base>อีกต่อไป แต่เป็นรูทโดเมนแทน


เอกสารระบุ "เส้นทางบริบทที่ส่งกลับมาServletContext.getContextPath() ควรถือเป็นพา ธ บริบทหลักหรือที่ต้องการของแอปพลิเคชัน" นั่นคือเหตุผลที่ฉันรวมคำตอบนี้ไว้ในคำตอบเดิมของฉันหลังจากที่ตระหนักถึงสิ่งนั้น ฉันไม่ได้ลบความพยายามครั้งแรกของฉันเนื่องจากฉันต้องการให้ OP พิจารณาอ่านเอกสารและเรียนรู้เพิ่มเติมเล็กน้อยเกี่ยวกับวิธีการที่เกี่ยวข้อง ฉันหวังว่าคุณจะเข้าใจประเด็นของฉัน
Adeel Ansari

@Vinegar: สำหรับไฟล์ JSP ที่ผลตอบแทนgetServletPath() /filename.jspOP ไม่ได้ถามเรื่องนี้เลยนี่ไม่ใช่วิธีที่จะไปอย่างแน่นอน
BalusC

แน่นอนฉันจะแก้ไขในโพสต์ของฉัน แต่คราวนี้ฉันคาดหวังว่าจะได้รับคำตอบจากความคิดเห็นของฉันซึ่งแตกต่างไปจากเดิมอย่างสิ้นเชิง :)
Adeel Ansari

2
ใน XHTML DOCTYPE คุณจะต้องต่อท้ายอักขระ '/' เข้ากับ contextPath <base href = "$ {pageContext.request.contextPath} /">
Basil Musa

ทำไมคุณไม่ปิด<base>แท็ก ไม่ควรปิดแท็กทั้งหมด?
Fabiano Francesconi

107

ดูเอกสารสำหรับHttpServletRequest.
ในการสร้าง URL ในตัวอย่างของคุณคุณจะต้องใช้:

  • getScheme()
  • getServerName()
  • getServerPort()
  • getContextPath()

นี่คือวิธีที่จะคืนค่าตัวอย่างของคุณ:

public static String getURLWithContextPath(HttpServletRequest request) {
   return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
}

1
วิธีรับ ip ในกรณีที่ servername เป็น localhost?
Mahmoud Saleh

เพียงแค่ทราบอย่างรวดเร็ว getScheme () ใช้ไม่ได้กับ https เสมอไปเซิร์ฟเวอร์บางตัวมีพฤติกรรมแปลก ๆ และอาจส่งคืน http แทน https เสมอ ฉันคิดว่าฉันควรแจ้งให้คุณทราบ ลอง request.getRequestURL () toString () และนวดถ้าคุณต้องการ
K ''

1
@MahmoudSalehrequest.getLocalAddr()
สีน้ำเงิน

จะเป็นการดีถ้าคุณแสดงผลลัพธ์ตัวอย่างสำหรับแต่ละวิธีด้วย มันเป็นความเจ็บปวดในการทำให้เว็บเซิร์ฟเวอร์ทำงานเพียงเพื่อตรวจสอบว่าผลลัพธ์ของแต่ละรายการอาจเป็นอย่างไร
Jus12

1
getContextPath()ในวิธีการไม่ส่งคืนอะไรเลย! และgetServerPort()ส่งกลับเพียงตัวเลข 2 หลักไม่ใช่ตัวเลข 4 หลัก! ฉันขอความช่วยเหลือได้ไหม
sam

26

ชื่อแอปพลิเคชันมาจาก getContextPathชื่อโปรแกรมประยุกต์มาจาก

ฉันพบกราฟิกนี้จากAgile Software Craftsmanship HttpServletRequest Path Decoding แยกวิธีการต่างๆทั้งหมดที่มีให้:

ป้อนคำอธิบายภาพที่นี่


1
ภาพนี้มีประโยชน์สำหรับการตอบคำถามมากมาย ฉันได้พยายามใช้คำตอบนี้ในคำตอบสำหรับคำถามหลายข้อ แต่ถูกลบทั้งหมด: มีกฎห้ามใช้คำตอบเดิมซ้ำ ซึ่งน่าเสียดาย. ทฤษฎีก็คือถ้าคุณใช้คำตอบเดียวกันคำถามก็ต้องเหมือนกันดังนั้นคุณควรทำเครื่องหมายคำถามว่าซ้ำกัน แต่นั่นไม่ใช่ความเป็นจริง มีคำถามมากมายที่สามารถตอบได้ด้วยกราฟิกเดียวกัน เป็นเรื่องเล็กน้อยที่จะใช้กฎตามอำเภอใจดังกล่าว หากคุณเห็นคำถามที่ตอบได้ดีที่สุดด้วยภาพกราฟิกนี้โปรดใช้คำถามนั้น
AgilePro


4

โค้ดต่อไปนี้อาจเป็นประโยชน์สำหรับเว็บแอปพลิเคชันที่ใช้ JavaScript

var newURL = window.location.protocol + "//"  + window.location.host + "" + window.location.pathname;

newURL = newURL.substring(0,newURL.indexOf(""));

0

หากคุณกำลังส่ง url เป็น String และต้องการแยกบริบทรูทของแอ็พพลิเคชันนั้นคุณสามารถใช้ regex นี้เพื่อแตกไฟล์ได้ จะใช้ได้กับ URL แบบเต็มหรือ URL สัมพัทธ์ที่ขึ้นต้นด้วยรูทบริบท

url.replaceAll("^(.*\\/\\/)?.*?\\/(.+?)\\/.*|\\/(.+)$", "$2$3")
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.