Как получить имя хоста с портом из запроса http или https
У меня есть два приложения, развернутые в контейнере jboss (тот же самый блок unix). Если я получаю запрос от app1, мне нужно создать соответствующий запрос для app2.
, например:
если запрос app1: http://example.com/context?param1=123
то мне нужно извлечь " http://example.com/", чтобы я мог запросить кадр для второго приложения.
Я попытался использовать:
HttpServletRequest.getServerName() &
HttpServletRequest.getServerPort() & \
HttpServletRequest.getHeader("host")
но запрос может быть http или https.
Пожалуйста, дайте мне знать, есть ли другой лучший способ.
Спасибо!
Ответы
Ответ 1
Вы можете использовать HttpServletRequest.getScheme()
для получения "http" или "https".
Использовать его вместе с HttpServletRequest.getServerName()
должно быть достаточно, чтобы перестроить часть URL-адреса, который вам нужен.
Вам не нужно явно указывать порт в URL-адресе, если вы используете стандартные (80 для http и 443 для https).
Изменить. Если ваш контейнер сервлета находится за обратным прокси-сервером или балансиром нагрузки, который завершает SSL, это немного сложнее, потому что запросы перенаправляются в контейнер сервлета как простой http. У вас есть несколько вариантов:
1) Вместо этого используйте HttpServletRequest.getHeader("x-forwarded-proto")
; это работает только в том случае, если ваш балансировочный балансир правильно устанавливает заголовок (Apache должен afaik).
2) Настройте RemoteIpValve в JBoss/Tomcat, что сделает getScheme()
работать должным образом. Опять же, это будет работать, только если балансировщик нагрузки задает правильные заголовки.
3) Если вышеуказанное не работает, вы можете настроить два разных коннектора в Tomcat/JBoss, один для http и один для https, как описано в этой статьи.
Ответ 2
Вы можете использовать HttpServletRequest.getRequestURL и HttpServletRequest.getRequestURI.
StringBuffer url = request.getRequestURL();
String uri = request.getRequestURI();
String host = url.substring(0, url.indexOf(uri)); //result
Ответ 3
Если вы используете балансировщик нагрузки и Nginx, настройте их без кода изменения.
Nginx:
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
Tomcat server.xml Двигатель:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
Если только изменить конфигурационный файл Nginx, код java должен быть:
String XForwardedProto = request.getHeader("X-Forwarded-Proto");
Ответ 4
Если вы хотите, чтобы исходный URL-адрес просто использовал метод, описанный jthalborn.
Если вы хотите перестроить URL-адрес, как объяснил Дэвид Левеске, вот фрагмент кода для него:
final javax.servlet.http.HttpServletRequest req = (javax.servlet.http.HttpServletRequest) ...;
final int serverPort = req.getServerPort();
if ((serverPort == 80) || (serverPort == 443)) {
// No need to add the server port for standard HTTP and HTTPS ports, the scheme will help determine it.
url = String.format("%s://%s/...", req.getScheme(), req.getServerName(), ...);
} else {
url = String.format("%s://%s:%s...", req.getScheme(), req.getServerName(), serverPort, ...);
}
Вам все равно нужно рассмотреть случай обратного прокси:
Можно использовать константы для портов, но не уверен, есть ли у них надежный источник, порты по умолчанию:
Большинство разработчиков будут знать о портах 80 и 443 в любом случае, поэтому константы не так полезны.
Также см. этот пост.
Ответ 5
Обратитесь к http://docs.oracle.com/javase/tutorial/networking/urls/urlInfo.html. Это наиболее краткий обзор синтаксического анализа URL.