URL पूरा करने के लिए HttpServletRequest


247

मेरे पास एक HttpServletRequestवस्तु है।

मुझे पूर्ण और सटीक URL कैसे प्राप्त होते हैं जिसके कारण यह कॉल मेरे सर्वलेट पर आई है?

या कम से कम सही रूप में संभव के रूप में, शायद ऐसी चीजें हैं जो पुनर्जीवित हो सकती हैं (मापदंडों का क्रम, शायद)।



हमने इसके लिए कोई उपयोग कार्य क्यों नहीं किया
vanduc1102

जवाबों:


392

HttpServletRequestनिम्न विधियों है:

  • getRequestURL() - क्वेरी स्ट्रिंग सेपरेटर कैरेक्टर से पहले पूर्ण URL का हिस्सा लौटाता है ?
  • getQueryString() - क्वेरी स्ट्रिंग सेपरेटर कैरेक्टर के बाद पूर्ण URL का हिस्सा लौटाता है ?

तो, पूर्ण URL प्राप्त करने के लिए, बस करें:

public static String getFullURL(HttpServletRequest request) {
    StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString());
    String queryString = request.getQueryString();

    if (queryString == null) {
        return requestURL.toString();
    } else {
        return requestURL.append('?').append(queryString).toString();
    }
}

3
आपने getRequestURI (गलत) से विवरण की प्रतिलिपि बनाई लेकिन कोड (दाएं) में getRequestURL का उपयोग करें।
विंको वर्सालोविच 14

21
यदि स्ट्रिंग स्ट्रिंग खाली है, तो आपको सशर्त रूप से जांचने की आवश्यकता है।
एडम गेंट

8
आप अनुरोध URL का समर्थन करते हुए StringBuffer को भी बदल रहे हैं। यदि अनुरोध कार्यान्वयन एक रक्षात्मक प्रतिलिपि नहीं बना रहा है, तो कोड के अन्य भागों में अजीब व्यवहार और बग को पेश करने का एक बहुत अच्छा तरीका है जो इसे मूल रूप में उम्मीद करता है।
केन ब्लेयर

5
StringBuffer के बजाय StringBuilder का उपयोग करें
Gladwin Burboz

17
@KenBlair: एक स्ट्रिंगरफ़र को उद्देश्य पर लौटाया जाता है, ताकि आप आसानी से अधिक स्टैश पर जोड़ सकें। चूंकि यह javadoc पर निर्दिष्ट किया गया है, इसलिए यह अपेक्षा के लिए बहुत ही बेतुका होगा कि लौटे StringBuffer को कॉलर द्वारा संशोधित नहीं किया जाएगा - इसलिए, यह अच्छा है।
12-13 को स्टॉल्सविक जू

145

मैं इस विधि का उपयोग करता हूं:

public static String getURL(HttpServletRequest req) {

    String scheme = req.getScheme();             // http
    String serverName = req.getServerName();     // hostname.com
    int serverPort = req.getServerPort();        // 80
    String contextPath = req.getContextPath();   // /mywebapp
    String servletPath = req.getServletPath();   // /servlet/MyServlet
    String pathInfo = req.getPathInfo();         // /a/b;c=123
    String queryString = req.getQueryString();          // d=789

    // Reconstruct original requesting URL
    StringBuilder url = new StringBuilder();
    url.append(scheme).append("://").append(serverName);

    if (serverPort != 80 && serverPort != 443) {
        url.append(":").append(serverPort);
    }

    url.append(contextPath).append(servletPath);

    if (pathInfo != null) {
        url.append(pathInfo);
    }
    if (queryString != null) {
        url.append("?").append(queryString);
    }
    return url.toString();
}

8
यह HttpServletRequest पर उपलब्ध जानकारी के सभी बिट्स के त्वरित संदर्भ के लिए एक उपयोगी उत्तर है। हालाँकि, मुझे लगता है कि आप यह तय करना चाहते हैं कि परिणाम में पोर्ट का टुकड़ा जोड़ा जाए या नहीं। उदाहरण के लिए "https" 443 होगा।
पीटर कार्डोना

2
एक छोटा सा अनुकूलन StringBuffer के बजाय एक StringBuilder का उपयोग करना होगा, बस एक संकेत
क्रिस

11
बस एक टिप्पणी: थ्रेड सुरक्षा इस विशिष्ट उदाहरण में कोई समस्या नहीं है क्योंकि urlकेवल विधि के अंदर घोषित, त्वरित और उपयोग किया जाता है, इसलिए इसे उस विधि के अलावा अन्य थ्रेड से एक्सेस नहीं किया जा सकता है।
दिओगो कोल्लॉस

1
जैसा कि उल्लेख किया गया है, थ्रेड सुरक्षा यहां कोई समस्या नहीं है क्योंकि आप StringBufferप्रत्येक कॉल के लिए अपना इंस्टेंस बना रहे हैं और इसे किसी अन्य थ्रेड के साथ साझा नहीं कर रहे हैं । इसे बदलकर ए होना चाहिए StringBuilder
ग्रे

1
उपयोग करने का कोई कारण नहीं getRequestURI?
क्रिस्टोफ रूसो

27
// http://hostname.com/mywebapp/servlet/MyServlet/a/b;c=123?d=789

public static String getUrl(HttpServletRequest req) {
    String reqUrl = req.getRequestURL().toString();
    String queryString = req.getQueryString();   // d=789
    if (queryString != null) {
        reqUrl += "?"+queryString;
    }
    return reqUrl;
}

5
आप के लाभ की अनदेखी कर रहे हैं StringBuffer
बालूसी

हाँ। मैं इसे स्वीकार करता हूं, लेकिन इसकी केवल दो अतिरिक्त वस्तुओं का मुझे अनुमान है।
तेजा कंतमनेनी

9
यह एक अतिरिक्त वस्तु है (एक स्ट्रिंगबर्ल) और जो वापस आ गया है उस अंतर्निहित स्ट्रिंगबर्गर को म्यूट नहीं करता है। मैं वास्तव में "स्वीकार किए जाते हैं" जवाब पर यह पसंद करूंगा, जेवीएम अंतर को ध्यान से दूर करेगा और इससे बग को शुरू करने का कोई जोखिम नहीं है।
केन ब्लेयर

(request.getRequestURL ()। toString () + ((request.getQueryString () = null)? ("?" + request.getQueryString ()): "")
एलेक्स


6

HttpUtil को अपदस्थ किया जा रहा है, यह सही तरीका है

StringBuffer url = req.getRequestURL();
String queryString = req.getQueryString();
if (queryString != null) {
    url.append('?');
    url.append(queryString);
}
String requestURL = url.toString();

5

के परिणामों के संयोजन getRequestURL()और getQueryString()आप वांछित परिणाम प्राप्त करना चाहिए।


पोस्ट से संबंधित Params को कैसे संभालें?
फ्लैश

2
@flash कडाई के बाद पैरामीटर URL का हिस्सा नहीं हैं, वे कर रहे हैं शरीर अनुरोध की।
गीर्ट

1

आप फ़िल्टर का उपयोग कर सकते हैं।

@Override
    public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException {
            HttpServletRequest test1=    (HttpServletRequest) arg0;

         test1.getRequestURL()); it gives  http://localhost:8081/applicationName/menu/index.action
         test1.getRequestURI()); it gives applicationName/menu/index.action
         String pathname = test1.getServletPath()); it gives //menu/index.action


        if(pathname.equals("//menu/index.action")){ 
            arg2.doFilter(arg0, arg1); // call to urs servlet or frameowrk managed controller method


            // in resposne 
           HttpServletResponse httpResp = (HttpServletResponse) arg1;
           RequestDispatcher rd = arg0.getRequestDispatcher("another.jsp");     
           rd.forward(arg0, arg1);





    }

donot <dispatcher>FORWARD</dispatcher>web.xml में फ़िल्टर मैपिंग में डालना भूल जाते हैं


रिकॉर्ड के लिए ... test1.getRequestURI ()); यह /applicationName/menu/index.action देता है (यानी इसमें प्रमुख स्लैश शामिल है)
Stevko

1

HttpServletRequest ऑब्जेक्ट पर निम्न विधियों का उपयोग करें

java.lang.String getRequestURI () -Returns इस अनुरोध के URL का हिस्सा प्रोटोकॉल नाम से HTTP स्ट्रिंग अनुरोध की पहली पंक्ति में स्ट्रिंग स्ट्रिंग तक देता है।

java.lang.StringBuffer getRequestURL () -Reconstructs URL जो अनुरोध करने के लिए उपयोग किया जाता है।

java.lang.String getQueryString () पथ के बाद अनुरोध URL में निहित क्वेरी स्ट्रिंग को पुन: प्रदर्शित करता है।


0

पार्टी के लिए थोड़ा देर हो गई, लेकिन मैंने इसे WebUtils में अपने MarkUtils-Web लाइब्रेरी में शामिल कर लिया - चेकस्टाइल -स्वीकृत और JUnit- परीक्षण:

import javax.servlet.http.HttpServletRequest;

public class GetRequestUrl{
    /**
     * <p>A faster replacement for {@link HttpServletRequest#getRequestURL()}
     *  (returns a {@link String} instead of a {@link StringBuffer} - and internally uses a {@link StringBuilder})
     *  that also includes the {@linkplain HttpServletRequest#getQueryString() query string}.</p>
     * <p><a href="https://gist.github.com/ziesemer/700376d8da8c60585438"
     *  >https://gist.github.com/ziesemer/700376d8da8c60585438</a></p>
     * @author Mark A. Ziesemer
     *  <a href="http://www.ziesemer.com.">&lt;www.ziesemer.com&gt;</a>
     */
    public String getRequestUrl(final HttpServletRequest req){
        final String scheme = req.getScheme();
        final int port = req.getServerPort();
        final StringBuilder url = new StringBuilder(256);
        url.append(scheme);
        url.append("://");
        url.append(req.getServerName());
        if(!(("http".equals(scheme) && (port == 0 || port == 80))
                || ("https".equals(scheme) && port == 443))){
            url.append(':');
            url.append(port);
        }
        url.append(req.getRequestURI());
        final String qs = req.getQueryString();
        if(qs != null){
            url.append('?');
            url.append(qs);
        }
        final String result = url.toString();
        return result;
    }
}

संभवत: मैट बानिक के पीछे अब तक का सबसे तेज और सबसे मजबूत जवाब है, लेकिन यहां तक ​​कि वह HTTP / HTTPS के साथ संभावित गैर-मानक पोर्ट कॉन्फ़िगरेशन के लिए खाता नहीं है।

यह सभी देखें:


0

आप एक साधारण एक लाइनर को टर्नरी के साथ लिख सकते हैं और यदि आप स्ट्रिंगरबफ़र के बिल्डर पैटर्न का उपयोग करते हैं .getRequestURL():

private String getUrlWithQueryParms(final HttpServletRequest request) { 
    return request.getQueryString() == null ? request.getRequestURL().toString() :
        request.getRequestURL().append("?").append(request.getQueryString()).toString();
}

लेकिन वह सिर्फ चीनी है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.