HttpServletRequest完成URL

时间:2010-02-08 14:34:52

标签: java http servlets

我有一个HttpServletRequest对象。

如何获得导致此调用的完整且准确的URL到达我的servlet?

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

11 个答案:

答案 0 :(得分:342)

HttpServletRequest有以下方法:

  • getRequestURL() - 在查询字符串分隔符?之前返回完整网址的一部分
  • getQueryString() - 在查询字符串分隔符?
  • 之后返回完整网址的一部分

因此,要获取完整的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();
    }
}

答案 1 :(得分:125)

我使用这种方法:

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

答案 2 :(得分: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;
}

答案 3 :(得分:6)

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

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

答案 4 :(得分:6)

在Spring项目中,您可以使用

UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request)).build().toUriString()

答案 5 :(得分:5)

结合getRequestURL()getQueryString()的结果可以获得理想的结果。

答案 6 :(得分: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);





    }

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

答案 7 :(得分:1)

在HttpServletRequest对象

上使用以下方法

java.lang.String getRequestURI() - 将此请求的URL部分从协议名称返回到HTTP请求第一行中的查询字符串。

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

java.lang.String getQueryString() - 返回路径后的请求URL中包含的查询字符串。

答案 8 :(得分:0)

参加派对的时间稍晚,但我在MarkUtils-Web library 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's - 但即使他没有考虑使用HTTP / HTTPS的潜在非标准端口配置。

另见:

答案 9 :(得分:0)

如果使用.getRequestURL()中StringBuffer的构建器模式,则可以编写一个带有三元数的简单线性衬里:

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

但这只是语法糖。

答案 10 :(得分:0)

当请求被转发时,例如从反向代理中,HttpServletRequest.getRequestURL() 方法不会返回转发的 url 而是本地 url。 设置 x-forwarded-* 标头后,这可以轻松处理:

public static String getCurrentUrl(HttpServletRequest request) {
    String forwardedHost = request.getHeader("x-forwarded-host");

    if(forwardedHost == null) {
        return request.getRequestURL().toString();
    }

    String scheme = request.getHeader("x-forwarded-proto");
    String prefix = request.getHeader("x-forwarded-prefix");

    return scheme + "://" + forwardedHost + prefix + request.getRequestURI();
}

这缺少查询部分,但可以按照其他答案中的假设追加。我来这里是因为我特别需要转发那些东西,希望可以帮助别人解决这个问题。