且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在 Servlet 中获取 HTTP 和 HTTPS 请求的完整 URL 和查询字符串

更新时间:2023-02-25 14:12:48

按照设计,getRequestURL() 为您提供完整的 URL,仅缺少查询字符串.

By design, getRequestURL() gives you the full URL, missing only the query string.

HttpServletRequest,您可以使用以下方法获取 URI 的各个部分:

In HttpServletRequest, you can get individual parts of the URI using the methods below:

// Example: http://myhost:8080/people?lastname=Fox&age=30

String uri = request.getScheme() + "://" +   // "http" + "://
             request.getServerName() +       // "myhost"
             ":" +                           // ":"
             request.getServerPort() +       // "8080"
             request.getRequestURI() +       // "/people"
             "?" +                           // "?"
             request.getQueryString();       // "lastname=Fox&age=30"

  • .getScheme() 会给你 "https" 如果它是一个 https://domain 请求.
  • .getServerName()http(s)://domain 上给出 domain.
  • .getServerPort() 会给你端口.
    • .getScheme() will give you "https" if it was a https://domain request.
    • .getServerName() gives domain on http(s)://domain.
    • .getServerPort() will give you the port.
String uri = request.getScheme() + "://" +
             request.getServerName() + 
             ("http".equals(request.getScheme()) && request.getServerPort() == 80 || "https".equals(request.getScheme()) && request.getServerPort() == 443 ? "" : ":" + request.getServerPort() ) +
             request.getRequestURI() +
            (request.getQueryString() != null ? "?" + request.getQueryString() : "");

上面的这段代码将获得完整的 URI,如果使用默认端口,则隐藏端口,如果未提供后者,则不添加 "?" 和查询字符串.

This snippet above will get the full URI, hiding the port if the default one was used, and not adding the "?" and the query string if the latter was not provided.

请注意,如果您的请求通过代理,您需要查看 X-Forwarded-Proto 标头,因为方案可能会被更改:

Note, that if your request passes through a proxy, you need to look at the X-Forwarded-Proto header since the scheme might be altered:

request.getHeader("X-Forwarded-Proto")

另外,一个常见的头是X-Forwarded-For,它显示原始请求IP而不是代理IP.

Also, a common header is X-Forwarded-For, which show the original request IP instead of the proxys IP.

request.getHeader("X-Forwarded-For")

如果您自己负责配置代理/负载均衡器,则需要确保在转发时设置这些标头.

If you are responsible for the configuration of the proxy/load balancer yourself, you need to ensure that these headers are set upon forwarding.