HttpServletRequest完成URL


Answers:


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(正确)。
Vinko Vrsalovic

21
您需要有条件地检查查询字符串是否为空。
亚当·根特2010年

8
您还将更改支持请求URL的StringBuffer。如果请求实现没有进行防御性复制,那么这是在原始形式中引入奇怪行为和错误的其他部分的好方法。
肯·布莱尔

5
使用StringBuilder代替StringBuffer
Gladwin Burboz 2013年

17
@KenBlair:故意返回StringBuffer,以便您可以轻松添加更多存储。由于这是在javadoc上指定的,因此,期望返回的StringBuffer不会被调用方修改的实现是非常荒谬的-因此,这很酷。
stolsvik

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
一个小的优化方法是使用StringBuilder代替StringBuffer,这只是一个提示
Chris

11
只是说明一下:在此特定示例中,线程安全性不是问题,因为url仅在方法内部声明,实例化并使用了线程安全性,因此只能从调用该方法的线程之外的线程访问它。
Diogo Kollross 2014年

1
如前所述,线程安全在这里不是问题,因为您正在StringBuffer为每个调用创建实例,并且不与任何其他线程共享该实例。应该将其更改为StringBuilder
2015年

1
有什么理由不使用getRequestURI吗?
Christophe Roussy 2015年

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
BalusC 2010年

是。我接受它,但是我猜它只有另外两个对象。
Teja Kantamneni

9
它是一个附加对象(一个StringBuilder),并且不会使返回的基础StringBuffer发生突变。我实际上更喜欢此方法,而不是“已接受”的答案,JVM会尽可能地优化差异,并且这不会带来引入错误的任何风险。
肯·布莱尔

(request.getRequestURL()。toString()+((request.getQueryString()!= null)?(“?” + request.getQueryString()):“”))
Alex


6

不推荐使用HttpUtil,这是正确的方法

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


1

您可以使用filter。

@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);





    }

不要忘记<dispatcher>FORWARD</dispatcher>在web.xml中放入 过滤器映射


记录... test1.getRequestURI()); 它给出了/applicationName/menu/index.action(即,它包含了斜杠)
Stevko 2015年


0

有点迟到了,但我在这包含MarkUtils的Web库WebUtils - Checkstyle的认可和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;
    }
}

到目前为止,这可能是Mat Banik的答案中最快,最可靠的答案-甚至他也没有考虑到HTTP / HTTPS潜在的非标准端口配置。

也可以看看:


0

您可以编写一个带有三元数的简单的线性函数,如果您使用StringBuffer的构建器模式,请使用.getRequestURL()

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

但这只是语法糖。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.