我有一个HttpServletRequest对象。

我如何获得导致这个调用到达我的servlet的完整而准确的URL ?

或者至少尽可能准确,因为有些东西是可以重新生成的(也许是参数的顺序)。


当前回答

你可以使用滤镜。

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

不要忘记在web.xml的filter mapping中放入<dispatcher>FORWARD</dispatcher>

其他回答

在HttpServletRequest对象上使用以下方法

以getRequestURI () 返回该请求的URL部分,从协议名到HTTP请求第一行的查询字符串。

java.lang.StringBuffer getRequestURL () -重建客户端用来发出请求的URL。

以getQueryString () -返回包含在请求URL中路径后面的查询字符串。

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();
    }
}

如果你使用了.getRequestURL()中的StringBuffer的构建器模式,你可以用三元写一个简单的一行代码:

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

但这只是语法糖。

有点晚了,但我把它包括在我的MarkUtils-Web库中的WebUtils - Checkstyle-approved和junit - tests:

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的潜在非标准端口配置。

参见:

http://blogger.ziesemer.com/2017/08/httpservletrequestgetrequesturl.html https://gist.github.com/ziesemer/700376d8da8c60585438

我有一个用例来生成cURL命令(我可以在终端使用)从httpServletRequest实例。我创建了一个这样的方法。您可以直接在终端中复制粘贴此方法的输出

private StringBuilder generateCURL(final HttpServletRequest httpServletRequest) {
    final StringBuilder curlCommand = new StringBuilder();
    curlCommand.append("curl ");

    // iterating over headers.
    for (Enumeration<?> e = httpServletRequest.getHeaderNames(); e.hasMoreElements();) {
        String headerName = (String) e.nextElement();
        String headerValue = httpServletRequest.getHeader(headerName);
        // skipping cookies, as we're appending cookies separately.
        if (Objects.equals(headerName, "cookie")) {
            continue;
        }
        if (headerName != null && headerValue != null) {
            curlCommand.append(String.format(" -H \"%s:%s\" ", headerName, headerValue));
        }
    }

    // iterating over cookies.
    final Cookie[] cookieArray = httpServletRequest.getCookies();
    final StringBuilder cookies = new StringBuilder();
    for (Cookie cookie : cookieArray) {
        if (cookie.getName() != null && cookie.getValue() != null) {
            cookies.append(cookie.getName());
            cookies.append('=');
            cookies.append(cookie.getValue());
            cookies.append("; ");
        }
    }
    curlCommand.append(" --cookie \"" + cookies.toString() + "\"");

    // appending request url.
    curlCommand.append(" \"" + httpServletRequest.getRequestURL().toString() + "\"");
    return curlCommand;
}